@@ -130,9 +130,17 @@ class AsyncGeneratorBuiltinsAssembler : public AsyncBuiltinsAssembler {
130
130
// for AsyncGenerators.
131
131
template <typename Descriptor>
132
132
void AsyncGeneratorAwait (bool is_catchable);
133
+ void AsyncGeneratorAwaitResume (
134
+ TNode<Context> context,
135
+ TNode<JSAsyncGeneratorObject> async_generator_object, TNode<Object> value,
136
+ JSAsyncGeneratorObject::ResumeMode resume_mode);
133
137
void AsyncGeneratorAwaitResumeClosure (
134
138
TNode<Context> context, TNode<Object> value,
135
139
JSAsyncGeneratorObject::ResumeMode resume_mode);
140
+ void AsyncGeneratorReturnClosedReject (
141
+ TNode<Context> context,
142
+ TNode<JSAsyncGeneratorObject> async_generator_object,
143
+ TNode<Object> value);
136
144
};
137
145
138
146
// Shared implementation for the 3 Async Iterator protocol methods of Async
@@ -208,12 +216,10 @@ AsyncGeneratorBuiltinsAssembler::AllocateAsyncGeneratorRequest(
208
216
return CAST (request);
209
217
}
210
218
211
- void AsyncGeneratorBuiltinsAssembler::AsyncGeneratorAwaitResumeClosure (
212
- TNode<Context> context, TNode<Object> value,
219
+ void AsyncGeneratorBuiltinsAssembler::AsyncGeneratorAwaitResume (
220
+ TNode<Context> context,
221
+ TNode<JSAsyncGeneratorObject> async_generator_object, TNode<Object> value,
213
222
JSAsyncGeneratorObject::ResumeMode resume_mode) {
214
- const TNode<JSAsyncGeneratorObject> async_generator_object =
215
- CAST (LoadContextElement (context, Context::EXTENSION_INDEX));
216
-
217
223
SetGeneratorNotAwaiting (async_generator_object);
218
224
219
225
CSA_SLOW_DCHECK (this , IsGeneratorSuspended (async_generator_object));
@@ -247,6 +253,16 @@ void AsyncGeneratorBuiltinsAssembler::AsyncGeneratorAwaitResumeClosure(
247
253
async_generator_object);
248
254
}
249
255
256
+ void AsyncGeneratorBuiltinsAssembler::AsyncGeneratorAwaitResumeClosure (
257
+ TNode<Context> context, TNode<Object> value,
258
+ JSAsyncGeneratorObject::ResumeMode resume_mode) {
259
+ const TNode<JSAsyncGeneratorObject> async_generator_object =
260
+ CAST (LoadContextElement (context, Context::EXTENSION_INDEX));
261
+
262
+ AsyncGeneratorAwaitResume (context, async_generator_object, value,
263
+ resume_mode);
264
+ }
265
+
250
266
template <typename Descriptor>
251
267
void AsyncGeneratorBuiltinsAssembler::AsyncGeneratorAwait (bool is_catchable) {
252
268
auto async_generator_object =
@@ -319,6 +335,19 @@ AsyncGeneratorBuiltinsAssembler::TakeFirstAsyncGeneratorRequestFromQueue(
319
335
StoreObjectField (generator, JSAsyncGeneratorObject::kQueueOffset , next);
320
336
return request;
321
337
}
338
+
339
+ void AsyncGeneratorBuiltinsAssembler::AsyncGeneratorReturnClosedReject (
340
+ TNode<Context> context, TNode<JSAsyncGeneratorObject> generator,
341
+ TNode<Object> value) {
342
+ SetGeneratorNotAwaiting (generator);
343
+
344
+ // https://tc39.github.io/proposal-async-iteration/
345
+ // #async-generator-resume-next-return-processor-rejected step 2:
346
+ // Return ! AsyncGeneratorReject(_F_.[[Generator]], _reason_).
347
+ CallBuiltin (Builtin::kAsyncGeneratorReject , context, generator, value);
348
+
349
+ TailCallBuiltin (Builtin::kAsyncGeneratorResumeNext , context, generator);
350
+ }
322
351
} // namespace
323
352
324
353
// https://tc39.github.io/proposal-async-iteration/
@@ -611,7 +640,7 @@ TF_BUILTIN(AsyncGeneratorReturn, AsyncGeneratorBuiltinsAssembler) {
611
640
// AsyncGeneratorReturn is called when resuming requests with "return" resume
612
641
// modes. It is similar to AsyncGeneratorAwait(), but selects different
613
642
// resolve/reject closures depending on whether or not the generator is marked
614
- // as closed.
643
+ // as closed, and handles exception on Await explicitly .
615
644
//
616
645
// In particular, non-closed generators will resume the generator with either
617
646
// "return" or "throw" resume modes, allowing finally blocks or catch blocks
@@ -624,7 +653,8 @@ TF_BUILTIN(AsyncGeneratorReturn, AsyncGeneratorBuiltinsAssembler) {
624
653
// (per proposal-async-iteration/#sec-asyncgeneratorresumenext step 10.b.i)
625
654
//
626
655
// In all cases, the final step is to jump back to AsyncGeneratorResumeNext.
627
- const auto generator = Parameter<JSGeneratorObject>(Descriptor::kGenerator );
656
+ const auto generator =
657
+ Parameter<JSAsyncGeneratorObject>(Descriptor::kGenerator );
628
658
const auto value = Parameter<Object>(Descriptor::kValue );
629
659
const auto is_caught = Parameter<Oddball>(Descriptor::kIsCaught );
630
660
const TNode<AsyncGeneratorRequest> req =
@@ -650,9 +680,34 @@ TF_BUILTIN(AsyncGeneratorReturn, AsyncGeneratorBuiltinsAssembler) {
650
680
auto context = Parameter<Context>(Descriptor::kContext );
651
681
const TNode<JSPromise> outer_promise =
652
682
LoadPromiseFromAsyncGeneratorRequest (req);
653
- Await (context, generator, value, outer_promise, var_on_resolve.value (),
654
- var_on_reject.value (), is_caught);
655
683
684
+ Label done (this ), await_exception (this , Label::kDeferred ),
685
+ closed_await_exception (this , Label::kDeferred );
686
+ TVARIABLE (Object, var_exception);
687
+ {
688
+ compiler::ScopedExceptionHandler handler (this , &await_exception,
689
+ &var_exception);
690
+
691
+ Await (context, generator, value, outer_promise, var_on_resolve.value (),
692
+ var_on_reject.value (), is_caught);
693
+ }
694
+ Goto (&done);
695
+
696
+ BIND (&await_exception);
697
+ {
698
+ GotoIf (IsGeneratorStateClosed (state), &closed_await_exception);
699
+ // Tail call to AsyncGeneratorResumeNext
700
+ AsyncGeneratorAwaitResume (context, generator, var_exception.value (),
701
+ JSGeneratorObject::kThrow );
702
+ }
703
+
704
+ BIND (&closed_await_exception);
705
+ {
706
+ // Tail call to AsyncGeneratorResumeNext
707
+ AsyncGeneratorReturnClosedReject (context, generator, var_exception.value ());
708
+ }
709
+
710
+ BIND (&done);
656
711
Return (UndefinedConstant ());
657
712
}
658
713
@@ -695,14 +750,7 @@ TF_BUILTIN(AsyncGeneratorReturnClosedRejectClosure,
695
750
const TNode<JSAsyncGeneratorObject> generator =
696
751
CAST (LoadContextElement (context, Context::EXTENSION_INDEX));
697
752
698
- SetGeneratorNotAwaiting (generator);
699
-
700
- // https://tc39.github.io/proposal-async-iteration/
701
- // #async-generator-resume-next-return-processor-rejected step 2:
702
- // Return ! AsyncGeneratorReject(_F_.[[Generator]], _reason_).
703
- CallBuiltin (Builtin::kAsyncGeneratorReject , context, generator, value);
704
-
705
- TailCallBuiltin (Builtin::kAsyncGeneratorResumeNext , context, generator);
753
+ AsyncGeneratorReturnClosedReject (context, generator, value);
706
754
}
707
755
708
756
} // namespace internal
0 commit comments