2020#include " ClassMetadataVisitor.h"
2121#include " ConstantBuilder.h"
2222#include " Explosion.h"
23+ #include " GenCall.h"
2324#include " GenClass.h"
2425#include " GenDecl.h"
2526#include " GenHeap.h"
3132#include " MetadataLayout.h"
3233#include " ProtocolInfo.h"
3334#include " Signature.h"
35+ #include " swift/AST/GenericEnvironment.h"
3436#include " swift/IRGen/Linking.h"
3537#include " swift/SIL/SILDeclRef.h"
3638#include " llvm/IR/Function.h"
@@ -79,14 +81,32 @@ static FunctionPointer lookupMethod(IRGenFunction &IGF, SILDeclRef declRef) {
7981 // Load the metadata, or use the 'self' value if we have a static method.
8082 llvm::Value *self;
8183
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+ }
90110
91111 auto selfTy = funcTy->getSelfParameter ().getSILStorageType (
92112 IGF.IGM .getSILModule (), funcTy, IGF.IGM .getMaximalTypeExpansionContext ());
@@ -109,13 +129,15 @@ void IRGenModule::emitDispatchThunk(SILDeclRef declRef) {
109129 }
110130
111131 IRGenFunction IGF (*this , f);
132+ IGF.setAsync (declRef.getAbstractFunctionDecl ()->hasAsync ());
112133
113134 // Look up the method.
114135 auto fn = lookupMethod (IGF, declRef);
115136
116137 // Call the witness, forwarding all of the parameters.
117138 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 ());
119141
120142 // Return the result, if we have one.
121143 if (result->getType ()->isVoidTy ())
0 commit comments