@@ -1373,11 +1373,16 @@ emitObjCThunkArguments(SILGenFunction &SGF, SILLocation loc, SILDeclRef thunk,
13731373 auto inputs = objcFnTy->getParameters ();
13741374 auto nativeInputs = swiftFnTy->getParameters ();
13751375 auto fnConv = SGF.silConv .getFunctionConventions (swiftFnTy);
1376- assert (nativeInputs.size () == bridgedFormalTypes.size ());
1377- assert (nativeInputs.size () == nativeFormalTypes.size ());
1376+ bool nativeInputsHasImplicitIsolatedParam = false ;
1377+ if (auto param = swiftFnTy->maybeGetIsolatedParameter ())
1378+ nativeInputsHasImplicitIsolatedParam = param->hasOption (SILParameterInfo::ImplicitLeading);
1379+ assert (nativeInputs.size () - unsigned (nativeInputsHasImplicitIsolatedParam) == bridgedFormalTypes.size ());
1380+ assert (nativeInputs.size () - unsigned (nativeInputsHasImplicitIsolatedParam) == nativeFormalTypes.size ());
13781381 assert (inputs.size () ==
13791382 nativeInputs.size () + unsigned (foreignError.has_value ())
1380- + unsigned (foreignAsync.has_value ()));
1383+ + unsigned (foreignAsync.has_value ()) -
1384+ unsigned (nativeInputsHasImplicitIsolatedParam));
1385+
13811386 for (unsigned i = 0 , e = inputs.size (); i < e; ++i) {
13821387 SILType argTy = SGF.getSILType (inputs[i], objcFnTy);
13831388 SILValue arg = SGF.F .begin ()->createFunctionArgument (argTy);
@@ -1423,13 +1428,13 @@ emitObjCThunkArguments(SILGenFunction &SGF, SILLocation loc, SILDeclRef thunk,
14231428 + unsigned (foreignAsync.has_value ())
14241429 == objcFnTy->getParameters ().size () &&
14251430 " objc inputs don't match number of arguments?!" );
1426- assert (bridgedArgs.size () == swiftFnTy->getParameters ().size () &&
1431+ assert (bridgedArgs.size () == swiftFnTy->getParameters ().size () - bool (nativeInputsHasImplicitIsolatedParam) &&
14271432 " swift inputs don't match number of arguments?!" );
14281433 assert ((foreignErrorSlot || !foreignError) &&
14291434 " didn't find foreign error slot" );
14301435
14311436 // Bridge the input types.
1432- assert (bridgedArgs.size () == nativeInputs.size ());
1437+ assert (bridgedArgs.size () == nativeInputs.size () - bool (nativeInputsHasImplicitIsolatedParam) );
14331438 for (unsigned i = 0 , size = bridgedArgs.size (); i < size; ++i) {
14341439 // Consider the bridged values to be "call results" since they're coming
14351440 // from potentially nil-unsound ObjC callers.
@@ -1656,6 +1661,31 @@ void SILGenFunction::emitNativeToForeignThunk(SILDeclRef thunk) {
16561661 // we will deallocate it too early.
16571662 Scope argScope (Cleanups, CleanupLocation (loc));
16581663
1664+ // See if our native function has an implicitly isolated parameter. In such a
1665+ // case, we need to pass in the isolation.
1666+ if (auto isolatedParameter = substTy->maybeGetIsolatedParameter ();
1667+ isolatedParameter && isolatedParameter->hasOption (SILParameterInfo::ImplicitLeading)) {
1668+ assert (F.isAsync () && " Can only be async" );
1669+ assert (isolation && " No isolation?!" );
1670+ switch (isolation->getKind ()) {
1671+ case ActorIsolation::Unspecified:
1672+ case ActorIsolation::Nonisolated:
1673+ case ActorIsolation::NonisolatedUnsafe:
1674+ case ActorIsolation::CallerIsolationInheriting:
1675+ args.push_back (emitNonIsolatedIsolation (loc).getValue ());
1676+ break ;
1677+ case ActorIsolation::ActorInstance:
1678+ llvm::report_fatal_error (" Should never see this" );
1679+ break ;
1680+ case ActorIsolation::GlobalActor:
1681+ args.push_back (emitLoadGlobalActorExecutor (isolation->getGlobalActor ()));
1682+ break ;
1683+ case ActorIsolation::Erased:
1684+ llvm::report_fatal_error (" Should never see this" );
1685+ break ;
1686+ }
1687+ }
1688+
16591689 // Bridge the arguments.
16601690 SILValue foreignErrorSlot;
16611691 SILValue foreignAsyncSlot;
@@ -2117,7 +2147,25 @@ void SILGenFunction::emitForeignToNativeThunk(SILDeclRef thunk) {
21172147 indirectResult = F.begin ()->createFunctionArgument (
21182148 nativeConv.getSingleSILResultType (F.getTypeExpansionContext ()));
21192149 }
2120-
2150+
2151+ // Before we do anything, see if our function type is async and has an
2152+ // implicit isolated parameter. In such a case, we need to implicitly insert
2153+ // it here before we insert other parameters.
2154+ //
2155+ // NOTE: We do not jump to it or do anything further since as mentioned above,
2156+ // we might switch to the callee's actor as part of making the call... but we
2157+ // don't need to do anything further than that because we're going to
2158+ // immediately return.
2159+ bool hasImplicitIsolatedParameter = false ;
2160+ if (auto isolatedParameter = nativeFnTy->maybeGetIsolatedParameter ();
2161+ isolatedParameter && nativeFnTy->isAsync () &&
2162+ isolatedParameter->hasOption (SILParameterInfo::ImplicitLeading)) {
2163+ auto loweredTy = getLoweredTypeForFunctionArgument (
2164+ isolatedParameter->getArgumentType (&F));
2165+ F.begin ()->createFunctionArgument (loweredTy);
2166+ hasImplicitIsolatedParameter = true ;
2167+ }
2168+
21212169 // Forward the arguments.
21222170 SmallVector<SILValue, 8 > params;
21232171
@@ -2182,9 +2230,12 @@ void SILGenFunction::emitForeignToNativeThunk(SILDeclRef thunk) {
21822230 getParameterTypes (nativeCI.LoweredType .getParams (), hasSelfParam);
21832231
21842232 for (unsigned nativeParamIndex : indices (params)) {
2233+ // Adjust the parameter if we inserted an implicit isolated parameter.
2234+ unsigned nativeFnTyParamIndex = nativeParamIndex + hasImplicitIsolatedParameter;
2235+
21852236 // Bring the parameter to +1.
21862237 auto paramValue = params[nativeParamIndex];
2187- auto thunkParam = nativeFnTy->getParameters ()[nativeParamIndex ];
2238+ auto thunkParam = nativeFnTy->getParameters ()[nativeFnTyParamIndex ];
21882239 // TODO: Could avoid a retain if the bridged parameter is also +0 and
21892240 // doesn't require a bridging conversion.
21902241 ManagedValue param;
0 commit comments