diff --git a/lib/IRGen/GenCall.cpp b/lib/IRGen/GenCall.cpp index ce0a7784b0f12..e83064f00cfbd 100644 --- a/lib/IRGen/GenCall.cpp +++ b/lib/IRGen/GenCall.cpp @@ -273,6 +273,27 @@ static llvm::Value *getAsyncTask(IRGenFunction &IGF) { return llvm::Constant::getNullValue(IGF.IGM.SwiftTaskPtrTy); } +llvm::Value *IRGenFunction::getAsyncTask() { + assert(isAsync()); + auto *value = CurFn->getArg((unsigned)AsyncFunctionArgumentIndex::Task); + assert(value->getType() == IGM.SwiftTaskPtrTy); + return value; +} + +llvm::Value *IRGenFunction::getAsyncExecutor() { + assert(isAsync()); + auto *value = CurFn->getArg((unsigned)AsyncFunctionArgumentIndex::Executor); + assert(value->getType() == IGM.SwiftExecutorPtrTy); + return value; +} + +llvm::Value *IRGenFunction::getAsyncContext() { + assert(isAsync()); + auto *value = CurFn->getArg((unsigned)AsyncFunctionArgumentIndex::Context); + assert(value->getType() == IGM.SwiftContextPtrTy); + return value; +} + llvm::Type *ExplosionSchema::getScalarResultType(IRGenModule &IGM) const { if (size() == 0) { return IGM.VoidTy; diff --git a/lib/IRGen/GenCall.h b/lib/IRGen/GenCall.h index 8f0b58da52721..5a7baea76eb4d 100644 --- a/lib/IRGen/GenCall.h +++ b/lib/IRGen/GenCall.h @@ -340,6 +340,11 @@ namespace irgen { CanSILFunctionType coroutineType, Explosion &yieldedValues); + enum class AsyncFunctionArgumentIndex : unsigned { + Task = 0, + Executor = 1, + Context = 2, + }; } // end namespace irgen } // end namespace swift diff --git a/lib/IRGen/IRGenFunction.h b/lib/IRGen/IRGenFunction.h index 4c3ece3df24a4..61f43c33993c4 100644 --- a/lib/IRGen/IRGenFunction.h +++ b/lib/IRGen/IRGenFunction.h @@ -83,7 +83,7 @@ class IRGenFunction { OptimizationMode Mode = OptimizationMode::NotSet, const SILDebugScope *DbgScope = nullptr, Optional DbgLoc = None); - ~IRGenFunction(); + virtual ~IRGenFunction(); void unimplemented(SourceLoc Loc, StringRef Message); @@ -127,7 +127,11 @@ class IRGenFunction { assert(handle != nullptr && "setting a null handle"); CoroutineHandle = handle; } - + + virtual llvm::Value *getAsyncTask(); + virtual llvm::Value *getAsyncExecutor(); + virtual llvm::Value *getAsyncContext(); + private: void emitPrologue(); void emitEpilogue(); diff --git a/lib/IRGen/IRGenSIL.cpp b/lib/IRGen/IRGenSIL.cpp index e115b77558d50..06127a14fd9f3 100644 --- a/lib/IRGen/IRGenSIL.cpp +++ b/lib/IRGen/IRGenSIL.cpp @@ -852,7 +852,43 @@ class IRGenSILFunction : } } } - + + llvm::Value *getAsyncTask() override { + // FIXME: (1) Remove this override, (2) mark the IRGenFunction::getAsyncTask + // declaration as non-virtual, and (3) mark IRGenFunction's + // destructor non-virtual once Task.runDetached is available. + // rdar://problem/70597390*/ + if (CurSILFn->getLoweredFunctionType()->getRepresentation() == + SILFunctionTypeRepresentation::CFunctionPointer) { + return llvm::Constant::getNullValue(IGM.SwiftTaskPtrTy); + } + return IRGenFunction::getAsyncTask(); + } + + llvm::Value *getAsyncExecutor() override { + // FIXME: (1) Remove this override, (2) mark the + // IRGenFunction::getAsyncExecutor declaration as non-virtual, and + // (3) mark IRGenFunction's destructor non-virtual once + // Task.runDetached is available. rdar://problem/70597390*/ + if (CurSILFn->getLoweredFunctionType()->getRepresentation() == + SILFunctionTypeRepresentation::CFunctionPointer) { + return llvm::Constant::getNullValue(IGM.SwiftExecutorPtrTy); + } + return IRGenFunction::getAsyncExecutor(); + } + + llvm::Value *getAsyncContext() override { + // FIXME: (1) Remove this override, (2) mark the + // IRGenFunction::getAsyncContext declaration as non-virtual, and + // (3) mark IRGenFunction's destructor non-virtual once + // Task.runDetached is available. rdar://problem/70597390*/ + if (CurSILFn->getLoweredFunctionType()->getRepresentation() == + SILFunctionTypeRepresentation::CFunctionPointer) { + return llvm::Constant::getNullValue(IGM.SwiftContextPtrTy); + } + return IRGenFunction::getAsyncContext(); + } + //===--------------------------------------------------------------------===// // SIL instruction lowering //===--------------------------------------------------------------------===// @@ -3179,7 +3215,7 @@ static void emitReturnInst(IRGenSILFunction &IGF, assert(!IGF.IndirectReturn.isValid() && "Formally direct results should stay direct results for async " "functions"); - llvm::Value *context = IGF.CurFn->getArg(2); + llvm::Value *context = IGF.getAsyncContext(); auto layout = getAsyncContextLayout(IGF); Address dataAddr = layout.emitCastTo(IGF, context);