@@ -180,6 +180,46 @@ static CanSILFunctionType getDynamicMethodLoweredType(SILGenFunction &gen,
180
180
return replaceSelfTypeForDynamicLookup (ctx, methodTy, selfTy, methodName);
181
181
}
182
182
183
+ // / Emit a sequence of instructions to partially apply the self
184
+ // / parameter of a super method invocation.
185
+ static ManagedValue emitPartialSuperMethod (SILGenFunction &SGF,
186
+ SILDeclRef constant,
187
+ SILLocation loc,
188
+ ArrayRef<Substitution> subs,
189
+ ArrayRef<ManagedValue> values,
190
+ CanFunctionType formalApplyType,
191
+ SGFContext C) {
192
+
193
+ assert (values.size () == 1 &&
194
+ " Can only partially apply the self parameater of a super method call" );
195
+
196
+ auto upcastedSelf = values.back ();
197
+
198
+ auto self = cast<UpcastInst>(upcastedSelf.getValue ())->getOperandRef ().get ();
199
+
200
+ auto constantInfo = SGF.getConstantInfo (constant);
201
+ SILValue superMethodVal = SGF.B .createSuperMethod (loc,
202
+ self,
203
+ constant,
204
+ constantInfo.getSILType (),
205
+ /* volatile*/
206
+ constant.isForeign );
207
+
208
+ auto closureTy = SILGenBuilder::getPartialApplyResultType (
209
+ constantInfo.getSILType (),
210
+ 1 ,
211
+ SGF.B .getModule (),
212
+ subs);
213
+
214
+ SILValue partialApply = SGF.B .createPartialApply (loc,
215
+ superMethodVal,
216
+ constantInfo.getSILType (),
217
+ subs,
218
+ { upcastedSelf.forward (SGF) },
219
+ closureTy);
220
+ return ManagedValue::forUnmanaged (partialApply);
221
+ }
222
+
183
223
namespace {
184
224
185
225
// / Abstractly represents a callee, and knows how to emit the entry point
@@ -650,6 +690,10 @@ class Callee {
650
690
return Substitutions;
651
691
}
652
692
693
+ SILDeclRef getMethodName () const {
694
+ return Method.MethodName ;
695
+ }
696
+
653
697
// / Return a specialized emission function if this is a function with a known
654
698
// / lowering, such as a builtin, or return null if there is no specialized
655
699
// / emitter.
@@ -663,9 +707,11 @@ class Callee {
663
707
case Kind::StandaloneFunction: {
664
708
return SpecializedEmitter::forDecl (SGM, StandaloneFunction);
665
709
}
710
+ case Kind::SuperMethod: {
711
+ return SpecializedEmitter (emitPartialSuperMethod);
712
+ }
666
713
case Kind::IndirectValue:
667
714
case Kind::ClassMethod:
668
- case Kind::SuperMethod:
669
715
case Kind::WitnessMethod:
670
716
case Kind::DynamicMethod:
671
717
return None;
@@ -3235,6 +3281,15 @@ namespace {
3235
3281
uncurriedArgs,
3236
3282
formalApplyType,
3237
3283
uncurriedContext);
3284
+ } else if (specializedEmitter->isLatePartialSuperEmitter ()) {
3285
+ auto emitter = specializedEmitter->getLatePartialSuperEmitter ();
3286
+ result = emitter (gen,
3287
+ callee.getMethodName (),
3288
+ uncurriedLoc.getValue (),
3289
+ callee.getSubstitutions (),
3290
+ uncurriedArgs,
3291
+ formalApplyType,
3292
+ uncurriedContext);
3238
3293
} else {
3239
3294
assert (specializedEmitter->isNamedBuiltin ());
3240
3295
auto builtinName = specializedEmitter->getBuiltinName ();
0 commit comments