@@ -498,21 +498,62 @@ class Callee {
498
498
return result;
499
499
}
500
500
501
+ SILDeclRef getConstantAtUncurryLevel (unsigned level) const {
502
+ unsigned uncurryLevel = Constant.getUncurryLevel ();
503
+ assert (level <= uncurryLevel &&
504
+ " uncurrying past natural uncurry level of standalone function" );
505
+ if (level < uncurryLevel) {
506
+ assert (level == 0 );
507
+ auto constant = Constant.asCurried ();
508
+
509
+ // If we're currying a direct reference to a class-dispatched method,
510
+ // make sure we emit the right set of thunks.
511
+ if (kind == Kind::StandaloneFunction) {
512
+ if (auto func = Constant.getAbstractFunctionDecl ()) {
513
+ if (getMethodDispatch (func) == MethodDispatch::Class) {
514
+ return constant.asDirectReference (true );
515
+ }
516
+ }
517
+ }
518
+
519
+ return constant;
520
+ }
521
+
522
+ return Constant;
523
+ }
524
+
525
+ SILType getDynamicMethodType (SILGenFunction &SGF) const {
526
+ // Lower the substituted type from the AST, which should have any generic
527
+ // parameters in the original signature erased to their upper bounds.
528
+ auto substFormalType = getSubstFormalType ();
529
+ auto objcFormalType = substFormalType.withExtInfo (
530
+ substFormalType->getExtInfo ().withSILRepresentation (
531
+ SILFunctionTypeRepresentation::ObjCMethod));
532
+ auto fnType = SGF.SGM .M .Types .getUncachedSILFunctionTypeForConstant (
533
+ Constant, objcFormalType);
534
+
535
+ auto closureType = replaceSelfTypeForDynamicLookup (
536
+ SGF.getASTContext (), fnType,
537
+ SelfValue.getValue ().getSILSubstType (SGF).getSwiftRValueType (),
538
+ Constant);
539
+
540
+ return SILType::getPrimitiveObjectType (closureType);
541
+ }
542
+
501
543
ManagedValue getFnValueAtUncurryLevel (SILGenFunction &SGF,
502
544
unsigned level) const & {
503
545
Optional<SILDeclRef> constant = None;
504
546
505
547
if (!Constant) {
506
548
assert (level == 0 && " can't curry indirect function" );
507
549
} else {
508
- unsigned uncurryLevel = Constant.getUncurryLevel ();
509
- assert (level <= uncurryLevel &&
510
- " uncurrying past natural uncurry level of standalone function" );
511
- if (level < uncurryLevel) {
512
- assert (level == 0 );
513
- constant = Constant.asCurried ();
514
- } else {
515
- constant = Constant;
550
+ constant = getConstantAtUncurryLevel (level);
551
+
552
+ // If the call is curried, emit a direct call to the curry thunk.
553
+ if (constant->isCurried ) {
554
+ auto constantInfo = SGF.getConstantInfo (*constant);
555
+ SILValue ref = SGF.emitGlobalFunctionRef (Loc, *constant, constantInfo);
556
+ return ManagedValue::forUnmanaged (ref);
516
557
}
517
558
}
518
559
@@ -522,36 +563,13 @@ class Callee {
522
563
return IndirectValue;
523
564
524
565
case Kind::StandaloneFunction: {
525
- // If we're currying a direct reference to a class-dispatched method,
526
- // make sure we emit the right set of thunks.
527
- if (constant->isCurried && Constant.hasDecl ())
528
- if (auto func = Constant.getAbstractFunctionDecl ())
529
- if (getMethodDispatch (func) == MethodDispatch::Class)
530
- constant = constant->asDirectReference (true );
531
-
532
- auto constantInfo = SGF.getConstantInfo (*constant);
533
- SILValue ref = SGF.emitGlobalFunctionRef (Loc, *constant, constantInfo);
534
- return ManagedValue::forUnmanaged (ref);
535
- }
536
- case Kind::EnumElement: {
537
566
auto constantInfo = SGF.getConstantInfo (*constant);
538
-
539
- // We should not end up here if the enum constructor call is fully
540
- // applied.
541
- assert (constant->isCurried );
542
-
543
567
SILValue ref = SGF.emitGlobalFunctionRef (Loc, *constant, constantInfo);
544
568
return ManagedValue::forUnmanaged (ref);
545
569
}
570
+ case Kind::EnumElement:
571
+ llvm_unreachable (" Should have been curried" );
546
572
case Kind::ClassMethod: {
547
- auto constantInfo = SGF.getConstantInfo (*constant);
548
-
549
- // If the call is curried, emit a direct call to the curry thunk.
550
- if (constant->isCurried ) {
551
- SILValue ref = SGF.emitGlobalFunctionRef (Loc, *constant, constantInfo);
552
- return ManagedValue::forUnmanaged (ref);
553
- }
554
-
555
573
auto methodTy = SGF.SGM .Types .getConstantOverrideType (*constant);
556
574
557
575
// Otherwise, do the dynamic dispatch inline.
@@ -594,15 +612,8 @@ class Callee {
594
612
case Kind::WitnessMethod: {
595
613
auto constantInfo = SGF.getConstantInfo (*constant);
596
614
597
- // If the call is curried, emit a direct call to the curry thunk.
598
- if (constant->isCurried ) {
599
- SILValue ref = SGF.emitGlobalFunctionRef (Loc, *constant, constantInfo);
600
- return ManagedValue::forUnmanaged (ref);
601
- }
602
-
603
- auto proto = Constant.getDecl ()
604
- ->getDeclContext ()
605
- ->getAsProtocolOrProtocolExtensionContext ();
615
+ auto proto = cast<ProtocolDecl>(
616
+ Constant.getDecl ()->getDeclContext ());
606
617
auto lookupType = getSubstFormalType ()
607
618
.getInput ()
608
619
->getRValueInstanceType ()
@@ -612,32 +623,17 @@ class Callee {
612
623
Loc, lookupType, ProtocolConformanceRef (proto), *constant,
613
624
constantInfo.getSILType (), constant->isForeign );
614
625
return ManagedValue::forUnmanaged (fn);
615
- ;
616
626
}
617
627
case Kind::DynamicMethod: {
618
- assert (!constant->isCurried );
619
628
assert (constant->isForeign );
620
-
621
- // Lower the substituted type from the AST, which should have any generic
622
- // parameters in the original signature erased to their upper bounds.
623
- auto substFormalType = getSubstFormalType ();
624
- auto objcFormalType = substFormalType.withExtInfo (
625
- substFormalType->getExtInfo ().withSILRepresentation (
626
- SILFunctionTypeRepresentation::ObjCMethod));
627
- auto fnType = SGF.SGM .M .Types .getUncachedSILFunctionTypeForConstant (
628
- *constant, objcFormalType);
629
-
630
- auto closureType = replaceSelfTypeForDynamicLookup (
631
- SGF.getASTContext (), fnType,
632
- SelfValue.getValue ().getSILSubstType (SGF).getSwiftRValueType (),
633
- Constant);
629
+ auto closureType = getDynamicMethodType (SGF);
634
630
635
631
Scope S (SGF, Loc);
636
632
ManagedValue self =
637
633
SelfValue.getValue ().borrow (SGF).getAsSingleValue (SGF);
638
634
SILValue fn = SGF.B .createObjCMethod (
639
635
Loc, self.getValue (), *constant,
640
- SILType::getPrimitiveObjectType ( closureType) );
636
+ closureType);
641
637
return ManagedValue::forUnmanaged (fn);
642
638
}
643
639
}
@@ -650,14 +646,12 @@ class Callee {
650
646
if (!Constant) {
651
647
assert (level == 0 && " can't curry indirect function" );
652
648
} else {
653
- unsigned uncurryLevel = Constant.getUncurryLevel ();
654
- assert (level <= uncurryLevel &&
655
- " uncurrying past natural uncurry level of standalone function" );
656
- if (level < uncurryLevel) {
657
- assert (level == 0 );
658
- constant = Constant.asCurried ();
659
- } else {
660
- constant = Constant;
649
+ constant = getConstantAtUncurryLevel (level);
650
+
651
+ // If the call is curried, emit a direct call to the curry thunk.
652
+ if (constant->isCurried ) {
653
+ auto constantInfo = SGF.getConstantInfo (*constant);
654
+ return createCalleeTypeInfo (SGF, constant, constantInfo.getSILType ());
661
655
}
662
656
}
663
657
@@ -667,38 +661,16 @@ class Callee {
667
661
return createCalleeTypeInfo (SGF, constant, IndirectValue.getType ());
668
662
669
663
case Kind::StandaloneFunction: {
670
- // If we're currying a direct reference to a class-dispatched method,
671
- // make sure we emit the right set of thunks.
672
- if (constant->isCurried && Constant.hasDecl ())
673
- if (auto func = Constant.getAbstractFunctionDecl ())
674
- if (getMethodDispatch (func) == MethodDispatch::Class)
675
- constant = constant->asDirectReference (true );
676
-
677
664
auto constantInfo = SGF.getConstantInfo (*constant);
678
665
return createCalleeTypeInfo (SGF, constant, constantInfo.getSILType ());
679
- ;
680
- }
681
- case Kind::EnumElement: {
682
- auto constantInfo = SGF.getConstantInfo (*constant);
683
-
684
- // We should not end up here if the enum constructor call is fully
685
- // applied.
686
- assert (constant->isCurried );
687
- return createCalleeTypeInfo (SGF, constant, constantInfo.getSILType ());
688
666
}
667
+ case Kind::EnumElement:
668
+ llvm_unreachable (" Should have been curried" );
689
669
case Kind::ClassMethod: {
690
- // If the call is curried, emit a direct call to the curry thunk.
691
- if (constant->isCurried ) {
692
- auto constantInfo = SGF.getConstantInfo (*constant);
693
- return createCalleeTypeInfo (SGF, constant, constantInfo.getSILType ());
694
- }
695
-
696
- // Otherwise, grab the override info.
697
670
auto constantInfo = SGF.SGM .Types .getConstantOverrideInfo (*constant);
698
671
return createCalleeTypeInfo (SGF, constant, constantInfo.getSILType ());
699
672
}
700
673
case Kind::SuperMethod: {
701
- assert (!constant->isCurried );
702
674
auto base = SGF.SGM .Types .getOverriddenVTableEntry (*constant);
703
675
auto constantInfo =
704
676
SGF.SGM .Types .getConstantOverrideInfo (*constant, base);
@@ -709,23 +681,7 @@ class Callee {
709
681
return createCalleeTypeInfo (SGF, constant, constantInfo.getSILType ());
710
682
}
711
683
case Kind::DynamicMethod: {
712
- assert (!constant->isCurried );
713
-
714
- // Lower the substituted type from the AST, which should have any generic
715
- // parameters in the original signature erased to their upper bounds.
716
- auto substFormalType = getSubstFormalType ();
717
- auto objcFormalType = substFormalType.withExtInfo (
718
- substFormalType->getExtInfo ().withSILRepresentation (
719
- SILFunctionTypeRepresentation::ObjCMethod));
720
- auto fnType = SGF.SGM .M .Types .getUncachedSILFunctionTypeForConstant (
721
- *constant, objcFormalType);
722
-
723
- auto closureType = replaceSelfTypeForDynamicLookup (
724
- SGF.getASTContext (), fnType,
725
- SelfValue.getValue ().getSILSubstType (SGF).getSwiftRValueType (),
726
- Constant);
727
-
728
- SILType formalType = SILType::getPrimitiveObjectType (closureType);
684
+ auto formalType = getDynamicMethodType (SGF);
729
685
return createCalleeTypeInfo (SGF, constant, formalType);
730
686
}
731
687
}
0 commit comments