@@ -1373,11 +1373,16 @@ emitObjCThunkArguments(SILGenFunction &SGF, SILLocation loc, SILDeclRef thunk,
1373
1373
auto inputs = objcFnTy->getParameters ();
1374
1374
auto nativeInputs = swiftFnTy->getParameters ();
1375
1375
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 ());
1378
1381
assert (inputs.size () ==
1379
1382
nativeInputs.size () + unsigned (foreignError.has_value ())
1380
- + unsigned (foreignAsync.has_value ()));
1383
+ + unsigned (foreignAsync.has_value ()) -
1384
+ unsigned (nativeInputsHasImplicitIsolatedParam));
1385
+
1381
1386
for (unsigned i = 0 , e = inputs.size (); i < e; ++i) {
1382
1387
SILType argTy = SGF.getSILType (inputs[i], objcFnTy);
1383
1388
SILValue arg = SGF.F .begin ()->createFunctionArgument (argTy);
@@ -1423,13 +1428,13 @@ emitObjCThunkArguments(SILGenFunction &SGF, SILLocation loc, SILDeclRef thunk,
1423
1428
+ unsigned (foreignAsync.has_value ())
1424
1429
== objcFnTy->getParameters ().size () &&
1425
1430
" objc inputs don't match number of arguments?!" );
1426
- assert (bridgedArgs.size () == swiftFnTy->getParameters ().size () &&
1431
+ assert (bridgedArgs.size () == swiftFnTy->getParameters ().size () - bool (nativeInputsHasImplicitIsolatedParam) &&
1427
1432
" swift inputs don't match number of arguments?!" );
1428
1433
assert ((foreignErrorSlot || !foreignError) &&
1429
1434
" didn't find foreign error slot" );
1430
1435
1431
1436
// Bridge the input types.
1432
- assert (bridgedArgs.size () == nativeInputs.size ());
1437
+ assert (bridgedArgs.size () == nativeInputs.size () - bool (nativeInputsHasImplicitIsolatedParam) );
1433
1438
for (unsigned i = 0 , size = bridgedArgs.size (); i < size; ++i) {
1434
1439
// Consider the bridged values to be "call results" since they're coming
1435
1440
// from potentially nil-unsound ObjC callers.
@@ -1656,6 +1661,31 @@ void SILGenFunction::emitNativeToForeignThunk(SILDeclRef thunk) {
1656
1661
// we will deallocate it too early.
1657
1662
Scope argScope (Cleanups, CleanupLocation (loc));
1658
1663
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
+
1659
1689
// Bridge the arguments.
1660
1690
SILValue foreignErrorSlot;
1661
1691
SILValue foreignAsyncSlot;
@@ -2117,7 +2147,25 @@ void SILGenFunction::emitForeignToNativeThunk(SILDeclRef thunk) {
2117
2147
indirectResult = F.begin ()->createFunctionArgument (
2118
2148
nativeConv.getSingleSILResultType (F.getTypeExpansionContext ()));
2119
2149
}
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
+
2121
2169
// Forward the arguments.
2122
2170
SmallVector<SILValue, 8 > params;
2123
2171
@@ -2182,9 +2230,12 @@ void SILGenFunction::emitForeignToNativeThunk(SILDeclRef thunk) {
2182
2230
getParameterTypes (nativeCI.LoweredType .getParams (), hasSelfParam);
2183
2231
2184
2232
for (unsigned nativeParamIndex : indices (params)) {
2233
+ // Adjust the parameter if we inserted an implicit isolated parameter.
2234
+ unsigned nativeFnTyParamIndex = nativeParamIndex + hasImplicitIsolatedParameter;
2235
+
2185
2236
// Bring the parameter to +1.
2186
2237
auto paramValue = params[nativeParamIndex];
2187
- auto thunkParam = nativeFnTy->getParameters ()[nativeParamIndex ];
2238
+ auto thunkParam = nativeFnTy->getParameters ()[nativeFnTyParamIndex ];
2188
2239
// TODO: Could avoid a retain if the bridged parameter is also +0 and
2189
2240
// doesn't require a bridging conversion.
2190
2241
ManagedValue param;
0 commit comments