@@ -768,15 +768,12 @@ class PartialApplicationForwarderEmission {
768
768
origParams(subIGF.collectParameters()) {}
769
769
770
770
public:
771
- enum class DynamicFunctionKind {
772
- Witness,
773
- PartialApply,
774
- };
775
771
virtual void begin (){};
776
772
777
773
virtual void gatherArgumentsFromApply () = 0;
778
774
779
- virtual void mapAsyncParameters () {}
775
+ virtual void mapAsyncParameters (FunctionPointer fnPtr) {}
776
+ virtual void recordAsyncParametersInsertionPoint (){};
780
777
781
778
void gatherArgumentsFromApply (bool isAsync) {
782
779
// Lower the forwarded arguments in the original function's generic context.
@@ -831,7 +828,7 @@ class PartialApplicationForwarderEmission {
831
828
}
832
829
833
830
if (isAsync)
834
- mapAsyncParameters ();
831
+ recordAsyncParametersInsertionPoint ();
835
832
836
833
// Reemit the parameters as unsubstituted.
837
834
for (unsigned i = 0 ; i < outType->getParameters ().size (); ++i) {
@@ -921,12 +918,10 @@ class PartialApplicationForwarderEmission {
921
918
922
919
llvm::Value *getContext () { return origParams.claimNext (); }
923
920
924
- virtual llvm::Value *getDynamicFunctionPointer (PointerAuthInfo &authInfo ) = 0;
921
+ virtual llvm::Value *getDynamicFunctionPointer () = 0;
925
922
virtual llvm::Value *getDynamicFunctionContext () = 0;
926
- virtual void addDynamicFunctionContext (Explosion &explosion,
927
- DynamicFunctionKind kind) = 0;
928
- virtual void addDynamicFunctionPointer (Explosion &explosion,
929
- DynamicFunctionKind kind) = 0;
923
+ virtual void addDynamicFunctionContext (Explosion &explosion) = 0;
924
+ virtual void addDynamicFunctionPointer (Explosion &explosion) = 0;
930
925
931
926
void addSelf (Explosion &explosion) { addArgument (explosion); }
932
927
void addWitnessSelfMetadata (llvm::Value *value) {
@@ -965,16 +960,12 @@ class SyncPartialApplicationForwarderEmission
965
960
void gatherArgumentsFromApply () override {
966
961
super::gatherArgumentsFromApply (false );
967
962
}
968
- llvm::Value *getDynamicFunctionPointer (PointerAuthInfo &authInfo) override {
969
- return args.takeLast ();
970
- }
963
+ llvm::Value *getDynamicFunctionPointer () override { return args.takeLast (); }
971
964
llvm::Value *getDynamicFunctionContext () override { return args.takeLast (); }
972
- void addDynamicFunctionContext (Explosion &explosion,
973
- DynamicFunctionKind kind) override {
965
+ void addDynamicFunctionContext (Explosion &explosion) override {
974
966
addArgument (explosion);
975
967
}
976
- void addDynamicFunctionPointer (Explosion &explosion,
977
- DynamicFunctionKind kind) override {
968
+ void addDynamicFunctionPointer (Explosion &explosion) override {
978
969
addArgument (explosion);
979
970
}
980
971
void forwardErrorResult () override {
@@ -1045,13 +1036,6 @@ class AsyncPartialApplicationForwarderEmission
1045
1036
Address context;
1046
1037
Address calleeContextBuffer;
1047
1038
unsigned currentArgumentIndex;
1048
- struct DynamicFunction {
1049
- using Kind = DynamicFunctionKind;
1050
- Kind kind;
1051
- llvm::Value *pointer;
1052
- llvm::Value *context;
1053
- };
1054
- Optional<DynamicFunction> dynamicFunction = llvm::None;
1055
1039
struct Self {
1056
1040
enum class Kind {
1057
1041
Method,
@@ -1061,6 +1045,7 @@ class AsyncPartialApplicationForwarderEmission
1061
1045
llvm::Value *value;
1062
1046
};
1063
1047
Optional<Self> self = llvm::None;
1048
+ unsigned asyncParametersInsertionIndex = 0 ;
1064
1049
1065
1050
void saveValue (ElementLayout layout, Explosion &explosion) {
1066
1051
Address addr = layout.project (subIGF, context, /* offsets*/ llvm::None);
@@ -1088,24 +1073,28 @@ class AsyncPartialApplicationForwarderEmission
1088
1073
1089
1074
void begin () override { super::begin (); }
1090
1075
1091
- void mapAsyncParameters () override {
1076
+ void recordAsyncParametersInsertionPoint () override {
1092
1077
// Ignore the original context.
1093
1078
(void )origParams.claimNext ();
1094
1079
1080
+ asyncParametersInsertionIndex = args.size ();
1081
+ }
1082
+ void mapAsyncParameters (FunctionPointer fnPtr) override {
1095
1083
llvm::Value *dynamicContextSize32;
1096
1084
auto initialContextSize = Size (0 );
1097
1085
std::tie (calleeFunction, dynamicContextSize32) = getAsyncFunctionAndSize (
1098
- subIGF, origType->getRepresentation (), *staticFnPtr ,
1099
- nullptr , std::make_pair (true , true ), initialContextSize);
1086
+ subIGF, origType->getRepresentation (), fnPtr, nullptr ,
1087
+ std::make_pair (true , true ), initialContextSize);
1100
1088
auto *dynamicContextSize =
1101
1089
subIGF.Builder .CreateZExt (dynamicContextSize32, subIGF.IGM .SizeTy );
1102
1090
calleeContextBuffer =
1103
1091
emitAllocAsyncContext (subIGF, dynamicContextSize);
1104
1092
context = layout.emitCastTo (subIGF, calleeContextBuffer.getAddress ());
1105
1093
auto calleeContext =
1106
1094
layout.emitCastTo (subIGF, calleeContextBuffer.getAddress ());
1107
- args.add (subIGF.Builder .CreateBitOrPointerCast (
1108
- calleeContextBuffer.getAddress (), IGM.SwiftContextPtrTy ));
1095
+ args.insert (asyncParametersInsertionIndex,
1096
+ subIGF.Builder .CreateBitOrPointerCast (
1097
+ calleeContextBuffer.getAddress (), IGM.SwiftContextPtrTy ));
1109
1098
1110
1099
// Set caller info into the context.
1111
1100
{ // caller context
@@ -1146,20 +1135,14 @@ class AsyncPartialApplicationForwarderEmission
1146
1135
void gatherArgumentsFromApply () override {
1147
1136
super::gatherArgumentsFromApply (true );
1148
1137
}
1149
- llvm::Value *getDynamicFunctionPointer (PointerAuthInfo &authInfo) override {
1150
- llvm_unreachable (
1151
- " async partial applies never have dynamic function pointers" );
1152
- }
1138
+ llvm::Value *getDynamicFunctionPointer () override { return args.takeLast (); }
1153
1139
llvm::Value *getDynamicFunctionContext () override {
1154
1140
return args.takeLast ();
1155
1141
}
1156
- void addDynamicFunctionContext (Explosion &explosion,
1157
- DynamicFunction::Kind kind) override {
1142
+ void addDynamicFunctionContext (Explosion &explosion) override {
1158
1143
addArgument (explosion);
1159
1144
}
1160
- void addDynamicFunctionPointer (Explosion &explosion,
1161
- DynamicFunction::Kind kind) override {
1162
- assert (false );
1145
+ void addDynamicFunctionPointer (Explosion &explosion) override {
1163
1146
addArgument (explosion);
1164
1147
}
1165
1148
@@ -1669,20 +1652,10 @@ static llvm::Value *emitPartialApplicationForwarder(IRGenModule &IGM,
1669
1652
} else {
1670
1653
switch (extraFieldIndex) {
1671
1654
case 0 :
1672
- emission->addDynamicFunctionContext (
1673
- param, isWitnessMethodCallee
1674
- ? PartialApplicationForwarderEmission::
1675
- DynamicFunctionKind::Witness
1676
- : PartialApplicationForwarderEmission::
1677
- DynamicFunctionKind::PartialApply);
1655
+ emission->addDynamicFunctionContext (param);
1678
1656
break ;
1679
1657
case 1 :
1680
- emission->addDynamicFunctionPointer (
1681
- param, isWitnessMethodCallee
1682
- ? PartialApplicationForwarderEmission::
1683
- DynamicFunctionKind::Witness
1684
- : PartialApplicationForwarderEmission::
1685
- DynamicFunctionKind::PartialApply);
1658
+ emission->addDynamicFunctionPointer (param);
1686
1659
break ;
1687
1660
default :
1688
1661
llvm_unreachable (" unexpected extra field in thick context" );
@@ -1724,22 +1697,29 @@ static llvm::Value *emitPartialApplicationForwarder(IRGenModule &IGM,
1724
1697
// Otherwise, it was the last thing we added to the layout.
1725
1698
1726
1699
assert (lastCapturedFieldPtr);
1727
- auto authInfo = PointerAuthInfo::emit (subIGF,
1728
- IGM.getOptions ().PointerAuth .PartialApplyCapture ,
1729
- lastCapturedFieldPtr,
1730
- PointerAuthEntity::Special::PartialApplyCapture);
1700
+ auto authInfo = PointerAuthInfo::emit (
1701
+ subIGF,
1702
+ origType->isAsync ()
1703
+ ? IGM.getOptions ().PointerAuth .AsyncPartialApplyCapture
1704
+ : IGM.getOptions ().PointerAuth .PartialApplyCapture ,
1705
+ lastCapturedFieldPtr, PointerAuthEntity::Special::PartialApplyCapture);
1731
1706
1732
1707
// The dynamic function pointer is packed "last" into the context,
1733
1708
// and we pulled it out as an argument. Just pop it off.
1734
- auto fnPtr = emission->getDynamicFunctionPointer (authInfo );
1709
+ auto fnPtr = emission->getDynamicFunctionPointer ();
1735
1710
1736
1711
// It comes out of the context as an i8*. Cast to the function type.
1737
1712
fnPtr = subIGF.Builder .CreateBitCast (fnPtr, fnTy);
1738
1713
1739
- return FunctionPointer (FunctionPointer::Kind::Function, fnPtr, authInfo,
1740
- origSig);
1714
+ return FunctionPointer (origType->isAsync ()
1715
+ ? FunctionPointer::Kind::AsyncFunctionPointer
1716
+ : FunctionPointer::Kind::Function,
1717
+ fnPtr, authInfo, origSig);
1741
1718
}();
1742
1719
1720
+ if (origType->isAsync ())
1721
+ emission->mapAsyncParameters (fnPtr);
1722
+
1743
1723
// Derive the context argument if needed. This is either:
1744
1724
// - the saved context argument, in which case it was the last
1745
1725
// thing we added to the layout other than a possible non-static
@@ -1770,12 +1750,7 @@ static llvm::Value *emitPartialApplicationForwarder(IRGenModule &IGM,
1770
1750
if (isMethodCallee) {
1771
1751
emission->addSelf (explosion);
1772
1752
} else {
1773
- emission->addDynamicFunctionContext (
1774
- explosion, isWitnessMethodCallee
1775
- ? PartialApplicationForwarderEmission::
1776
- DynamicFunctionKind::Witness
1777
- : PartialApplicationForwarderEmission::
1778
- DynamicFunctionKind::PartialApply);
1753
+ emission->addDynamicFunctionContext (explosion);
1779
1754
}
1780
1755
1781
1756
// Pass a placeholder for thin function calls.
@@ -2120,16 +2095,18 @@ Optional<StackAddress> irgen::emitFunctionPartialApplication(
2120
2095
// We don't add non-constant function pointers to the explosion above,
2121
2096
// so we need to handle them specially now.
2122
2097
if (i == nonStaticFnIndex) {
2123
- llvm::Value *fnPtr;
2124
- if (auto &schema = IGF.getOptions ().PointerAuth .PartialApplyCapture ) {
2125
- auto schemaAuthInfo =
2126
- PointerAuthInfo::emit (IGF, schema, fieldAddr.getAddress (),
2127
- PointerAuthEntity::Special::PartialApplyCapture);
2098
+ llvm::Value *fnPtr = fn.getRawPointer ();
2099
+ if (auto &schema =
2100
+ origType->isAsync ()
2101
+ ? IGF.getOptions ().PointerAuth .AsyncPartialApplyCapture
2102
+ : IGF.getOptions ().PointerAuth .PartialApplyCapture ) {
2103
+ auto schemaAuthInfo = PointerAuthInfo::emit (
2104
+ IGF, schema, fieldAddr.getAddress (),
2105
+ PointerAuthEntity::Special::PartialApplyCapture);
2128
2106
fnPtr =
2129
2107
emitPointerAuthResign (IGF, fn, schemaAuthInfo).getRawPointer ();
2130
- } else {
2131
- fnPtr = fn.getRawPointer ();
2132
2108
}
2109
+
2133
2110
fnPtr = IGF.Builder .CreateBitCast (fnPtr, IGF.IGM .Int8PtrTy );
2134
2111
IGF.Builder .CreateStore (fnPtr, fieldAddr);
2135
2112
continue ;
0 commit comments