@@ -157,6 +157,9 @@ static bool canUseStaticDispatch(SILGenFunction &SGF,
157
157
}
158
158
159
159
static SILValue getOriginalSelfValue (SILValue selfValue) {
160
+ if (auto *TTOI = dyn_cast<ThickToObjCMetatypeInst>(selfValue))
161
+ selfValue = TTOI->getOperand ();
162
+
160
163
if (auto *BBI = dyn_cast<BeginBorrowInst>(selfValue))
161
164
selfValue = BBI->getOperand ();
162
165
@@ -242,10 +245,6 @@ class Callee {
242
245
// / *NOTE* This should never be non-null if IndirectValue is non-null.
243
246
SILDeclRef Constant;
244
247
245
- // / This field is set if we are calling to a SuperMethod or ClassMethod and
246
- // / thus need to pass self to get the correct implementation.
247
- Optional<ArgumentSource> SelfValue;
248
-
249
248
// / The abstraction pattern of the callee.
250
249
AbstractionPattern OrigFormalInterfaceType;
251
250
@@ -298,11 +297,10 @@ class Callee {
298
297
{
299
298
}
300
299
301
- Callee (Kind methodKind, SILGenFunction &SGF,
302
- Optional<ArgumentSource> &&selfValue, SILDeclRef methodName,
300
+ Callee (Kind methodKind, SILGenFunction &SGF, SILDeclRef methodName,
303
301
AbstractionPattern origFormalType, CanAnyFunctionType substFormalType,
304
302
SubstitutionList subs, SILLocation l)
305
- : kind(methodKind), Constant(methodName), SelfValue(std::move(selfValue)),
303
+ : kind(methodKind), Constant(methodName),
306
304
OrigFormalInterfaceType(origFormalType),
307
305
SubstFormalInterfaceType(
308
306
getSubstFormalInterfaceType (substFormalType, subs)),
@@ -327,23 +325,23 @@ class Callee {
327
325
SILLocation l) {
328
326
assert (isa<EnumElementDecl>(c.getDecl ()));
329
327
auto &ci = SGF.getConstantInfo (c);
330
- return Callee (Kind::EnumElement, SGF, None, c, ci.FormalPattern ,
328
+ return Callee (Kind::EnumElement, SGF, c, ci.FormalPattern ,
331
329
ci.FormalType , subs, l);
332
330
}
333
- static Callee forClassMethod (SILGenFunction &SGF, ArgumentSource &&selfValue,
331
+ static Callee forClassMethod (SILGenFunction &SGF,
334
332
SILDeclRef c, SubstitutionList subs,
335
333
SILLocation l) {
336
334
auto base = SGF.SGM .Types .getOverriddenVTableEntry (c);
337
335
auto &baseCI = SGF.getConstantInfo (base);
338
336
auto &derivedCI = SGF.getConstantInfo (c);
339
- return Callee (Kind::ClassMethod, SGF, std::move (selfValue), c,
337
+ return Callee (Kind::ClassMethod, SGF, c,
340
338
baseCI.FormalPattern , derivedCI.FormalType , subs, l);
341
339
}
342
- static Callee forSuperMethod (SILGenFunction &SGF, ArgumentSource &&selfValue,
340
+ static Callee forSuperMethod (SILGenFunction &SGF,
343
341
SILDeclRef c, SubstitutionList subs,
344
342
SILLocation l) {
345
343
auto &ci = SGF.getConstantInfo (c);
346
- return Callee (Kind::SuperMethod, SGF, std::move (selfValue), c,
344
+ return Callee (Kind::SuperMethod, SGF, c,
347
345
ci.FormalPattern , ci.FormalType , subs, l);
348
346
}
349
347
static Callee forWitnessMethod (SILGenFunction &SGF,
@@ -352,10 +350,10 @@ class Callee {
352
350
SubstitutionList subs,
353
351
SILLocation l) {
354
352
auto &ci = SGF.getConstantInfo (c);
355
- return Callee (Kind::WitnessMethod, SGF, None, c, ci.FormalPattern ,
353
+ return Callee (Kind::WitnessMethod, SGF, c, ci.FormalPattern ,
356
354
ci.FormalType , subs, l);
357
355
}
358
- static Callee forDynamic (SILGenFunction &SGF, ArgumentSource &&arg,
356
+ static Callee forDynamic (SILGenFunction &SGF,
359
357
SILDeclRef c, const SubstitutionList &constantSubs,
360
358
CanAnyFunctionType substFormalType,
361
359
SubstitutionList subs, SILLocation l) {
@@ -377,7 +375,7 @@ class Callee {
377
375
}
378
376
origFormalType.rewriteType (CanGenericSignature (), origFormalFnType);
379
377
380
- return Callee (Kind::DynamicMethod, SGF, std::move (arg), c, origFormalType,
378
+ return Callee (Kind::DynamicMethod, SGF, c, origFormalType,
381
379
substFormalType, subs, l);
382
380
}
383
381
@@ -423,6 +421,22 @@ class Callee {
423
421
llvm_unreachable (" Unhandled Kind in switch." );
424
422
}
425
423
424
+ bool requiresSelfValueForDispatch () const {
425
+ switch (kind) {
426
+ case Kind::IndirectValue:
427
+ case Kind::StandaloneFunction:
428
+ case Kind::EnumElement:
429
+ case Kind::WitnessMethod:
430
+ return false ;
431
+ case Kind::ClassMethod:
432
+ case Kind::SuperMethod:
433
+ case Kind::DynamicMethod:
434
+ return true ;
435
+ }
436
+
437
+ llvm_unreachable (" Unhandled Kind in switch." );
438
+ }
439
+
426
440
EnumElementDecl *getEnumElementDecl () {
427
441
assert (kind == Kind::EnumElement);
428
442
return cast<EnumElementDecl>(Constant.getDecl ());
@@ -480,7 +494,8 @@ class Callee {
480
494
return SILType::getPrimitiveObjectType (fnType);
481
495
}
482
496
483
- ManagedValue getFnValue (SILGenFunction &SGF, bool isCurried) const & {
497
+ ManagedValue getFnValue (SILGenFunction &SGF, bool isCurried,
498
+ Optional<ManagedValue> borrowedSelf) const & {
484
499
Optional<SILDeclRef> constant = None;
485
500
486
501
if (!Constant) {
@@ -513,17 +528,15 @@ class Callee {
513
528
514
529
// Otherwise, do the dynamic dispatch inline.
515
530
Scope S (SGF, Loc);
516
- ManagedValue borrowedSelf =
517
- SelfValue.getValue ().borrow (SGF).getAsSingleValue (SGF);
518
531
519
532
SILValue methodVal;
520
533
if (!constant->isForeign ) {
521
534
methodVal = SGF.B .createClassMethod (
522
- Loc, borrowedSelf. getValue (), *constant,
535
+ Loc, borrowedSelf-> getValue (), *constant,
523
536
SILType::getPrimitiveObjectType (methodTy));
524
537
} else {
525
538
methodVal = SGF.B .createObjCMethod (
526
- Loc, borrowedSelf. getValue (), *constant,
539
+ Loc, borrowedSelf-> getValue (), *constant,
527
540
SILType::getPrimitiveObjectType (methodTy));
528
541
}
529
542
return ManagedValue::forUnmanaged (methodVal);
@@ -532,9 +545,8 @@ class Callee {
532
545
assert (!constant->isCurried );
533
546
534
547
Scope S (SGF, Loc);
535
- ManagedValue self =
536
- SelfValue.getValue ().borrow (SGF).getAsSingleValue (SGF);
537
- ManagedValue castValue = borrowedCastToOriginalSelfType (SGF, Loc, self);
548
+ ManagedValue castValue = borrowedCastToOriginalSelfType (
549
+ SGF, Loc, *borrowedSelf);
538
550
539
551
auto base = SGF.SGM .Types .getOverriddenVTableEntry (*constant);
540
552
auto constantInfo =
@@ -568,10 +580,8 @@ class Callee {
568
580
auto closureType = getDynamicMethodType (SGF.SGM .M );
569
581
570
582
Scope S (SGF, Loc);
571
- ManagedValue self =
572
- SelfValue.getValue ().borrow (SGF).getAsSingleValue (SGF);
573
583
SILValue fn = SGF.B .createObjCMethod (
574
- Loc, self. getValue (), *constant,
584
+ Loc, borrowedSelf-> getValue (), *constant,
575
585
closureType);
576
586
return ManagedValue::forUnmanaged (fn);
577
587
}
@@ -955,8 +965,7 @@ class SILGenApply : public Lowering::ExprVisitor<SILGenApply> {
955
965
ArgumentSource selfArgSource (thisCallSite->getArg (), std::move (self));
956
966
auto subs = e->getDeclRef ().getSubstitutions ();
957
967
SILLocation loc (thisCallSite->getArg ());
958
- setCallee (Callee::forClassMethod (SGF, selfArgSource.delayedBorrow (SGF),
959
- constant, subs, e));
968
+ setCallee (Callee::forClassMethod (SGF, constant, subs, e));
960
969
961
970
setSelfParam (std::move (selfArgSource), thisCallSite);
962
971
return true ;
@@ -1139,8 +1148,7 @@ class SILGenApply : public Lowering::ExprVisitor<SILGenApply> {
1139
1148
ArgumentSource superArgSource (arg, std::move (super));
1140
1149
if (!canUseStaticDispatch (SGF, constant)) {
1141
1150
// ObjC super calls require dynamic dispatch.
1142
- setCallee (Callee::forSuperMethod (SGF, superArgSource.delayedBorrow (SGF),
1143
- constant, substitutions, fn));
1151
+ setCallee (Callee::forSuperMethod (SGF, constant, substitutions, fn));
1144
1152
} else {
1145
1153
// Native Swift super calls to final methods are direct.
1146
1154
setCallee (Callee::forDirect (SGF, constant, substitutions, fn));
@@ -1309,8 +1317,7 @@ class SILGenApply : public Lowering::ExprVisitor<SILGenApply> {
1309
1317
// Dynamic dispatch to the initializer.
1310
1318
Scope S (SGF, expr);
1311
1319
setCallee (Callee::forClassMethod (
1312
- SGF, selfArgSource.delayedBorrow (SGF),
1313
- constant, subs, fn));
1320
+ SGF, constant, subs, fn));
1314
1321
} else {
1315
1322
// Directly call the peer constructor.
1316
1323
setCallee (
@@ -1409,8 +1416,7 @@ class SILGenApply : public Lowering::ExprVisitor<SILGenApply> {
1409
1416
dynamicMemberRef->getBase ()->getType ()->getCanonicalType (),
1410
1417
substFormalType, AnyFunctionType::ExtInfo ());
1411
1418
1412
- setCallee (Callee::forDynamic (SGF, baseArgSource.delayedBorrow (SGF),
1413
- member, memberRef.getSubstitutions (),
1419
+ setCallee (Callee::forDynamic (SGF, member, memberRef.getSubstitutions (),
1414
1420
substFormalType, {}, e));
1415
1421
setSelfParam (std::move (baseArgSource), dynamicMemberRef);
1416
1422
};
@@ -4069,7 +4075,6 @@ CallEmission::applyNormalCall(SGFContext C) {
4069
4075
4070
4076
// Get the callee type information.
4071
4077
auto calleeTypeInfo = callee.getTypeInfo (SGF, isCurried);
4072
- auto mv = callee.getFnValue (SGF, isCurried);
4073
4078
4074
4079
// In C language modes, substitute the type of the AbstractionPattern
4075
4080
// so that we won't see type parameters down when we try to form bridging
@@ -4117,6 +4122,15 @@ CallEmission::applyNormalCall(SGFContext C) {
4117
4122
firstLevelResult.formalType , origFormalType, calleeTypeInfo.substFnType ,
4118
4123
calleeTypeInfo.foreignError , calleeTypeInfo.foreignSelf , uncurriedArgs,
4119
4124
uncurriedLoc, formalApplyType);
4125
+
4126
+ // Now evaluate the callee.
4127
+ Optional<ManagedValue> borrowedSelf;
4128
+ if (callee.requiresSelfValueForDispatch ()) {
4129
+ borrowedSelf = uncurriedArgs.back ();
4130
+ }
4131
+
4132
+ auto mv = callee.getFnValue (SGF, isCurried, borrowedSelf);
4133
+
4120
4134
// Emit the uncurried call.
4121
4135
firstLevelResult.value =
4122
4136
SGF.emitApply (std::move (resultPlan), std::move (argScope),
@@ -4555,7 +4569,12 @@ SILGenFunction::emitApplyOfLibraryIntrinsic(SILLocation loc,
4555
4569
auto substFormalType = callee.getSubstFormalType ();
4556
4570
4557
4571
auto calleeTypeInfo = callee.getTypeInfo (*this , /* isCurried=*/ false );
4558
- auto mv = callee.getFnValue (*this , /* isCurried=*/ false );
4572
+
4573
+ Optional<ManagedValue> borrowedSelf;
4574
+ if (callee.requiresSelfValueForDispatch ())
4575
+ borrowedSelf = args.back ();
4576
+ auto mv = callee.getFnValue (*this , /* isCurried=*/ false ,
4577
+ borrowedSelf);
4559
4578
4560
4579
assert (!calleeTypeInfo.foreignError );
4561
4580
assert (!calleeTypeInfo.foreignSelf .isImportAsMember ());
@@ -4884,14 +4903,12 @@ static Callee getBaseAccessorFunctionRef(SILGenFunction &SGF,
4884
4903
// Otherwise, if we have a non-final class dispatch to a normal method,
4885
4904
// perform a dynamic dispatch.
4886
4905
if (!isSuper)
4887
- return Callee::forClassMethod (SGF, selfValue.delayedBorrow (SGF), constant,
4888
- subs, loc);
4906
+ return Callee::forClassMethod (SGF, constant, subs, loc);
4889
4907
4890
4908
// If this is a "super." dispatch, we do a dynamic dispatch for objc methods
4891
4909
// or non-final native Swift methods.
4892
4910
if (!canUseStaticDispatch (SGF, constant))
4893
- return Callee::forSuperMethod (SGF, selfValue.delayedBorrow (SGF), constant,
4894
- subs, loc);
4911
+ return Callee::forSuperMethod (SGF, constant, subs, loc);
4895
4912
4896
4913
return Callee::forDirect (SGF, constant, subs, loc);
4897
4914
}
0 commit comments