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