@@ -1945,6 +1945,7 @@ namespace {
1945
1945
class SourceFileScope {
1946
1946
SILGenModule &sgm;
1947
1947
Optional<Scope> scope;
1948
+ bool isAsyncTopLevel = false ;
1948
1949
public:
1949
1950
SourceFileScope (SILGenModule &sgm, SourceFile *sf) : sgm(sgm) {
1950
1951
// If this is the script-mode file for the module, create a toplevel.
@@ -1954,30 +1955,39 @@ class SourceFileScope {
1954
1955
sgm.getASTContext ().getEntryPointFunctionName ()) &&
1955
1956
" already emitted toplevel?!" );
1956
1957
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);
1960
1960
toplevel->setBare (IsBare);
1961
1961
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
+ }
1964
1969
1965
1970
sgm.TopLevelSGF = new SILGenFunction (sgm, *toplevel, sf);
1966
1971
sgm.TopLevelSGF ->MagicFunctionName = sgm.SwiftModule ->getName ();
1967
1972
auto moduleCleanupLoc = CleanupLocation::getModuleCleanupLocation ();
1968
- sgm.TopLevelSGF ->prepareEpilog (None, true , moduleCleanupLoc);
1969
1973
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);
1980
1975
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
+ }
1981
1991
scope.emplace (sgm.TopLevelSGF ->Cleanups , moduleCleanupLoc);
1982
1992
}
1983
1993
}
@@ -1997,8 +2007,23 @@ class SourceFileScope {
1997
2007
auto returnLoc = returnInfo.second ;
1998
2008
returnLoc.markAutoGenerated ();
1999
2009
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
+
2002
2027
auto emitTopLevelReturnValue = [&](unsigned value) -> SILValue {
2003
2028
// Create an integer literal for the value.
2004
2029
auto litType = SILType::getBuiltinIntegerType (32 , sgm.getASTContext ());
@@ -2059,8 +2084,16 @@ class SourceFileScope {
2059
2084
}
2060
2085
2061
2086
// 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
+ }
2064
2097
2065
2098
// Okay, we're done emitting the top-level function; destroy the
2066
2099
// emitter and verify the result.
0 commit comments