Skip to content

Commit 80d1f83

Browse files
committed
[Async CC] Add coroutine fields to context.
The following fields are now available when the function is a coroutine: - TaskContinuationFunction * __ptrauth(...) yieldToCaller? - TaskContinuationFunction * __ptrauth(...) resumeFromYield? - TaskContinuationFunction * __ptrauth(...) abortFromYield? - ExecutorRef calleeActorDuringYield? - YieldTypes yieldValues... These fields have yet to be filled in. The following field are now available when the function is NOT a coroutine (whereas previously they were always available): - ResultTypes directResults...
1 parent c22c0c5 commit 80d1f83

File tree

2 files changed

+95
-15
lines changed

2 files changed

+95
-15
lines changed

lib/IRGen/GenCall.cpp

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ AsyncContextLayout irgen::getAsyncContextLayout(
9797
SmallVector<const TypeInfo *, 4> typeInfos;
9898
SmallVector<SILType, 4> valTypes;
9999
SmallVector<AsyncContextLayout::ArgumentInfo, 4> paramInfos;
100+
bool isCoroutine = originalType->isCoroutine();
101+
SmallVector<SILYieldInfo, 4> yieldInfos;
100102
SmallVector<SILResultInfo, 4> indirectReturnInfos;
101103
SmallVector<SILResultInfo, 4> directReturnInfos;
102104

@@ -141,6 +143,11 @@ AsyncContextLayout irgen::getAsyncContextLayout(
141143
typeInfos.push_back(&ti);
142144
}
143145

146+
if (isCoroutine) {
147+
// SwiftPartialFunction * __ptrauth(...) yieldToCaller?;
148+
addTaskContinuationFunction();
149+
}
150+
144151
// SwiftError *errorResult;
145152
auto errorCanType = IGF.IGM.Context.getExceptionType();
146153
auto errorType = SILType::getPrimitiveObjectType(errorCanType);
@@ -160,15 +167,33 @@ AsyncContextLayout irgen::getAsyncContextLayout(
160167
indirectReturnInfos.push_back(indirectResult);
161168
}
162169

163-
// ResultTypes directResults...;
164-
auto directResults = fnConv.getDirectSILResults();
165-
for (auto result : directResults) {
166-
auto ty =
167-
fnConv.getSILType(result, IGF.IGM.getMaximalTypeExpansionContext());
168-
auto &ti = IGF.getTypeInfoForLowered(ty.getASTType());
169-
valTypes.push_back(ty);
170-
typeInfos.push_back(&ti);
171-
directReturnInfos.push_back(result);
170+
// union {
171+
if (isCoroutine) {
172+
// SwiftPartialFunction * __ptrauth(...) resumeFromYield?
173+
addTaskContinuationFunction();
174+
// SwiftPartialFunction * __ptrauth(...) abortFromYield?
175+
addTaskContinuationFunction();
176+
// SwiftActor * __ptrauth(...) calleeActorDuringYield?
177+
addExecutor();
178+
// YieldTypes yieldValues...
179+
for (auto yield : fnConv.getYields()) {
180+
auto ty =
181+
fnConv.getSILType(yield, IGF.IGM.getMaximalTypeExpansionContext());
182+
auto &ti = IGF.getTypeInfoForLowered(ty.getASTType());
183+
valTypes.push_back(ty);
184+
typeInfos.push_back(&ti);
185+
yieldInfos.push_back(yield);
186+
}
187+
} else {
188+
// ResultTypes directResults...;
189+
for (auto result : fnConv.getDirectSILResults()) {
190+
auto ty =
191+
fnConv.getSILType(result, IGF.IGM.getMaximalTypeExpansionContext());
192+
auto &ti = IGF.getTypeInfoForLowered(ty.getASTType());
193+
valTypes.push_back(ty);
194+
typeInfos.push_back(&ti);
195+
directReturnInfos.push_back(result);
196+
}
172197
}
173198

174199
// SelfType self?;
@@ -257,7 +282,8 @@ AsyncContextLayout irgen::getAsyncContextLayout(
257282
IGF.IGM, LayoutStrategy::Optimal, valTypes, typeInfos, IGF, originalType,
258283
substitutedType, substitutionMap, std::move(bindings),
259284
trailingWitnessInfo, errorType, canHaveValidError, paramInfos,
260-
indirectReturnInfos, directReturnInfos, localContextInfo);
285+
isCoroutine, yieldInfos, indirectReturnInfos, directReturnInfos,
286+
localContextInfo);
261287
}
262288

