Skip to content

Commit 6d831bd

Browse files
committed
Add specialized emitter for partially applied super_method
This creates the heavy lifting in SILGen of emission of super methods with the implicit self partially applied, which is still possible even after removing curried function declaration syntax. NFC for current IRGen - SILGen doesn't lead to here yet. rdar://problem/22749732
1 parent ed599c1 commit 6d831bd

File tree

1 file changed

+56
-1
lines changed

1 file changed

+56
-1
lines changed

lib/SILGen/SILGenApply.cpp

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,46 @@ static CanSILFunctionType getDynamicMethodLoweredType(SILGenFunction &gen,
180180
return replaceSelfTypeForDynamicLookup(ctx, methodTy, selfTy, methodName);
181181
}
182182

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+
183223
namespace {
184224

185225
/// Abstractly represents a callee, and knows how to emit the entry point
@@ -650,6 +690,10 @@ class Callee {
650690
return Substitutions;
651691
}
652692

693+
SILDeclRef getMethodName() const {
694+
return Method.MethodName;
695+
}
696+
653697
/// Return a specialized emission function if this is a function with a known
654698
/// lowering, such as a builtin, or return null if there is no specialized
655699
/// emitter.
@@ -663,9 +707,11 @@ class Callee {
663707
case Kind::StandaloneFunction: {
664708
return SpecializedEmitter::forDecl(SGM, StandaloneFunction);
665709
}
710+
case Kind::SuperMethod: {
711+
return SpecializedEmitter(emitPartialSuperMethod);
712+
}
666713
case Kind::IndirectValue:
667714
case Kind::ClassMethod:
668-
case Kind::SuperMethod:
669715
case Kind::WitnessMethod:
670716
case Kind::DynamicMethod:
671717
return None;
@@ -3235,6 +3281,15 @@ namespace {
32353281
uncurriedArgs,
32363282
formalApplyType,
32373283
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);
32383293
} else {
32393294
assert(specializedEmitter->isNamedBuiltin());
32403295
auto builtinName = specializedEmitter->getBuiltinName();

0 commit comments

Comments
 (0)