@@ -97,12 +97,27 @@ AsyncContextLayout irgen::getAsyncContextLayout(
97
97
SmallVector<const TypeInfo *, 4 > typeInfos;
98
98
SmallVector<SILType, 4 > valTypes;
99
99
SmallVector<AsyncContextLayout::ArgumentInfo, 4 > paramInfos;
100
+ bool isCoroutine = originalType->isCoroutine ();
101
+ SmallVector<SILYieldInfo, 4 > yieldInfos;
100
102
SmallVector<SILResultInfo, 4 > indirectReturnInfos;
101
103
SmallVector<SILResultInfo, 4 > directReturnInfos;
102
104
103
105
auto parameters = substitutedType->getParameters ();
104
106
SILFunctionConventions fnConv (substitutedType, IGF.getSILModule ());
105
107
108
+ auto addTaskContinuationFunction = [&]() {
109
+ auto ty = SILType ();
110
+ auto &ti = IGF.IGM .getTaskContinuationFunctionPtrTypeInfo ();
111
+ valTypes.push_back (ty);
112
+ typeInfos.push_back (&ti);
113
+ };
114
+ auto addExecutor = [&]() {
115
+ auto ty = SILType ();
116
+ auto &ti = IGF.IGM .getSwiftExecutorPtrTypeInfo ();
117
+ valTypes.push_back (ty);
118
+ typeInfos.push_back (&ti);
119
+ };
120
+
106
121
// AsyncContext * __ptrauth_swift_async_context_parent Parent;
107
122
{
108
123
auto ty = SILType ();
@@ -113,21 +128,26 @@ AsyncContextLayout irgen::getAsyncContextLayout(
113
128
114
129
// TaskContinuationFunction * __ptrauth_swift_async_context_resume
115
130
// ResumeParent;
116
- {
117
- auto ty = SILType ();
118
- auto &ti = IGF.IGM .getTaskContinuationFunctionPtrTypeInfo ();
119
- valTypes.push_back (ty);
120
- typeInfos.push_back (&ti);
121
- }
131
+ addTaskContinuationFunction ();
122
132
123
133
// ExecutorRef ResumeParentExecutor;
134
+ addExecutor ();
135
+
136
+ // AsyncContextFlags Flags;
124
137
{
125
- auto ty = SILType ();
126
- auto &ti = IGF.IGM .getSwiftExecutorPtrTypeInfo ();
138
+ auto ty = SILType::getPrimitiveObjectType (
139
+ BuiltinIntegerType::get (32 , IGF.IGM .IRGen .SIL .getASTContext ())
140
+ ->getCanonicalType ());
141
+ const auto &ti = IGF.IGM .getTypeInfo (ty);
127
142
valTypes.push_back (ty);
128
143
typeInfos.push_back (&ti);
129
144
}
130
145
146
+ if (isCoroutine) {
147
+ // SwiftPartialFunction * __ptrauth(...) yieldToCaller?;
148
+ addTaskContinuationFunction ();
149
+ }
150
+
131
151
// SwiftError *errorResult;
132
152
auto errorCanType = IGF.IGM .Context .getExceptionType ();
133
153
auto errorType = SILType::getPrimitiveObjectType (errorCanType);
@@ -147,15 +167,33 @@ AsyncContextLayout irgen::getAsyncContextLayout(
147
167
indirectReturnInfos.push_back (indirectResult);
148
168
}
149
169
150
- // ResultTypes directResults...;
151
- auto directResults = fnConv.getDirectSILResults ();
152
- for (auto result : directResults) {
153
- auto ty =
154
- fnConv.getSILType (result, IGF.IGM .getMaximalTypeExpansionContext ());
155
- auto &ti = IGF.getTypeInfoForLowered (ty.getASTType ());
156
- valTypes.push_back (ty);
157
- typeInfos.push_back (&ti);
158
- 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
+ }
159
197
}
160
198
161
199
// SelfType self?;
@@ -244,7 +282,8 @@ AsyncContextLayout irgen::getAsyncContextLayout(
244
282
IGF.IGM , LayoutStrategy::Optimal, valTypes, typeInfos, IGF, originalType,
245
283
substitutedType, substitutionMap, std::move (bindings),
246
284
trailingWitnessInfo, errorType, canHaveValidError, paramInfos,
247
- indirectReturnInfos, directReturnInfos, localContextInfo);
285
+ isCoroutine, yieldInfos, indirectReturnInfos, directReturnInfos,
286
+ localContextInfo);
248
287
}
249
288
250
289
AsyncContextLayout::AsyncContextLayout (
@@ -254,14 +293,16 @@ AsyncContextLayout::AsyncContextLayout(
254
293
SubstitutionMap substitutionMap, NecessaryBindings &&bindings,
255
294
Optional<TrailingWitnessInfo> trailingWitnessInfo, SILType errorType,
256
295
bool canHaveValidError, ArrayRef<ArgumentInfo> argumentInfos,
296
+ bool isCoroutine, ArrayRef<SILYieldInfo> yieldInfos,
257
297
ArrayRef<SILResultInfo> indirectReturnInfos,
258
298
ArrayRef<SILResultInfo> directReturnInfos,
259
299
Optional<AsyncContextLayout::ArgumentInfo> localContextInfo)
260
300
: StructLayout(IGM, /* decl=*/ nullptr , LayoutKind::NonHeapObject, strategy,
261
301
fieldTypeInfos, /* typeToFill*/ nullptr ),
262
302
IGF(IGF), originalType(originalType), substitutedType(substitutedType),
263
303
substitutionMap(substitutionMap), errorType(errorType),
264
- canHaveValidError(canHaveValidError),
304
+ canHaveValidError(canHaveValidError), isCoroutine(isCoroutine),
305
+ yieldInfos(yieldInfos.begin(), yieldInfos.end()),
265
306
directReturnInfos(directReturnInfos.begin(), directReturnInfos.end()),
266
307
indirectReturnInfos(indirectReturnInfos.begin(),
267
308
indirectReturnInfos.end()),
@@ -271,6 +312,11 @@ AsyncContextLayout::AsyncContextLayout(
271
312
#ifndef NDEBUG
272
313
assert (fieldTypeInfos.size () == fieldTypes.size () &&
273
314
" type infos don't match types" );
315
+ if (isCoroutine) {
316
+ assert (directReturnInfos.empty ());
317
+ } else {
318
+ assert (yieldInfos.empty ());
319
+ }
274
320
if (!bindings.empty ()) {
275
321
assert (fieldTypeInfos.size () >= 2 && " no field for bindings" );
276
322
auto fixedBindingsField =
0 commit comments