Skip to content

[Async CC] Add remaining fields to context. #34471

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 65 additions & 19 deletions lib/IRGen/GenCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,27 @@ AsyncContextLayout irgen::getAsyncContextLayout(
SmallVector<const TypeInfo *, 4> typeInfos;
SmallVector<SILType, 4> valTypes;
SmallVector<AsyncContextLayout::ArgumentInfo, 4> paramInfos;
bool isCoroutine = originalType->isCoroutine();
SmallVector<SILYieldInfo, 4> yieldInfos;
SmallVector<SILResultInfo, 4> indirectReturnInfos;
SmallVector<SILResultInfo, 4> directReturnInfos;

auto parameters = substitutedType->getParameters();
SILFunctionConventions fnConv(substitutedType, IGF.getSILModule());

auto addTaskContinuationFunction = [&]() {
auto ty = SILType();
auto &ti = IGF.IGM.getTaskContinuationFunctionPtrTypeInfo();
valTypes.push_back(ty);
typeInfos.push_back(&ti);
};
auto addExecutor = [&]() {
auto ty = SILType();
auto &ti = IGF.IGM.getSwiftExecutorPtrTypeInfo();
valTypes.push_back(ty);
typeInfos.push_back(&ti);
};

// AsyncContext * __ptrauth_swift_async_context_parent Parent;
{
auto ty = SILType();
Expand All @@ -113,21 +128,26 @@ AsyncContextLayout irgen::getAsyncContextLayout(

// TaskContinuationFunction * __ptrauth_swift_async_context_resume
// ResumeParent;
{
auto ty = SILType();
auto &ti = IGF.IGM.getTaskContinuationFunctionPtrTypeInfo();
valTypes.push_back(ty);
typeInfos.push_back(&ti);
}
addTaskContinuationFunction();

// ExecutorRef ResumeParentExecutor;
addExecutor();

// AsyncContextFlags Flags;
{
auto ty = SILType();
auto &ti = IGF.IGM.getSwiftExecutorPtrTypeInfo();
auto ty = SILType::getPrimitiveObjectType(
BuiltinIntegerType::get(32, IGF.IGM.IRGen.SIL.getASTContext())
->getCanonicalType());
const auto &ti = IGF.IGM.getTypeInfo(ty);
valTypes.push_back(ty);
typeInfos.push_back(&ti);
}

if (isCoroutine) {
// SwiftPartialFunction * __ptrauth(...) yieldToCaller?;
addTaskContinuationFunction();
}

// SwiftError *errorResult;
auto errorCanType = IGF.IGM.Context.getExceptionType();
auto errorType = SILType::getPrimitiveObjectType(errorCanType);
Expand All @@ -147,15 +167,33 @@ AsyncContextLayout irgen::getAsyncContextLayout(
indirectReturnInfos.push_back(indirectResult);
}

// ResultTypes directResults...;
auto directResults = fnConv.getDirectSILResults();
for (auto result : directResults) {
auto ty =
fnConv.getSILType(result, IGF.IGM.getMaximalTypeExpansionContext());
auto &ti = IGF.getTypeInfoForLowered(ty.getASTType());
valTypes.push_back(ty);
typeInfos.push_back(&ti);
directReturnInfos.push_back(result);
// union {
if (isCoroutine) {
// SwiftPartialFunction * __ptrauth(...) resumeFromYield?
addTaskContinuationFunction();
// SwiftPartialFunction * __ptrauth(...) abortFromYield?
addTaskContinuationFunction();
// SwiftActor * __ptrauth(...) calleeActorDuringYield?
addExecutor();
// YieldTypes yieldValues...
for (auto yield : fnConv.getYields()) {
auto ty =
fnConv.getSILType(yield, IGF.IGM.getMaximalTypeExpansionContext());
auto &ti = IGF.getTypeInfoForLowered(ty.getASTType());
valTypes.push_back(ty);
typeInfos.push_back(&ti);
yieldInfos.push_back(yield);
}
} else {
// ResultTypes directResults...;
for (auto result : fnConv.getDirectSILResults()) {
auto ty =
fnConv.getSILType(result, IGF.IGM.getMaximalTypeExpansionContext());
auto &ti = IGF.getTypeInfoForLowered(ty.getASTType());
valTypes.push_back(ty);
typeInfos.push_back(&ti);
directReturnInfos.push_back(result);
}
}

// SelfType self?;
Expand Down Expand Up @@ -244,7 +282,8 @@ AsyncContextLayout irgen::getAsyncContextLayout(
IGF.IGM, LayoutStrategy::Optimal, valTypes, typeInfos, IGF, originalType,
substitutedType, substitutionMap, std::move(bindings),
trailingWitnessInfo, errorType, canHaveValidError, paramInfos,
indirectReturnInfos, directReturnInfos, localContextInfo);
isCoroutine, yieldInfos, indirectReturnInfos, directReturnInfos,
localContextInfo);
}

AsyncContextLayout::AsyncContextLayout(
Expand All @@ -254,14 +293,16 @@ AsyncContextLayout::AsyncContextLayout(
SubstitutionMap substitutionMap, NecessaryBindings &&bindings,
Optional<TrailingWitnessInfo> trailingWitnessInfo, SILType errorType,
bool canHaveValidError, ArrayRef<ArgumentInfo> argumentInfos,
bool isCoroutine, ArrayRef<SILYieldInfo> yieldInfos,
ArrayRef<SILResultInfo> indirectReturnInfos,
ArrayRef<SILResultInfo> directReturnInfos,
Optional<AsyncContextLayout::ArgumentInfo> localContextInfo)
: StructLayout(IGM, /*decl=*/nullptr, LayoutKind::NonHeapObject, strategy,
fieldTypeInfos, /*typeToFill*/ nullptr),
IGF(IGF), originalType(originalType), substitutedType(substitutedType),
substitutionMap(substitutionMap), errorType(errorType),
canHaveValidError(canHaveValidError),
canHaveValidError(canHaveValidError), isCoroutine(isCoroutine),
yieldInfos(yieldInfos.begin(), yieldInfos.end()),
directReturnInfos(directReturnInfos.begin(), directReturnInfos.end()),
indirectReturnInfos(indirectReturnInfos.begin(),
indirectReturnInfos.end()),
Expand All @@ -271,6 +312,11 @@ AsyncContextLayout::AsyncContextLayout(
#ifndef NDEBUG
assert(fieldTypeInfos.size() == fieldTypes.size() &&
"type infos don't match types");
if (isCoroutine) {
assert(directReturnInfos.empty());
} else {
assert(yieldInfos.empty());
}
if (!bindings.empty()) {
assert(fieldTypeInfos.size() >= 2 && "no field for bindings");
auto fixedBindingsField =
Expand Down
60 changes: 55 additions & 5 deletions lib/IRGen/GenCall.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ namespace irgen {
Parent = 0,
ResumeParent = 1,
ResumeParentExecutor = 2,
Error = 3,
Flags = 3,
YieldToParent = 4,
};
enum class FixedCount : unsigned {
Parent = 1,
Expand All @@ -110,6 +111,8 @@ namespace irgen {
SubstitutionMap substitutionMap;
SILType errorType;
bool canHaveValidError;
bool isCoroutine;
SmallVector<SILYieldInfo, 4> yieldInfos;
SmallVector<SILResultInfo, 4> directReturnInfos;
SmallVector<SILResultInfo, 4> indirectReturnInfos;
Optional<ArgumentInfo> localContextInfo;
Expand All @@ -124,20 +127,57 @@ namespace irgen {
unsigned getResumeParentExecutorIndex() {
return (unsigned)FixedIndex::ResumeParentExecutor;
}
unsigned getErrorIndex() { return (unsigned)FixedIndex::Error; }
unsigned getFlagsIndex() { return (unsigned)FixedIndex::Flags; }
unsigned getYieldToParentIndex() {
assert(isCoroutine);
return (unsigned)FixedIndex::YieldToParent;
}
unsigned getErrorIndex() {
return (isCoroutine ? getYieldToParentIndex() : getFlagsIndex()) + 1;
}
unsigned getFirstIndirectReturnIndex() {
return getErrorIndex() + getErrorCount();
}
unsigned getIndexAfterIndirectReturns() {
return getFirstIndirectReturnIndex() + getIndirectReturnCount();
}
unsigned getFirstDirectReturnIndex() {
assert(!isCoroutine);
return getIndexAfterIndirectReturns();
}
unsigned getIndexAfterDirectReturns() {
assert(!isCoroutine);
return getFirstDirectReturnIndex() + getDirectReturnCount();
}
unsigned getFirstArgumentIndex() { return getIndexAfterDirectReturns(); }
unsigned getResumeFromYieldIndex() {
assert(isCoroutine);
return getIndexAfterIndirectReturns();
}
unsigned getAbortFromYieldIndex() {
assert(isCoroutine);
return getResumeFromYieldIndex() + 1;
;
}
unsigned getCalleeExecutorDuringYieldIndex() {
assert(isCoroutine);
return getAbortFromYieldIndex() + 1;
}
unsigned getFirstYieldIndex() {
assert(isCoroutine);
return getCalleeExecutorDuringYieldIndex() + 1;
}
unsigned getIndexAfterYields() {
assert(isCoroutine);
return getFirstYieldIndex() + getYieldCount();
}
unsigned getIndexAfterUnion() {
if (isCoroutine) {
return getIndexAfterYields();
} else {
return getIndexAfterDirectReturns();
}
}
unsigned getFirstArgumentIndex() { return getIndexAfterUnion(); }
unsigned getIndexAfterArguments() {
return getFirstArgumentIndex() + getArgumentCount();
}
Expand Down Expand Up @@ -176,6 +216,7 @@ namespace irgen {
ElementLayout getResumeParentExecutorLayout() {
return getElement(getResumeParentExecutorIndex());
}
ElementLayout getFlagsLayout() { return getElement(getFlagsIndex()); }
bool canHaveError() { return canHaveValidError; }
ElementLayout getErrorLayout() { return getElement(getErrorIndex()); }
unsigned getErrorCount() { return (unsigned)FixedCount::Error; }
Expand Down Expand Up @@ -227,10 +268,18 @@ namespace irgen {
return getElement(getSelfWitnessTableIndex());
}

unsigned getDirectReturnCount() { return directReturnInfos.size(); }
unsigned getDirectReturnCount() {
assert(!isCoroutine);
return directReturnInfos.size();
}
ElementLayout getDirectReturnLayout(unsigned index) {
assert(!isCoroutine);
return getElement(getFirstDirectReturnIndex() + index);
}
unsigned getYieldCount() {
assert(isCoroutine);
return yieldInfos.size();
}

AsyncContextLayout(
IRGenModule &IGM, LayoutStrategy strategy, ArrayRef<SILType> fieldTypes,
Expand All @@ -239,8 +288,9 @@ namespace irgen {
SubstitutionMap substitutionMap, NecessaryBindings &&bindings,
Optional<TrailingWitnessInfo> trailingWitnessInfo, SILType errorType,
bool canHaveValidError, ArrayRef<ArgumentInfo> argumentInfos,
ArrayRef<SILResultInfo> directReturnInfos,
bool isCoroutine, ArrayRef<SILYieldInfo> yieldInfos,
ArrayRef<SILResultInfo> indirectReturnInfos,
ArrayRef<SILResultInfo> directReturnInfos,
Optional<ArgumentInfo> localContextInfo);
};

Expand Down