@@ -451,6 +451,33 @@ class TupleInitializationResultPlan final : public ResultPlan {
451
451
}
452
452
};
453
453
454
+ class ForeignAsyncInitializationPlan final : public ResultPlan {
455
+ SILGenFunction &SGF;
456
+ SILLocation loc;
457
+ public:
458
+ ForeignAsyncInitializationPlan (SILGenFunction &SGF, SILLocation loc)
459
+ : SGF(SGF), loc(loc) {
460
+ }
461
+
462
+ void
463
+ gatherIndirectResultAddrs (SILGenFunction &SGF, SILLocation loc,
464
+ SmallVectorImpl<SILValue> &outList) const override {
465
+ // TODO: Move values from the continuation result buffer to the individual
466
+ // out argument buffers, unless we were able to emit the resume buffer
467
+ // in-place.
468
+ }
469
+
470
+ RValue finish (SILGenFunction &SGF, SILLocation loc, CanType substType,
471
+ ArrayRef<ManagedValue> &directResults) override {
472
+ // There should be no direct results from the call.
473
+ assert (directResults.empty ());
474
+
475
+ // TODO: Get the actual result values from the awaited continuation.
476
+ // For now, produce an undef RValue.
477
+ return SGF.emitUndefRValue (loc, substType);
478
+ }
479
+ };
480
+
454
481
class ForeignErrorInitializationPlan final : public ResultPlan {
455
482
SILLocation loc;
456
483
LValue lvalue;
@@ -467,7 +494,7 @@ class ForeignErrorInitializationPlan final : public ResultPlan {
467
494
ResultPlanPtr &&subPlan)
468
495
: loc(loc), subPlan(std::move(subPlan)) {
469
496
unsigned errorParamIndex =
470
- calleeTypeInfo.foreignError ->getErrorParameterIndex ();
497
+ calleeTypeInfo.foreign . error ->getErrorParameterIndex ();
471
498
auto substFnType = calleeTypeInfo.substFnType ;
472
499
SILParameterInfo errorParameter =
473
500
substFnType->getParameters ()[errorParamIndex];
@@ -543,51 +570,56 @@ class ForeignErrorInitializationPlan final : public ResultPlan {
543
570
// / If the initialization is non-null, the result plan will emit into it.
544
571
ResultPlanPtr ResultPlanBuilder::buildTopLevelResult (Initialization *init,
545
572
SILLocation loc) {
546
- // First check if we do not have a foreign error. If we don't, just call
547
- // build.
548
- auto foreignError = calleeTypeInfo.foreignError ;
549
- if (!foreignError) {
573
+ // First check if we have a foreign error and/or async convention.
574
+ if (auto foreignAsync = calleeTypeInfo.foreign .async ) {
575
+ // Create a result plan that gets the result schema from the completion
576
+ // handler callback's arguments.
577
+ // completion handler.
578
+ return ResultPlanPtr (new ForeignAsyncInitializationPlan (SGF, loc));
579
+
580
+ } else if (auto foreignError = calleeTypeInfo.foreign .error ) {
581
+ // Handle the foreign error first.
582
+ //
583
+ // The plan needs to be built using the formal result type after foreign-error
584
+ // adjustment.
585
+ switch (foreignError->getKind ()) {
586
+ // These conventions make the formal result type ().
587
+ case ForeignErrorConvention::ZeroResult:
588
+ case ForeignErrorConvention::NonZeroResult:
589
+ assert (calleeTypeInfo.substResultType ->isVoid ());
590
+ allResults.clear ();
591
+ break ;
592
+
593
+ // These conventions leave the formal result alone.
594
+ case ForeignErrorConvention::ZeroPreservedResult:
595
+ case ForeignErrorConvention::NonNilError:
596
+ break ;
597
+
598
+ // This convention changes the formal result to the optional object type; we
599
+ // need to make our own make SILResultInfo array.
600
+ case ForeignErrorConvention::NilResult: {
601
+ assert (allResults.size () == 1 );
602
+ auto substFnTy = calleeTypeInfo.substFnType ;
603
+ CanType objectType = allResults[0 ]
604
+ .getReturnValueType (SGF.SGM .M , substFnTy,
605
+ SGF.getTypeExpansionContext ())
606
+ .getOptionalObjectType ();
607
+ SILResultInfo optResult = allResults[0 ].getWithInterfaceType (objectType);
608
+ allResults.clear ();
609
+ allResults.push_back (optResult);
610
+ break ;
611
+ }
612
+ }
613
+
614
+ ResultPlanPtr subPlan = build (init, calleeTypeInfo.origResultType .getValue (),
615
+ calleeTypeInfo.substResultType );
616
+ return ResultPlanPtr (new ForeignErrorInitializationPlan (
617
+ SGF, loc, calleeTypeInfo, std::move (subPlan)));
618
+ } else {
619
+ // Otherwise, we can just call build.
550
620
return build (init, calleeTypeInfo.origResultType .getValue (),
551
621
calleeTypeInfo.substResultType );
552
622
}
553
-
554
- // Otherwise, handle the foreign error first.
555
- //
556
- // The plan needs to be built using the formal result type after foreign-error
557
- // adjustment.
558
- switch (foreignError->getKind ()) {
559
- // These conventions make the formal result type ().
560
- case ForeignErrorConvention::ZeroResult:
561
- case ForeignErrorConvention::NonZeroResult:
562
- assert (calleeTypeInfo.substResultType ->isVoid ());
563
- allResults.clear ();
564
- break ;
565
-
566
- // These conventions leave the formal result alone.
567
- case ForeignErrorConvention::ZeroPreservedResult:
568
- case ForeignErrorConvention::NonNilError:
569
- break ;
570
-
571
- // This convention changes the formal result to the optional object type; we
572
- // need to make our own make SILResultInfo array.
573
- case ForeignErrorConvention::NilResult: {
574
- assert (allResults.size () == 1 );
575
- auto substFnTy = calleeTypeInfo.substFnType ;
576
- CanType objectType = allResults[0 ]
577
- .getReturnValueType (SGF.SGM .M , substFnTy,
578
- SGF.getTypeExpansionContext ())
579
- .getOptionalObjectType ();
580
- SILResultInfo optResult = allResults[0 ].getWithInterfaceType (objectType);
581
- allResults.clear ();
582
- allResults.push_back (optResult);
583
- break ;
584
- }
585
- }
586
-
587
- ResultPlanPtr subPlan = build (init, calleeTypeInfo.origResultType .getValue (),
588
- calleeTypeInfo.substResultType );
589
- return ResultPlanPtr (new ForeignErrorInitializationPlan (
590
- SGF, loc, calleeTypeInfo, std::move (subPlan)));
591
623
}
592
624
593
625
// / Build a result plan for the results of an apply.
0 commit comments