@@ -4430,27 +4430,6 @@ class FixLifetimeDestroyCleanup : public Cleanup {
44304430#endif
44314431 }
44324432};
4433-
4434- class EmitBreadcrumbCleanup : public Cleanup {
4435- ExecutorBreadcrumb breadcrumb;
4436-
4437- public:
4438- EmitBreadcrumbCleanup (ExecutorBreadcrumb &&breadcrumb)
4439- : breadcrumb(std::move(breadcrumb)) {}
4440-
4441- void emit (SILGenFunction &SGF, CleanupLocation l,
4442- ForUnwind_t forUnwind) override {
4443- breadcrumb.emit (SGF, l);
4444- }
4445-
4446- void dump (SILGenFunction &SGF) const override {
4447- #ifndef NDEBUG
4448- llvm::errs () << " EmitBreadcrumbCleanup "
4449- << " State:" << getState ()
4450- << " NeedsEmit:" << breadcrumb.needsEmit ();
4451- #endif
4452- }
4453- };
44544433} // end anonymous namespace
44554434
44564435// ===----------------------------------------------------------------------===//
@@ -4610,7 +4589,7 @@ RValue SILGenFunction::emitApply(
46104589 // generates `await_async_continuation`.
46114590 // Lifetime is extended by creating unmanaged copies here and by pushing the
46124591 // cleanups required just before the result plan is generated.
4613- SmallVector<SILValue , 8 > unmanagedCopies;
4592+ SmallVector<ManagedValue , 8 > unmanagedCopies;
46144593 if (calleeTypeInfo.foreign .async ) {
46154594 for (auto arg : args) {
46164595 if (arg.hasCleanup ()) {
@@ -4697,23 +4676,32 @@ RValue SILGenFunction::emitApply(
46974676 *foreignError, calleeTypeInfo.foreign .async );
46984677 }
46994678
4700- // For objc async calls, push cleanups to be used on
4701- // both result and throw paths prior to finishing the result plan.
4702- if (calleeTypeInfo.foreign .async ) {
4703- for (auto unmanagedCopy : unmanagedCopies) {
4704- Cleanups.pushCleanup <FixLifetimeDestroyCleanup>(unmanagedCopy);
4705- }
4706- // save breadcrumb as a clean-up so it is emitted in result / throw cases.
4707- Cleanups.pushCleanup <EmitBreadcrumbCleanup>(std::move (breadcrumb));
4708- } else {
4709- assert (unmanagedCopies.empty ());
4679+ // For objc async calls, push cleanup to be used on throw paths in the result
4680+ // planner.
4681+ for (unsigned i : indices (unmanagedCopies)) {
4682+ SILValue value = unmanagedCopies[i].getValue ();
4683+ Cleanups.pushCleanup <FixLifetimeDestroyCleanup>(value);
4684+ unmanagedCopies[i] = ManagedValue (value, Cleanups.getTopCleanup ());
47104685 }
47114686
47124687 auto directResultsArray = makeArrayRef (directResults);
47134688 RValue result = resultPlan->finish (*this , loc, substResultType,
47144689 directResultsArray, bridgedForeignError);
47154690 assert (directResultsArray.empty () && " didn't claim all direct results" );
47164691
4692+ // For objc async calls, generate cleanup on the resume path here and forward
4693+ // the previously pushed cleanups.
4694+ if (calleeTypeInfo.foreign .async ) {
4695+ for (auto unmanagedCopy : unmanagedCopies) {
4696+ auto value = unmanagedCopy.forward (*this );
4697+ B.emitFixLifetime (loc, value);
4698+ B.emitDestroyOperation (loc, value);
4699+ }
4700+
4701+ // hop back to the current executor
4702+ breadcrumb.emit (*this , loc);
4703+ }
4704+
47174705 return result;
47184706}
47194707
0 commit comments