20
20
#include " ClassMetadataVisitor.h"
21
21
#include " ConstantBuilder.h"
22
22
#include " Explosion.h"
23
+ #include " GenCall.h"
23
24
#include " GenClass.h"
24
25
#include " GenDecl.h"
25
26
#include " GenHeap.h"
31
32
#include " MetadataLayout.h"
32
33
#include " ProtocolInfo.h"
33
34
#include " Signature.h"
35
+ #include " swift/AST/GenericEnvironment.h"
34
36
#include " swift/IRGen/Linking.h"
35
37
#include " swift/SIL/SILDeclRef.h"
36
38
#include " llvm/IR/Function.h"
@@ -79,14 +81,32 @@ static FunctionPointer lookupMethod(IRGenFunction &IGF, SILDeclRef declRef) {
79
81
// Load the metadata, or use the 'self' value if we have a static method.
80
82
llvm::Value *self;
81
83
82
- // Non-throwing class methods always have the 'self' parameter at the end.
83
- // Throwing class methods have 'self' right before the error parameter.
84
- //
85
- // FIXME: Should find a better way of expressing this.
86
- if (funcTy->hasErrorResult ())
87
- self = (IGF.CurFn ->arg_end () - 2 );
88
- else
89
- self = (IGF.CurFn ->arg_end () - 1 );
84
+ if (funcTy->isAsync ()) {
85
+ auto originalType = funcTy;
86
+ auto forwardingSubstitutionMap =
87
+ decl->getGenericEnvironment ()
88
+ ? decl->getGenericEnvironment ()->getForwardingSubstitutionMap ()
89
+ : SubstitutionMap ();
90
+ auto substitutedType = originalType->substGenericArgs (
91
+ IGF.IGM .getSILModule (), forwardingSubstitutionMap,
92
+ IGF.IGM .getMaximalTypeExpansionContext ());
93
+ auto layout = getAsyncContextLayout (IGF.IGM , originalType, substitutedType,
94
+ forwardingSubstitutionMap);
95
+ assert (layout.hasLocalContext ());
96
+ auto context = layout.emitCastTo (IGF, IGF.getAsyncContext ());
97
+ auto localContextAddr =
98
+ layout.getLocalContextLayout ().project (IGF, context, llvm::None);
99
+ self = IGF.Builder .CreateLoad (localContextAddr);
100
+ } else {
101
+ // Non-throwing class methods always have the 'self' parameter at the end.
102
+ // Throwing class methods have 'self' right before the error parameter.
103
+ //
104
+ // FIXME: Should find a better way of expressing this.
105
+ if (funcTy->hasErrorResult ())
106
+ self = (IGF.CurFn ->arg_end () - 2 );
107
+ else
108
+ self = (IGF.CurFn ->arg_end () - 1 );
109
+ }
90
110
91
111
auto selfTy = funcTy->getSelfParameter ().getSILStorageType (
92
112
IGF.IGM .getSILModule (), funcTy, IGF.IGM .getMaximalTypeExpansionContext ());
@@ -109,13 +129,15 @@ void IRGenModule::emitDispatchThunk(SILDeclRef declRef) {
109
129
}
110
130
111
131
IRGenFunction IGF (*this , f);
132
+ IGF.setAsync (declRef.getAbstractFunctionDecl ()->hasAsync ());
112
133
113
134
// Look up the method.
114
135
auto fn = lookupMethod (IGF, declRef);
115
136
116
137
// Call the witness, forwarding all of the parameters.
117
138
auto params = IGF.collectParameters ();
118
- auto result = IGF.Builder .CreateCall (fn, params.claimAll ());
139
+ auto result =
140
+ IGF.Builder .CreateCall (fn.getAsFunction (IGF), params.claimAll ());
119
141
120
142
// Return the result, if we have one.
121
143
if (result->getType ()->isVoidTy ())
0 commit comments