@@ -552,7 +552,7 @@ void SILGenFunction::emitProlog(CaptureInfo captureInfo,
552552 return false ;
553553 };
554554
555- // Initialize ExpectedExecutor if the function is an actor-isolated
555+ // Initialize ExpectedExecutor if the function is an async
556556 // function or closure.
557557 bool wantDataRaceChecks = getOptions ().EnableActorDataRaceChecks &&
558558 !F.isAsync () &&
@@ -642,6 +642,13 @@ void SILGenFunction::emitProlog(CaptureInfo captureInfo,
642642 }
643643 }
644644 }
645+
646+ // In async functions, the generic executor is our expected executor
647+ // if we don't have any sort of isolation.
648+ if (!ExpectedExecutor && F.isAsync ()) {
649+ ExpectedExecutor = emitGenericExecutor (
650+ RegularLocation::getAutoGeneratedLocation (F.getLocation ()));
651+ }
645652
646653 // Jump to the expected executor.
647654 if (ExpectedExecutor) {
@@ -661,6 +668,54 @@ void SILGenFunction::emitProlog(CaptureInfo captureInfo,
661668 }
662669}
663670
671+ SILValue SILGenFunction::emitMainExecutor (SILLocation loc) {
672+ // Get main executor
673+ FuncDecl *getMainExecutorFuncDecl = SGM.getGetMainExecutor ();
674+ if (!getMainExecutorFuncDecl) {
675+ // If it doesn't exist due to an SDK-compiler mismatch, we can conjure one
676+ // up instead of crashing:
677+ // @available(SwiftStdlib 5.1, *)
678+ // @_silgen_name("swift_task_getMainExecutor")
679+ // internal func _getMainExecutor() -> Builtin.Executor
680+ auto &ctx = getASTContext ();
681+
682+ ParameterList *emptyParams = ParameterList::createEmpty (ctx);
683+ getMainExecutorFuncDecl = FuncDecl::createImplicit (
684+ ctx, StaticSpellingKind::None,
685+ DeclName (
686+ ctx,
687+ DeclBaseName (ctx.getIdentifier (" _getMainExecutor" )),
688+ /* Arguments*/ emptyParams),
689+ {}, /* async*/ false , /* throws*/ false , {}, emptyParams,
690+ ctx.TheExecutorType ,
691+ getModule ().getSwiftModule ());
692+ getMainExecutorFuncDecl->getAttrs ().add (
693+ new (ctx)
694+ SILGenNameAttr (" swift_task_getMainExecutor" , /* implicit*/ true ));
695+ }
696+
697+ auto fn = SGM.getFunction (
698+ SILDeclRef (getMainExecutorFuncDecl, SILDeclRef::Kind::Func),
699+ NotForDefinition);
700+ SILValue fnRef = B.createFunctionRefFor (loc, fn);
701+ return B.createApply (loc, fnRef, {}, {});
702+ }
703+
704+ SILValue SILGenFunction::emitGenericExecutor (SILLocation loc) {
705+ // The generic executor is encoded as the nil value of
706+ // Optional<Builtin.SerialExecutor>.
707+ auto ty = SILType::getOptionalType (
708+ SILType::getPrimitiveObjectType (
709+ getASTContext ().TheExecutorType ));
710+ return B.createOptionalNone (loc, ty);
711+ }
712+
713+ void SILGenFunction::emitPrologGlobalActorHop (SILLocation loc,
714+ Type globalActor) {
715+ ExpectedExecutor = emitLoadGlobalActorExecutor (globalActor);
716+ B.createHopToExecutor (loc, ExpectedExecutor, /* mandatory*/ false );
717+ }
718+
664719SILValue SILGenFunction::emitLoadGlobalActorExecutor (Type globalActor) {
665720 CanType actorType = CanType (globalActor);
666721 NominalTypeDecl *nominal = actorType->getNominalOrBoundGenericNominal ();
@@ -800,19 +855,8 @@ void ExecutorBreadcrumb::emit(SILGenFunction &SGF, SILLocation loc) {
800855}
801856
802857SILValue SILGenFunction::emitGetCurrentExecutor (SILLocation loc) {
803- // If this is an actor method, then the actor is the only executor we should
804- // be running on (if we aren't setting up for a cross-actor call).
805- if (ExpectedExecutor)
806- return ExpectedExecutor;
807-
808- // Otherwise, we'll have to ask the current task what executor it's running
809- // on.
810- auto &ctx = getASTContext ();
811- return B.createBuiltin (
812- loc,
813- ctx.getIdentifier (getBuiltinName (BuiltinValueKind::GetCurrentExecutor)),
814- getLoweredType (OptionalType::get (ctx.TheExecutorType )),
815- SubstitutionMap (), { });
858+ assert (ExpectedExecutor && " prolog failed to set up expected executor?" );
859+ return ExpectedExecutor;
816860}
817861
818862static void emitIndirectResultParameters (SILGenFunction &SGF,
0 commit comments