@@ -1945,6 +1945,7 @@ namespace {
19451945class SourceFileScope {
19461946 SILGenModule &sgm;
19471947 Optional<Scope> scope;
1948+ bool isAsyncTopLevel = false ;
19481949public:
19491950 SourceFileScope (SILGenModule &sgm, SourceFile *sf) : sgm(sgm) {
19501951 // If this is the script-mode file for the module, create a toplevel.
@@ -1954,30 +1955,39 @@ class SourceFileScope {
19541955 sgm.getASTContext ().getEntryPointFunctionName ()) &&
19551956 " already emitted toplevel?!" );
19561957
1957- RegularLocation TopLevelLoc = RegularLocation::getModuleLocation ();
1958- auto ref = SILDeclRef::getMainFileEntryPoint (sf);
1959- auto *toplevel = sgm.getFunction (ref, ForDefinition);
1958+ auto mainEntryRef = SILDeclRef::getMainFileEntryPoint (sf);
1959+ SILFunction * toplevel = sgm.getFunction (mainEntryRef, ForDefinition);
19601960 toplevel->setBare (IsBare);
19611961
1962- // Assign a debug scope pointing into the void to the top level function.
1963- toplevel->setDebugScope (new (sgm.M ) SILDebugScope (TopLevelLoc, toplevel));
1962+ if (sf->isAsyncContext ()) {
1963+ isAsyncTopLevel = true ;
1964+ auto asyncEntryRef = SILDeclRef::getAsyncMainFileEntryPoint (sf);
1965+ SILFunction * asyncTopLevel = sgm.getFunction (asyncEntryRef, ForDefinition);
1966+ SILGenFunction (sgm, *toplevel, sf).emitAsyncMainThreadStart (asyncEntryRef);
1967+ toplevel = asyncTopLevel;
1968+ }
19641969
19651970 sgm.TopLevelSGF = new SILGenFunction (sgm, *toplevel, sf);
19661971 sgm.TopLevelSGF ->MagicFunctionName = sgm.SwiftModule ->getName ();
19671972 auto moduleCleanupLoc = CleanupLocation::getModuleCleanupLocation ();
1968- sgm.TopLevelSGF ->prepareEpilog (None, true , moduleCleanupLoc);
19691973
1970- // Create the argc and argv arguments.
1971- auto prologueLoc = RegularLocation::getModuleLocation ();
1972- prologueLoc.markAsPrologue ();
1973- auto entry = sgm.TopLevelSGF ->B .getInsertionBB ();
1974- auto context = sgm.TopLevelSGF ->getTypeExpansionContext ();
1975- auto paramTypeIter = sgm.TopLevelSGF ->F .getConventions ()
1976- .getParameterSILTypes (context)
1977- .begin ();
1978- entry->createFunctionArgument (*paramTypeIter);
1979- entry->createFunctionArgument (*std::next (paramTypeIter));
1974+ sgm.TopLevelSGF ->prepareEpilog (None, true , moduleCleanupLoc);
19801975
1976+ // emitAsyncMainThreadStart will handle creating argc argv
1977+ // for the async case
1978+ if (!sf->isAsyncContext ()) {
1979+ // Create the argc and argv arguments.
1980+ auto prologueLoc = RegularLocation::getModuleLocation ();
1981+ prologueLoc.markAsPrologue ();
1982+ auto entry = sgm.TopLevelSGF ->B .getInsertionBB ();
1983+ auto context = sgm.TopLevelSGF ->getTypeExpansionContext ();
1984+ auto paramTypeIter = sgm.TopLevelSGF ->F .getConventions ()
1985+ .getParameterSILTypes (context)
1986+ .begin ();
1987+
1988+ entry->createFunctionArgument (*paramTypeIter);
1989+ entry->createFunctionArgument (*std::next (paramTypeIter));
1990+ }
19811991 scope.emplace (sgm.TopLevelSGF ->Cleanups , moduleCleanupLoc);
19821992 }
19831993 }
@@ -1997,8 +2007,23 @@ class SourceFileScope {
19972007 auto returnLoc = returnInfo.second ;
19982008 returnLoc.markAutoGenerated ();
19992009
2000- SILType returnType = SGF.F .getConventions ().getSingleSILResultType (
2001- SGF.getTypeExpansionContext ());
2010+ SILFunction *exitFunc = nullptr ;
2011+
2012+ SILType returnType;
2013+ if (isAsyncTopLevel) {
2014+ FuncDecl *exitFuncDecl = sgm.getExit ();
2015+ assert (exitFuncDecl && " Failed to find exit function declaration" );
2016+ exitFunc = sgm.getFunction (
2017+ SILDeclRef (exitFuncDecl, SILDeclRef::Kind::Func, /* isForeign*/ true ),
2018+ NotForDefinition);
2019+ SILFunctionType & funcType = *exitFunc->getLoweredType ().getAs <SILFunctionType>();
2020+ returnType = SILType::getPrimitiveObjectType (
2021+ funcType.getParameters ().front ().getInterfaceType ());
2022+ } else {
2023+ returnType = SGF.F .getConventions ().getSingleSILResultType (
2024+ SGF.getTypeExpansionContext ());
2025+ }
2026+
20022027 auto emitTopLevelReturnValue = [&](unsigned value) -> SILValue {
20032028 // Create an integer literal for the value.
20042029 auto litType = SILType::getBuiltinIntegerType (32 , sgm.getASTContext ());
@@ -2059,8 +2084,16 @@ class SourceFileScope {
20592084 }
20602085
20612086 // Return.
2062- if (SGF.B .hasValidInsertionPoint ())
2063- SGF.B .createReturn (returnLoc, returnValue);
2087+ if (SGF.B .hasValidInsertionPoint ()) {
2088+
2089+ if (isAsyncTopLevel) {
2090+ SILValue exitCall = SGF.B .createFunctionRef (moduleLoc, exitFunc);
2091+ SGF.B .createApply (moduleLoc, exitCall, {}, {returnValue});
2092+ SGF.B .createUnreachable (moduleLoc);
2093+ } else {
2094+ SGF.B .createReturn (returnLoc, returnValue);
2095+ }
2096+ }
20642097
20652098 // Okay, we're done emitting the top-level function; destroy the
20662099 // emitter and verify the result.
0 commit comments