@@ -255,19 +255,23 @@ SILGenModule::getOrCreateForeignAsyncCompletionHandlerImplFunction(
255
255
auto continuationVal = SGF.B .createLoad (loc, continuationAddr,
256
256
LoadOwnershipQualifier::Trivial);
257
257
auto continuation = ManagedValue::forUnmanaged (continuationVal);
258
-
258
+
259
259
// Check for an error if the convention includes one.
260
- auto errorIndex = convention.completionHandlerErrorParamIndex ();
261
- auto flagIndex = convention.completionHandlerFlagParamIndex ();
260
+ // Increment the error and flag indices if present. They do not account
261
+ // for the fact that they are preceded by the block_storage arguments.
262
+ auto errorIndex = convention.completionHandlerErrorParamIndex ().map (
263
+ [](auto original) { return original + 1 ; });
264
+ auto flagIndex = convention.completionHandlerFlagParamIndex ().map (
265
+ [](auto original) { return original + 1 ; });
262
266
263
267
FuncDecl *resumeIntrinsic;
264
268
265
269
SILBasicBlock *returnBB = nullptr ;
266
270
if (errorIndex) {
267
271
resumeIntrinsic = getResumeUnsafeThrowingContinuation ();
268
272
auto errorIntrinsic = getResumeUnsafeThrowingContinuationWithError ();
269
-
270
- auto errorArgument = params[*errorIndex + 1 ];
273
+
274
+ auto errorArgument = params[*errorIndex];
271
275
auto someErrorBB = SGF.createBasicBlock (FunctionSection::Postmatter);
272
276
auto noneErrorBB = SGF.createBasicBlock ();
273
277
returnBB = SGF.createBasicBlockAfter (noneErrorBB);
@@ -276,8 +280,8 @@ SILGenModule::getOrCreateForeignAsyncCompletionHandlerImplFunction(
276
280
// Check whether there's an error, based on the presence of a flag
277
281
// parameter. If there is a flag parameter, test it against zero.
278
282
if (flagIndex) {
279
- auto flagArgument = params[*flagIndex + 1 ];
280
-
283
+ auto flagArgument = params[*flagIndex];
284
+
281
285
// The flag must be an integer type. Get the underlying builtin
282
286
// integer field from it.
283
287
auto builtinFlagArg = SGF.emitUnwrapIntegerResult (loc, flagArgument.getValue ());
@@ -372,31 +376,31 @@ SILGenModule::getOrCreateForeignAsyncCompletionHandlerImplFunction(
372
376
bridgedArg.forwardInto (SGF, loc, destBuf);
373
377
};
374
378
379
+ // Collect the indices which correspond to the values to be returned.
380
+ SmallVector<unsigned long , 4 > paramIndices;
381
+ for (auto index : indices (params)) {
382
+ // The first index is the block_storage parameter.
383
+ if (index == 0 )
384
+ continue ;
385
+ if (errorIndex && index == *errorIndex)
386
+ continue ;
387
+ if (flagIndex && index == *flagIndex)
388
+ continue ;
389
+ paramIndices.push_back (index);
390
+ }
375
391
if (auto resumeTuple = dyn_cast<TupleType>(resumeType)) {
392
+ assert (paramIndices.size () == resumeTuple->getNumElements ());
376
393
assert (params.size () == resumeTuple->getNumElements ()
377
394
+ 1 + (bool )errorIndex + (bool )flagIndex);
378
395
for (unsigned i : indices (resumeTuple.getElementTypes ())) {
379
- unsigned paramI = i;
380
- if (errorIndex && paramI >= *errorIndex) {
381
- ++paramI;
382
- }
383
- if (flagIndex && paramI >= *flagIndex) {
384
- ++paramI;
385
- }
386
396
auto resumeEltBuf = SGF.B .createTupleElementAddr (loc,
387
397
resumeArgBuf, i);
388
- prepareArgument (resumeEltBuf, params[paramI + 1 ]);
398
+ prepareArgument (resumeEltBuf, params[paramIndices[i] ]);
389
399
}
390
400
} else {
401
+ assert (paramIndices.size () == 1 );
391
402
assert (params.size () == 2 + (bool )errorIndex + (bool )flagIndex);
392
- unsigned paramI = 0 ;
393
- if (errorIndex && paramI >= *errorIndex) {
394
- ++paramI;
395
- }
396
- if (flagIndex && paramI >= *flagIndex) {
397
- ++paramI;
398
- }
399
- prepareArgument (resumeArgBuf, params[paramI + 1 ]);
403
+ prepareArgument (resumeArgBuf, params[paramIndices[0 ]]);
400
404
}
401
405
402
406
// Resume the continuation with the composed bridged result.
0 commit comments