@@ -338,24 +338,15 @@ SILGenModule::getConformanceToBridgedStoredNSError(SILLocation loc, Type type) {
338
338
return SwiftModule->lookupConformance (type, proto);
339
339
}
340
340
341
- static FuncDecl *lookupConcurrencyIntrinsic (ASTContext &C,
342
- Optional<FuncDecl*> &cache,
343
- StringRef name) {
341
+ static FuncDecl *lookupIntrinsic (ModuleDecl &module ,
342
+ Optional<FuncDecl *> &cache, Identifier name) {
344
343
if (cache)
345
344
return *cache;
346
-
347
- auto *module = C.getLoadedModule (C.Id_Concurrency );
348
- if (!module ) {
349
- cache = nullptr ;
350
- return nullptr ;
351
- }
352
-
353
- SmallVector<ValueDecl *, 1 > decls;
354
- module ->lookupQualified (module ,
355
- DeclNameRef (C.getIdentifier (name)),
356
- NL_QualifiedDefault | NL_IncludeUsableFromInline,
357
- decls);
358
345
346
+ SmallVector<ValueDecl *, 1 > decls;
347
+ module .lookupQualified (&module , DeclNameRef (name),
348
+ NL_QualifiedDefault | NL_IncludeUsableFromInline,
349
+ decls);
359
350
if (decls.size () != 1 ) {
360
351
cache = nullptr ;
361
352
return nullptr ;
@@ -365,6 +356,18 @@ static FuncDecl *lookupConcurrencyIntrinsic(ASTContext &C,
365
356
return func;
366
357
}
367
358
359
+ static FuncDecl *lookupConcurrencyIntrinsic (ASTContext &C,
360
+ Optional<FuncDecl *> &cache,
361
+ StringRef name) {
362
+ auto *module = C.getLoadedModule (C.Id_Concurrency );
363
+ if (!module ) {
364
+ cache = nullptr ;
365
+ return nullptr ;
366
+ }
367
+
368
+ return lookupIntrinsic (*module , cache, C.getIdentifier (name));
369
+ }
370
+
368
371
FuncDecl *
369
372
SILGenModule::getAsyncLetStart () {
370
373
return lookupConcurrencyIntrinsic (getASTContext (),
@@ -437,6 +440,37 @@ SILGenModule::getCheckExpectedExecutor() {
437
440
" _checkExpectedExecutor" );
438
441
}
439
442
443
+ FuncDecl *SILGenModule::getAsyncMainDrainQueue () {
444
+ return lookupConcurrencyIntrinsic (getASTContext (), AsyncMainDrainQueue,
445
+ " _asyncMainDrainQueue" );
446
+ }
447
+
448
+ FuncDecl *SILGenModule::getGetMainExecutor () {
449
+ return lookupConcurrencyIntrinsic (getASTContext (), GetMainExecutor,
450
+ " _getMainExecutor" );
451
+ }
452
+
453
+ FuncDecl *SILGenModule::getSwiftJobRun () {
454
+ return lookupConcurrencyIntrinsic (getASTContext (), SwiftJobRun,
455
+ " _swiftJobRun" );
456
+ }
457
+
458
+ FuncDecl *SILGenModule::getExit () {
459
+ if (ExitFunc)
460
+ return *ExitFunc;
461
+
462
+ ASTContext &C = getASTContext ();
463
+ ModuleDecl *concurrencyShims =
464
+ C.getModuleByIdentifier (C.getIdentifier (" _SwiftConcurrencyShims" ));
465
+
466
+ if (!concurrencyShims) {
467
+ ExitFunc = nullptr ;
468
+ return nullptr ;
469
+ }
470
+
471
+ return lookupIntrinsic (*concurrencyShims, ExitFunc, C.getIdentifier (" exit" ));
472
+ }
473
+
440
474
ProtocolConformance *SILGenModule::getNSErrorConformanceToError () {
441
475
if (NSErrorConformanceToError)
442
476
return *NSErrorConformanceToError;
@@ -1036,6 +1070,7 @@ void SILGenModule::emitFunctionDefinition(SILDeclRef constant, SILFunction *f) {
1036
1070
postEmitFunction (constant, f);
1037
1071
return ;
1038
1072
}
1073
+ case SILDeclRef::Kind::AsyncEntryPoint:
1039
1074
case SILDeclRef::Kind::EntryPoint: {
1040
1075
f->setBare (IsBare);
1041
1076
@@ -1046,7 +1081,27 @@ void SILGenModule::emitFunctionDefinition(SILDeclRef constant, SILFunction *f) {
1046
1081
auto *decl = constant.getDecl ();
1047
1082
auto *dc = decl->getDeclContext ();
1048
1083
PrettyStackTraceSILFunction X (" silgen emitArtificialTopLevel" , f);
1049
- SILGenFunction (*this , *f, dc).emitArtificialTopLevel (decl);
1084
+ // In all cases, a constant.kind == EntryPoint indicates the main entrypoint
1085
+ // to the program, @main.
1086
+ // In the synchronous case, the decl is not async, so emitArtificialTopLevel
1087
+ // emits the error unwrapping and call to MainType.$main() into @main.
1088
+ //
1089
+ // In the async case, emitAsyncMainThreadStart is responsible for generating
1090
+ // the contents of @main. This wraps @async_main in a task, passes that task
1091
+ // to swift_job_run to execute the first thunk, and starts the runloop to
1092
+ // run any additional continuations. The kind is EntryPoint, and the decl is
1093
+ // async.
1094
+ // When the kind is 'AsyncMain', we are generating @async_main. In this
1095
+ // case, emitArtificialTopLevel emits the code for calling MaintType.$main,
1096
+ // unwrapping errors, and calling exit(0) into @async_main to run the
1097
+ // user-specified main function.
1098
+ if (constant.kind == SILDeclRef::Kind::EntryPoint && isa<FuncDecl>(decl) &&
1099
+ static_cast <FuncDecl *>(decl)->hasAsync ()) {
1100
+ SILDeclRef mainEntryPoint = SILDeclRef::getAsyncMainDeclEntryPoint (decl);
1101
+ SILGenFunction (*this , *f, dc).emitAsyncMainThreadStart (mainEntryPoint);
1102
+ } else {
1103
+ SILGenFunction (*this , *f, dc).emitArtificialTopLevel (decl);
1104
+ }
1050
1105
postEmitFunction (constant, f);
1051
1106
return ;
1052
1107
}
@@ -2029,10 +2084,15 @@ class SILGenModuleRAII {
2029
2084
2030
2085
// If the source file contains an artificial main, emit the implicit
2031
2086
// top-level code.
2032
- if (auto *mainDecl = sf->getMainDecl ())
2087
+ if (auto *mainDecl = sf->getMainDecl ()) {
2088
+ if (isa<FuncDecl>(mainDecl) &&
2089
+ static_cast <FuncDecl *>(mainDecl)->hasAsync ())
2090
+ emitSILFunctionDefinition (
2091
+ SILDeclRef::getAsyncMainDeclEntryPoint (mainDecl));
2033
2092
emitSILFunctionDefinition (SILDeclRef::getMainDeclEntryPoint (mainDecl));
2093
+ }
2034
2094
}
2035
-
2095
+
2036
2096
void emitSILFunctionDefinition (SILDeclRef ref) {
2037
2097
SGM.emitFunctionDefinition (ref, SGM.getFunction (ref, ForDefinition));
2038
2098
}
0 commit comments