@@ -985,7 +985,7 @@ ManagedValue Transform::transformTuple(ManagedValue inputTuple,
985
985
void SILGenFunction::collectThunkParams (
986
986
SILLocation loc, SmallVectorImpl<ManagedValue> ¶ms,
987
987
SmallVectorImpl<ManagedValue> *indirectResults,
988
- SmallVectorImpl<ManagedValue> *indirectErrors) {
988
+ SmallVectorImpl<ManagedValue> *indirectErrors, ThunkGenOptions options ) {
989
989
// Add the indirect results.
990
990
for (auto resultTy : F.getConventions ().getIndirectSILResultTypes (
991
991
getTypeExpansionContext ())) {
@@ -1021,7 +1021,16 @@ void SILGenFunction::collectThunkParams(
1021
1021
// be lowered to their underlying type if allowed by resilience.
1022
1022
auto inContextParamTy = F.getLoweredType (paramTy.getASTType ())
1023
1023
.getCategoryType (paramTy.getCategory ());
1024
- params.push_back (B.createInputFunctionArgument (inContextParamTy, loc));
1024
+ auto functionArgument =
1025
+ B.createInputFunctionArgument (inContextParamTy, loc);
1026
+
1027
+ // If we are told to not propagate the isolated parameter and this is the
1028
+ // implicit leading/isolated parameter, continue.
1029
+ if (options.contains (ThunkGenFlag::ConvertingToNonIsolatedCaller) &&
1030
+ param.hasOption (SILParameterInfo::ImplicitLeading) &&
1031
+ param.hasOption (SILParameterInfo::Isolated))
1032
+ continue ;
1033
+ params.push_back (functionArgument);
1025
1034
}
1026
1035
}
1027
1036
@@ -1454,15 +1463,18 @@ class TranslateArguments : public ExpanderBase<TranslateArguments, ParamInfo> {
1454
1463
CanSILFunctionType InnerTypesFuncTy;
1455
1464
ArrayRef<SILParameterInfo> InnerTypes;
1456
1465
InnerPackArgGenerator InnerPacks;
1466
+ SILGenFunction::ThunkGenOptions Options;
1467
+
1457
1468
public:
1458
1469
TranslateArguments (SILGenFunction &SGF, SILLocation loc,
1459
1470
ArrayRef<ManagedValue> outerArgs,
1460
1471
SmallVectorImpl<ManagedValue> &innerArgs,
1461
1472
CanSILFunctionType innerTypesFuncTy,
1462
- ArrayRef<SILParameterInfo> innerTypes)
1463
- : ExpanderBase(SGF, loc, outerArgs), InnerArgs(innerArgs),
1464
- InnerTypesFuncTy (innerTypesFuncTy), InnerTypes(innerTypes),
1465
- InnerPacks(*this ) {}
1473
+ ArrayRef<SILParameterInfo> innerTypes,
1474
+ SILGenFunction::ThunkGenOptions options = {})
1475
+ : ExpanderBase(SGF, loc, outerArgs), InnerArgs(innerArgs),
1476
+ InnerTypesFuncTy (innerTypesFuncTy), InnerTypes(innerTypes),
1477
+ InnerPacks(*this ), Options(options) {}
1466
1478
1467
1479
void process (AbstractionPattern innerOrigFunctionType,
1468
1480
AnyFunctionType::CanParamArrayRef innerSubstTypes,
@@ -2905,12 +2917,18 @@ static ManagedValue applyTrivialConversions(SILGenFunction &SGF,
2905
2917
}
2906
2918
2907
2919
// / Forward arguments according to a function type's ownership conventions.
2908
- static void forwardFunctionArguments (SILGenFunction &SGF,
2909
- SILLocation loc,
2910
- CanSILFunctionType fTy ,
2911
- ArrayRef<ManagedValue> managedArgs,
2912
- SmallVectorImpl<SILValue> &forwardedArgs) {
2920
+ static void
2921
+ forwardFunctionArguments (SILGenFunction &SGF, SILLocation loc,
2922
+ CanSILFunctionType fTy ,
2923
+ ArrayRef<ManagedValue> managedArgs,
2924
+ SmallVectorImpl<SILValue> &forwardedArgs,
2925
+ SILGenFunction::ThunkGenOptions options = {}) {
2913
2926
auto argTypes = fTy ->getParameters ();
2927
+ if (options.contains (
2928
+ SILGenFunction::ThunkGenFlag::ConvertingFromNonIsolatedCaller)) {
2929
+ argTypes = argTypes.drop_front ();
2930
+ }
2931
+
2914
2932
for (auto index : indices (managedArgs)) {
2915
2933
auto arg = managedArgs[index];
2916
2934
auto argTy = argTypes[index];
@@ -5424,9 +5442,31 @@ static void buildThunkBody(SILGenFunction &SGF, SILLocation loc,
5424
5442
5425
5443
FullExpr scope (SGF.Cleanups , CleanupLocation (loc));
5426
5444
5445
+ using ThunkGenFlag = SILGenFunction::ThunkGenFlag;
5446
+ auto options = SILGenFunction::ThunkGenOptions ();
5447
+
5448
+ // If our original function was nonisolated caller and our eventual type is
5449
+ // just nonisolated, pop the isolated argument.
5450
+ //
5451
+ // NOTE: We do this early before thunk params so that we avoid pushing the
5452
+ // isolated parameter preventing us from having to memcpy over the array.
5453
+ if (outputSubstType->isAsync ()) {
5454
+ if (outputSubstType->getIsolation ().getKind () ==
5455
+ FunctionTypeIsolation::Kind::NonIsolatedCaller &&
5456
+ inputSubstType->getIsolation ().getKind () !=
5457
+ FunctionTypeIsolation::Kind::NonIsolatedCaller)
5458
+ options |= ThunkGenFlag::ConvertingToNonIsolatedCaller;
5459
+
5460
+ if (outputSubstType->getIsolation ().getKind () !=
5461
+ FunctionTypeIsolation::Kind::NonIsolatedCaller &&
5462
+ inputSubstType->getIsolation ().getKind () ==
5463
+ FunctionTypeIsolation::Kind::NonIsolatedCaller)
5464
+ options |= ThunkGenFlag::ConvertingFromNonIsolatedCaller;
5465
+ }
5466
+
5427
5467
SmallVector<ManagedValue, 8 > params;
5428
5468
SmallVector<ManagedValue, 4 > indirectResultParams;
5429
- SGF.collectThunkParams (loc, params, &indirectResultParams);
5469
+ SGF.collectThunkParams (loc, params, &indirectResultParams, nullptr , options );
5430
5470
5431
5471
// Ignore the self parameter at the SIL level. IRGen will use it to
5432
5472
// recover type metadata.
@@ -5444,6 +5484,16 @@ static void buildThunkBody(SILGenFunction &SGF, SILLocation loc,
5444
5484
outputErasedIsolation = params.pop_back_val ();
5445
5485
}
5446
5486
5487
+ if (!SGF.F .maybeGetIsolatedArgument () && argTypes.size () &&
5488
+ argTypes.front ().hasOption (SILParameterInfo::Isolated) &&
5489
+ argTypes.front ().hasOption (SILParameterInfo::ImplicitLeading))
5490
+ options |= ThunkGenFlag::ConvertingFromNonIsolatedCaller;
5491
+
5492
+ // If we are converting to nonisolated caller, we are going to have an extra
5493
+ // parameter in our argTypes that we need to drop.
5494
+ if (options.contains (ThunkGenFlag::ConvertingFromNonIsolatedCaller))
5495
+ argTypes = argTypes.drop_front ();
5496
+
5447
5497
// We may need to establish the right executor for the input function.
5448
5498
// If both function types are synchronous, whoever calls this thunk is
5449
5499
// responsible for establishing the executor properly, so we don't need
@@ -5514,11 +5564,9 @@ static void buildThunkBody(SILGenFunction &SGF, SILLocation loc,
5514
5564
// other direction (the thunk receives an Int like a T, and passes it
5515
5565
// like a normal Int when calling the inner function).
5516
5566
SmallVector<ManagedValue, 8 > args;
5517
- TranslateArguments (SGF, loc, params, args, fnType, argTypes)
5518
- .process (inputOrigType,
5519
- inputSubstType.getParams (),
5520
- outputOrigType,
5521
- outputSubstType.getParams ());
5567
+ TranslateArguments (SGF, loc, params, args, fnType, argTypes, options)
5568
+ .process (inputOrigType, inputSubstType.getParams (), outputOrigType,
5569
+ outputSubstType.getParams ());
5522
5570
5523
5571
SmallVector<SILValue, 8 > argValues;
5524
5572
@@ -5546,11 +5594,35 @@ static void buildThunkBody(SILGenFunction &SGF, SILLocation loc,
5546
5594
/* mandatory*/ false );
5547
5595
}
5548
5596
5597
+ // If we are thunking a nonisolated caller to nonisolated or global actor, we
5598
+ // need to load the actor.
5599
+ if (options.contains (ThunkGenFlag::ConvertingFromNonIsolatedCaller)) {
5600
+ auto outputIsolation = outputSubstType->getIsolation ();
5601
+ switch (outputIsolation.getKind ()) {
5602
+ case FunctionTypeIsolation::Kind::NonIsolated:
5603
+ argValues.push_back (SGF.emitNonIsolatedIsolation (loc).getValue ());
5604
+ break ;
5605
+ case FunctionTypeIsolation::Kind::GlobalActor: {
5606
+ auto globalActor =
5607
+ outputIsolation.getGlobalActorType ()->getCanonicalType ();
5608
+ argValues.push_back (
5609
+ SGF.emitGlobalActorIsolation (loc, globalActor).getValue ());
5610
+ break ;
5611
+ }
5612
+ case FunctionTypeIsolation::Kind::Parameter:
5613
+ case FunctionTypeIsolation::Kind::Erased:
5614
+ case FunctionTypeIsolation::Kind::NonIsolatedCaller:
5615
+ llvm_unreachable (" Should never see this" );
5616
+ break ;
5617
+ }
5618
+ }
5619
+
5549
5620
// Add the rest of the arguments.
5550
- forwardFunctionArguments (SGF, loc, fnType, args, argValues);
5621
+ forwardFunctionArguments (SGF, loc, fnType, args, argValues, options );
5551
5622
5552
5623
auto fun = fnType->isCalleeGuaranteed () ? fnValue.borrow (SGF, loc).getValue ()
5553
5624
: fnValue.forward (SGF);
5625
+
5554
5626
SILValue innerResult =
5555
5627
SGF.emitApplyWithRethrow (loc, fun,
5556
5628
/* substFnType*/ fnValue.getType (),
@@ -5683,18 +5755,29 @@ static ManagedValue createThunk(SILGenFunction &SGF,
5683
5755
auto toType = expectedType->getWithExtInfo (
5684
5756
expectedType->getExtInfo ().withNoEscape (false ));
5685
5757
CanType dynamicSelfType;
5686
- auto thunkType = SGF.buildThunkType (sourceType, toType,
5687
- inputSubstType,
5688
- outputSubstType,
5689
- genericEnv,
5690
- interfaceSubs,
5691
- dynamicSelfType);
5692
- // An actor-isolated non-async function can be converted to an async function
5693
- // by inserting a hop to the global actor.
5758
+ auto thunkType =
5759
+ SGF.buildThunkType (sourceType, toType, inputSubstType, outputSubstType,
5760
+ genericEnv, interfaceSubs, dynamicSelfType);
5694
5761
CanType globalActorForThunk;
5695
- if (outputSubstType->isAsync ()
5696
- && !inputSubstType->isAsync ()) {
5697
- globalActorForThunk = CanType (inputSubstType->getGlobalActor ());
5762
+ // If our output type is async...
5763
+ if (outputSubstType->isAsync ()) {
5764
+ // And our input type is not async, we can convert the actor-isolated
5765
+ // non-async function to an async function by inserting a hop to the global
5766
+ // actor.
5767
+ if (!inputSubstType->isAsync ()) {
5768
+ globalActorForThunk = CanType (inputSubstType->getGlobalActor ());
5769
+ } else {
5770
+ // If our inputSubstType is also async and we are converting from a
5771
+ // nonisolated caller to a global actor from a global actor, attach the
5772
+ // global actor for thunk so we mangle appropriately.
5773
+ auto outputIsolation = outputSubstType->getIsolation ();
5774
+ if (outputIsolation.getKind () ==
5775
+ FunctionTypeIsolation::Kind::GlobalActor &&
5776
+ inputSubstType->getIsolation ().getKind () ==
5777
+ FunctionTypeIsolation::Kind::NonIsolatedCaller)
5778
+ globalActorForThunk =
5779
+ outputIsolation.getGlobalActorType ()->getCanonicalType ();
5780
+ }
5698
5781
}
5699
5782
5700
5783
auto thunk = SGF.SGM .getOrCreateReabstractionThunk (
0 commit comments