@@ -4095,9 +4095,8 @@ class CallSite {
4095
4095
}
4096
4096
4097
4097
// / Take the arguments for special processing, in place of the above.
4098
- ArgumentSource &&forward() && {
4099
- assert (Args.isScalar ());
4100
- return std::move (std::move (Args).getSources ()[0 ]);
4098
+ PreparedArguments &&forward() && {
4099
+ return std::move (Args);
4101
4100
}
4102
4101
};
4103
4102
@@ -4483,6 +4482,12 @@ CallEmission::applyNormalCall(SGFContext C) {
4483
4482
return firstLevelResult;
4484
4483
}
4485
4484
4485
+ static void emitPseudoFunctionArguments (SILGenFunction &SGF,
4486
+ AbstractionPattern origFnType,
4487
+ CanFunctionType substFnType,
4488
+ SmallVectorImpl<ManagedValue> &outVals,
4489
+ PreparedArguments &&args);
4490
+
4486
4491
CallEmission::FirstLevelApplicationResult
4487
4492
CallEmission::applyEnumElementConstructor (SGFContext C) {
4488
4493
FirstLevelApplicationResult firstLevelResult;
@@ -4507,18 +4512,32 @@ CallEmission::applyEnumElementConstructor(SGFContext C) {
4507
4512
CanType formalResultType = firstLevelResult.formalType .getResult ();
4508
4513
4509
4514
// Ignore metatype argument
4515
+ SmallVector<ManagedValue, 0 > metatypeVal;
4516
+ emitPseudoFunctionArguments (SGF,
4517
+ AbstractionPattern (firstLevelResult.formalType ),
4518
+ firstLevelResult.formalType , metatypeVal,
4519
+ std::move (uncurriedSites[0 ]).forward ());
4520
+ assert (metatypeVal.size () == 1 );
4521
+
4510
4522
origFormalType = origFormalType.getFunctionResultType ();
4511
4523
claimNextParamClause (firstLevelResult.formalType );
4512
- std::move (uncurriedSites[0 ]).forward ().getAsSingleValue (SGF);
4513
4524
4514
4525
// Get the payload argument.
4515
4526
ArgumentSource payload;
4516
4527
if (element->hasAssociatedValues ()) {
4517
4528
assert (uncurriedSites.size () == 2 );
4518
4529
SmallVector<ManagedValue, 4 > argVals;
4519
4530
auto resultFnType = cast<FunctionType>(formalResultType);
4520
- auto arg = SGF.prepareEnumPayload (element, resultFnType,
4521
- std::move (uncurriedSites[1 ]).forward ());
4531
+
4532
+ emitPseudoFunctionArguments (SGF,
4533
+ AbstractionPattern (resultFnType),
4534
+ resultFnType, argVals,
4535
+ std::move (uncurriedSites[1 ]).forward ());
4536
+
4537
+ auto payloadTy = AnyFunctionType::composeInput (SGF.getASTContext (),
4538
+ resultFnType.getParams (),
4539
+ /* canonicalVararg*/ true );
4540
+ auto arg = RValue (SGF, argVals, payloadTy->getCanonicalType ());
4522
4541
payload = ArgumentSource (element, std::move (arg));
4523
4542
formalResultType = firstLevelResult.formalType .getResult ();
4524
4543
origFormalType = origFormalType.getFunctionResultType ();
@@ -4640,7 +4659,10 @@ CallEmission::applySpecializedEmitter(SpecializedEmitter &specializedEmitter,
4640
4659
4641
4660
// We should be able to enforce that these arguments are
4642
4661
// always still expressions.
4643
- Expr *argument = std::move (uncurriedSites[0 ]).forward ().asKnownExpr ();
4662
+ PreparedArguments args = std::move (uncurriedSites[0 ]).forward ();
4663
+ assert (args.isScalar ());
4664
+ Expr *argument = std::move (std::move (args).getSources ()[0 ]).asKnownExpr ();
4665
+
4644
4666
ManagedValue resultMV =
4645
4667
emitter (SGF, uncurriedLoc, callee.getSubstitutions (),
4646
4668
argument, uncurriedContext);
@@ -5982,9 +6004,10 @@ static void collectFakeIndexParameters(SILGenFunction &SGF,
5982
6004
}
5983
6005
5984
6006
static void emitPseudoFunctionArguments (SILGenFunction &SGF,
6007
+ AbstractionPattern origFnType,
5985
6008
CanFunctionType substFnType,
5986
6009
SmallVectorImpl<ManagedValue> &outVals,
5987
- ArgumentSource &&source ) {
6010
+ PreparedArguments &&args ) {
5988
6011
auto substParams = substFnType->getParams ();
5989
6012
5990
6013
SmallVector<SILParameterInfo, 4 > substParamTys;
@@ -6002,7 +6025,7 @@ static void emitPseudoFunctionArguments(SILGenFunction &SGF,
6002
6025
argValues, delayedArgs,
6003
6026
/* foreign error*/ None, ImportAsMemberStatus ());
6004
6027
6005
- emitter.emitTopLevel (std::move (source ), AbstractionPattern (substFnType) );
6028
+ emitter.emitPreparedArgs (std::move (args ), origFnType );
6006
6029
6007
6030
// TODO: do something to preserve LValues in the delayed arguments?
6008
6031
if (!delayedArgs.empty ())
@@ -6034,11 +6057,22 @@ SILGenFunction::prepareSubscriptIndices(SubscriptDecl *subscript,
6034
6057
substFnType = cast<FunctionType>(interfaceType
6035
6058
->getCanonicalType ());
6036
6059
6060
+
6061
+ AbstractionPattern origFnType (substFnType);
6062
+
6063
+ // Prepare the unevaluated index expression.
6037
6064
auto substParams = substFnType->getParams ();
6065
+ PreparedArguments args (substParams, /* isScalar=*/ true );
6066
+ args.addArbitrary (indexExpr);
6038
6067
6068
+ // Now, force it to be evaluated.
6039
6069
SmallVector<ManagedValue, 4 > argValues;
6040
- emitPseudoFunctionArguments (*this , substFnType, argValues, indexExpr);
6070
+ emitPseudoFunctionArguments (*this , origFnType, substFnType,
6071
+ argValues, std::move (args));
6041
6072
6073
+ // Finally, prepare the evaluated index expression. We might be calling
6074
+ // the getter and setter, and it is important to only evaluate the
6075
+ // index expression once.
6042
6076
PreparedArguments result (substParams, /* isScalar=*/ false );
6043
6077
6044
6078
ArrayRef<ManagedValue> remainingArgs = argValues;
@@ -6055,19 +6089,6 @@ SILGenFunction::prepareSubscriptIndices(SubscriptDecl *subscript,
6055
6089
return result;
6056
6090
}
6057
6091
6058
- RValue
6059
- SILGenFunction::prepareEnumPayload (EnumElementDecl *element,
6060
- CanFunctionType substFnType,
6061
- ArgumentSource &&args) {
6062
- SmallVector<ManagedValue, 4 > argValues;
6063
- emitPseudoFunctionArguments (*this , substFnType, argValues, std::move (args));
6064
-
6065
- auto payloadTy = AnyFunctionType::composeInput (getASTContext (),
6066
- substFnType.getParams (),
6067
- /* canonicalVararg*/ true );
6068
- return RValue (*this , argValues, payloadTy->getCanonicalType ());
6069
- }
6070
-
6071
6092
SILDeclRef SILGenModule::getAccessorDeclRef (AccessorDecl *accessor) {
6072
6093
return SILDeclRef (accessor, SILDeclRef::Kind::Func)
6073
6094
.asForeign (requiresForeignEntryPoint (accessor));
0 commit comments