263289
AsyncContextLayout::AsyncContextLayout(
@@ -267,14 +293,16 @@ AsyncContextLayout::AsyncContextLayout(
267293
SubstitutionMap substitutionMap, NecessaryBindings &&bindings,
268294
Optional<TrailingWitnessInfo> trailingWitnessInfo, SILType errorType,
269295
bool canHaveValidError, ArrayRef<ArgumentInfo> argumentInfos,
296+
bool isCoroutine, ArrayRef<SILYieldInfo> yieldInfos,
270297
ArrayRef<SILResultInfo> indirectReturnInfos,
271298
ArrayRef<SILResultInfo> directReturnInfos,
272299
Optional<AsyncContextLayout::ArgumentInfo> localContextInfo)
273300
: StructLayout(IGM, /*decl=*/nullptr, LayoutKind::NonHeapObject, strategy,
274301
fieldTypeInfos, /*typeToFill*/ nullptr),
275302
IGF(IGF), originalType(originalType), substitutedType(substitutedType),
276303
substitutionMap(substitutionMap), errorType(errorType),
277-
canHaveValidError(canHaveValidError),
304+
canHaveValidError(canHaveValidError), isCoroutine(isCoroutine),
305+
yieldInfos(yieldInfos.begin(), yieldInfos.end()),
278306
directReturnInfos(directReturnInfos.begin(), directReturnInfos.end()),
279307
indirectReturnInfos(indirectReturnInfos.begin(),
280308
indirectReturnInfos.end()),
@@ -284,6 +312,11 @@ AsyncContextLayout::AsyncContextLayout(
284312
#ifndef NDEBUG
285313
assert(fieldTypeInfos.size() == fieldTypes.size() &&
286314
"type infos don't match types");
315+
if (isCoroutine) {
316+
assert(directReturnInfos.empty());
317+
} else {
318+
assert(yieldInfos.empty());
319+
}
287320
if (!bindings.empty()) {
288321
assert(fieldTypeInfos.size() >= 2 && "no field for bindings");
289322
auto fixedBindingsField =

lib/IRGen/GenCall.h

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ namespace irgen {
9797
ResumeParent = 1,
9898
ResumeParentExecutor = 2,
9999
Flags = 3,
100-
Error = 4,
100+
YieldToParent = 4,
101101
};
102102
enum class FixedCount : unsigned {
103103
Parent = 1,
@@ -111,6 +111,8 @@ namespace irgen {
111111
SubstitutionMap substitutionMap;
112112
SILType errorType;
113113
bool canHaveValidError;
114+
bool isCoroutine;
115+
SmallVector<SILYieldInfo, 4> yieldInfos;
114116
SmallVector<SILResultInfo, 4> directReturnInfos;
115117
SmallVector<SILResultInfo, 4> indirectReturnInfos;
116118
Optional<ArgumentInfo> localContextInfo;
@@ -126,20 +128,56 @@ namespace irgen {
126128
return (unsigned)FixedIndex::ResumeParentExecutor;
127129
}
128130
unsigned getFlagsIndex() { return (unsigned)FixedIndex::Flags; }
129-
unsigned getErrorIndex() { return (unsigned)FixedIndex::Error; }
131+
unsigned getYieldToParentIndex() {
132+
assert(isCoroutine);
133+
return (unsigned)FixedIndex::YieldToParent;
134+
}
135+
unsigned getErrorIndex() {
136+
return (isCoroutine ? getYieldToParentIndex() : getFlagsIndex()) + 1;
137+
}
130138
unsigned getFirstIndirectReturnIndex() {
131139
return getErrorIndex() + getErrorCount();
132140
}
133141
unsigned getIndexAfterIndirectReturns() {
134142
return getFirstIndirectReturnIndex() + getIndirectReturnCount();
135143
}
136144
unsigned getFirstDirectReturnIndex() {
145+
assert(!isCoroutine);
137146
return getIndexAfterIndirectReturns();
138147
}
139148
unsigned getIndexAfterDirectReturns() {
149+
assert(!isCoroutine);
140150
return getFirstDirectReturnIndex() + getDirectReturnCount();
141151
}
142-
unsigned getFirstArgumentIndex() { return getIndexAfterDirectReturns(); }
152+
unsigned getResumeFromYieldIndex() {
153+
assert(isCoroutine);
154+
return getIndexAfterIndirectReturns();
155+
}
156+
unsigned getAbortFromYieldIndex() {
157+
assert(isCoroutine);
158+
return getResumeFromYieldIndex() + 1;
159+
;
160+
}
161+
unsigned getCalleeExecutorDuringYieldIndex() {
162+
assert(isCoroutine);
163+
return getAbortFromYieldIndex() + 1;
164+
}
165+
unsigned getFirstYieldIndex() {
166+
assert(isCoroutine);
167+
return getCalleeExecutorDuringYieldIndex() + 1;
168+
}
169+
unsigned getIndexAfterYields() {
170+
assert(isCoroutine);
171+
return getFirstYieldIndex() + getYieldCount();
172+
}
173+
unsigned getIndexAfterUnion() {
174+
if (isCoroutine) {
175+
return getIndexAfterYields();
176+
} else {
177+
return getIndexAfterDirectReturns();
178+
}
179+
}
180+
unsigned getFirstArgumentIndex() { return getIndexAfterUnion(); }
143181
unsigned getIndexAfterArguments() {
144182
return getFirstArgumentIndex() + getArgumentCount();
145183
}
@@ -230,10 +268,18 @@ namespace irgen {
230268
return getElement(getSelfWitnessTableIndex());
231269
}
232270

233-
unsigned getDirectReturnCount() { return directReturnInfos.size(); }
271+
unsigned getDirectReturnCount() {
272+
assert(!isCoroutine);
273+
return directReturnInfos.size();
274+
}
234275
ElementLayout getDirectReturnLayout(unsigned index) {
276+
assert(!isCoroutine);
235277
return getElement(getFirstDirectReturnIndex() + index);
236278
}
279+
unsigned getYieldCount() {
280+
assert(isCoroutine);
281+
return yieldInfos.size();
282+
}
237283

238284
AsyncContextLayout(
239285
IRGenModule &IGM, LayoutStrategy strategy, ArrayRef<SILType> fieldTypes,
@@ -242,6 +288,7 @@ namespace irgen {
242288
SubstitutionMap substitutionMap, NecessaryBindings &&bindings,
243289
Optional<TrailingWitnessInfo> trailingWitnessInfo, SILType errorType,
244290
bool canHaveValidError, ArrayRef<ArgumentInfo> argumentInfos,
291+
bool isCoroutine, ArrayRef<SILYieldInfo> yieldInfos,
245292
ArrayRef<SILResultInfo> indirectReturnInfos,
246293
ArrayRef<SILResultInfo> directReturnInfos,
247294
Optional<ArgumentInfo> localContextInfo);

0 commit comments

Comments
 (0)