2022-05-05 08:47:36 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Copyright  ( c )  2022 ,  Linus  Groh  < linusg @ serenityos . org > 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 21:57:49 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								 *  Copyright  ( c )  2023 ,  Luke  Wilde  < lukew @ serenityos . org > 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-05 08:47:36 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  SPDX - License - Identifier :  BSD - 2 - Clause 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <LibJS/Runtime/AsyncGenerator.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <LibJS/Runtime/AsyncGeneratorPrototype.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-23 11:44:43 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <LibJS/Runtime/AsyncGeneratorRequest.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 21:57:49 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <LibJS/Runtime/ECMAScriptFunctionObject.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-05 08:47:36 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								# include  <LibJS/Runtime/GlobalObject.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 21:57:49 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <LibJS/Runtime/PromiseConstructor.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-05 08:47:36 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								namespace  JS  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-11-19 09:45:05 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								JS_DEFINE_ALLOCATOR ( AsyncGenerator ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-11-27 17:27:51 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								ThrowCompletionOr < NonnullGCPtr < AsyncGenerator > >  AsyncGenerator : : create ( Realm &  realm ,  Value  initial_value ,  ECMAScriptFunctionObject *  generating_function ,  NonnullOwnPtr < ExecutionContext >  execution_context ,  NonnullOwnPtr < Bytecode : : CallFrame >  frame ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 21:57:49 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto &  vm  =  realm . vm ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // This is "g1.prototype" in figure-2 (https://tc39.es/ecma262/img/figure-2.png)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto  generating_function_prototype  =  TRY ( generating_function - > get ( vm . names . prototype ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto  generating_function_prototype_object  =  TRY ( generating_function_prototype . to_object ( vm ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-13 13:05:26 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    auto  object  =  realm . heap ( ) . allocate < AsyncGenerator > ( realm ,  realm ,  generating_function_prototype_object ,  move ( execution_context ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 21:57:49 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    object - > m_generating_function  =  generating_function ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    object - > m_frame  =  move ( frame ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    object - > m_previous_value  =  initial_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  object ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-11-27 16:45:45 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								AsyncGenerator : : AsyncGenerator ( Realm & ,  Object &  prototype ,  NonnullOwnPtr < ExecutionContext >  context ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-14 12:17:58 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    :  Object ( ConstructWithPrototypeTag : : Tag ,  prototype ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 21:57:49 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    ,  m_async_generator_context ( move ( context ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-05 08:47:36 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  AsyncGenerator : : visit_edges ( Cell : : Visitor &  visitor ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    Base : : visit_edges ( visitor ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    for  ( auto  const &  request  :  m_async_generator_queue )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( request . completion . value ( ) . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            visitor . visit ( * request . completion . value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-02 12:11:30 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        visitor . visit ( request . capability ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-05 08:47:36 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 21:57:49 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    visitor . visit ( m_generating_function ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    visitor . visit ( m_previous_value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-11-27 17:27:51 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( m_frame ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 21:57:49 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        m_frame - > visit_edges ( visitor ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    visitor . visit ( m_current_promise ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// 27.6.3.4 AsyncGeneratorEnqueue ( generator, completion, promiseCapability ), https://tc39.es/ecma262/#sec-asyncgeneratorenqueue
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  AsyncGenerator : : async_generator_enqueue ( Completion  completion ,  NonnullGCPtr < PromiseCapability >  promise_capability ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 1. Let request be AsyncGeneratorRequest { [[Completion]]: completion, [[Capability]]: promiseCapability }.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto  request  =  AsyncGeneratorRequest  {  . completion  =  move ( completion ) ,  . capability  =  promise_capability  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 2. Append request to generator.[[AsyncGeneratorQueue]].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    m_async_generator_queue . append ( move ( request ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 3. Return unused.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  AsyncGenerator : : set_async_generator_state ( Badge < AsyncGeneratorPrototype > ,  AsyncGenerator : : State  value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    m_async_generator_state  =  value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// 27.7.5.3 Await ( value ), https://tc39.es/ecma262/#await
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								ThrowCompletionOr < void >  AsyncGenerator : : await ( Value  value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto &  vm  =  this - > vm ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto &  realm  =  * vm . current_realm ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 1. Let asyncContext be the running execution context.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto &  async_context  =  vm . running_execution_context ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 2. Let promise be ? PromiseResolve(%Promise%, value).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto *  promise_object  =  TRY ( promise_resolve ( vm ,  realm . intrinsics ( ) . promise_constructor ( ) ,  value ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 3. Let fulfilledClosure be a new Abstract Closure with parameters (v) that captures asyncContext and performs the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    //    following steps when called:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto  fulfilled_closure  =  [ this ,  & async_context ] ( VM &  vm )  - >  ThrowCompletionOr < Value >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        auto  value  =  vm . argument ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // a. Let prevContext be the running execution context.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        auto &  prev_context  =  vm . running_execution_context ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // FIXME: b. Suspend prevContext.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // c. Push asyncContext onto the execution context stack; asyncContext is now the running execution context.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        TRY ( vm . push_execution_context ( async_context ,  { } ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // d. Resume the suspended evaluation of asyncContext using NormalCompletion(v) as the result of the operation that
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        //    suspended it.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        execute ( vm ,  normal_completion ( value ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // e. Assert: When we reach this step, asyncContext has already been removed from the execution context stack and
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        //    prevContext is the currently running execution context.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        VERIFY ( & vm . running_execution_context ( )  = =  & prev_context ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // f. Return undefined.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  js_undefined ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 4. Let onFulfilled be CreateBuiltinFunction(fulfilledClosure, 1, "", « »).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto  on_fulfilled  =  NativeFunction : : create ( realm ,  move ( fulfilled_closure ) ,  1 ,  " " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 5. Let rejectedClosure be a new Abstract Closure with parameters (reason) that captures asyncContext and performs the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    //    following steps when called:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto  rejected_closure  =  [ this ,  & async_context ] ( VM &  vm )  - >  ThrowCompletionOr < Value >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        auto  reason  =  vm . argument ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // a. Let prevContext be the running execution context.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        auto &  prev_context  =  vm . running_execution_context ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // FIXME: b. Suspend prevContext.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // c. Push asyncContext onto the execution context stack; asyncContext is now the running execution context.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        TRY ( vm . push_execution_context ( async_context ,  { } ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // d. Resume the suspended evaluation of asyncContext using ThrowCompletion(reason) as the result of the operation that
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        //    suspended it.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        execute ( vm ,  throw_completion ( reason ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // e. Assert: When we reach this step, asyncContext has already been removed from the execution context stack and
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        //    prevContext is the currently running execution context.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        VERIFY ( & vm . running_execution_context ( )  = =  & prev_context ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // f. Return undefined.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  js_undefined ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 6. Let onRejected be CreateBuiltinFunction(rejectedClosure, 1, "", « »).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto  on_rejected  =  NativeFunction : : create ( realm ,  move ( rejected_closure ) ,  1 ,  " " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 7. Perform PerformPromiseThen(promise, onFulfilled, onRejected).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    m_current_promise  =  verify_cast < Promise > ( promise_object ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    m_current_promise - > perform_then ( on_fulfilled ,  on_rejected ,  { } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 8. Remove asyncContext from the execution context stack and restore the execution context that is at the top of the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    //    execution context stack as the running execution context.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    vm . pop_execution_context ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // NOTE: None of these are necessary. 10-12 are handled by step d of the above lambdas.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 9. Let callerContext be the running execution context.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 10. Resume callerContext passing empty. If asyncContext is ever resumed again, let completion be the Completion Record with which it is resumed.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 11. Assert: If control reaches here, then asyncContext is the running execution context again.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 12. Return completion.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  AsyncGenerator : : execute ( VM &  vm ,  Completion  completion ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    while  ( true )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // Loosely based on step 4 of https://tc39.es/ecma262/#sec-asyncgeneratorstart
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        VERIFY ( completion . value ( ) . has_value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        auto  generated_value  =  [ ] ( Value  value )  - >  Value  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( value . is_object ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                return  value . as_object ( ) . get_without_side_effects ( " result " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            return  value . is_empty ( )  ?  js_undefined ( )  :  value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        auto  generated_continuation  =  [ & ] ( Value  value )  - >  Bytecode : : BasicBlock  const *  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( value . is_object ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                auto  number_value  =  value . as_object ( ) . get_without_side_effects ( " continuation " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                return  reinterpret_cast < Bytecode : : BasicBlock  const * > ( static_cast < u64 > ( number_value . as_double ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        auto  generated_is_await  =  [ ] ( Value  value )  - >  bool  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( value . is_object ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                return  value . as_object ( ) . get_without_side_effects ( " isAwait " ) . as_bool ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        auto &  realm  =  * vm . current_realm ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        auto  completion_object  =  Object : : create ( realm ,  nullptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        completion_object - > define_direct_property ( vm . names . type ,  Value ( to_underlying ( completion . type ( ) ) ) ,  default_attributes ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        completion_object - > define_direct_property ( vm . names . value ,  completion . value ( ) . value ( ) ,  default_attributes ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        auto &  bytecode_interpreter  =  vm . bytecode_interpreter ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        auto  const *  next_block  =  generated_continuation ( m_previous_value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // We should never enter `execute` again after the generator is complete.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        VERIFY ( next_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        VERIFY ( ! m_generating_function - > bytecode_executable ( ) - > basic_blocks . find_if ( [ next_block ] ( auto &  block )  {  return  block  = =  next_block ;  } ) . is_end ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-20 10:46:42 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        Bytecode : : CallFrame *  frame  =  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-11-27 17:27:51 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( m_frame ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            frame  =  m_frame . ptr ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 21:57:49 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( frame ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-11-27 17:27:51 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            frame - > registers ( ) [ 0 ]  =  completion_object ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 21:57:49 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            bytecode_interpreter . accumulator ( )  =  completion_object ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-09-21 09:26:32 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        auto  next_result  =  bytecode_interpreter . run_and_return_frame ( * m_generating_function - > bytecode_executable ( ) ,  next_block ,  frame ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 21:57:49 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-11-27 17:27:51 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( ! m_frame ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            m_frame  =  move ( next_result . frame ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 21:57:49 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        auto  result_value  =  move ( next_result . value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ! result_value . is_throw_completion ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            m_previous_value  =  result_value . release_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            auto  value  =  generated_value ( m_previous_value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            bool  is_await  =  generated_is_await ( m_previous_value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( is_await )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                auto  await_result  =  this - > await ( value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                if  ( await_result . is_throw_completion ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    completion  =  await_result . release_error ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        bool  done  =  result_value . is_throw_completion ( )  | |  generated_continuation ( m_previous_value )  = =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ! done )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            // 27.6.3.8 AsyncGeneratorYield ( value ), https://tc39.es/ecma262/#sec-asyncgeneratoryield
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            // 1. Let genContext be the running execution context.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            // 2. Assert: genContext is the execution context of a generator.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            // 3. Let generator be the value of the Generator component of genContext.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            // 4. Assert: GetGeneratorKind() is async.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            // NOTE: genContext is `m_async_generator_context`, generator is `this`.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            // 5. Let completion be NormalCompletion(value).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            auto  value  =  generated_value ( m_previous_value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            auto  yield_completion  =  normal_completion ( value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            // 6. Assert: The execution context stack has at least two elements.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            VERIFY ( vm . execution_context_stack ( ) . size ( )  > =  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            // 7. Let previousContext be the second to top element of the execution context stack.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            auto &  previous_context  =  vm . execution_context_stack ( ) . at ( vm . execution_context_stack ( ) . size ( )  -  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            // 8. Let previousRealm be previousContext's Realm.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            auto  previous_realm  =  previous_context - > realm ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            // 9. Perform AsyncGeneratorCompleteStep(generator, completion, false, previousRealm).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            complete_step ( yield_completion ,  false ,  previous_realm . ptr ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            // 10. Let queue be generator.[[AsyncGeneratorQueue]].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            auto &  queue  =  m_async_generator_queue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            // 11. If queue is not empty, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( ! queue . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                // a. NOTE: Execution continues without suspending the generator.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                // b. Let toYield be the first element of queue.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                auto &  to_yield  =  queue . first ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                // c. Let resumptionValue be Completion(toYield.[[Completion]]).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                completion  =  Completion ( to_yield . completion ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                // d. Return ? AsyncGeneratorUnwrapYieldResumption(resumptionValue).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                // NOTE: AsyncGeneratorUnwrapYieldResumption is performed inside the continuation block inside the generator,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                //       so we just need to enter the generator again.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            // 12. Else,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                // a. Set generator.[[AsyncGeneratorState]] to suspendedYield.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                m_async_generator_state  =  State : : SuspendedYield ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                // b. Remove genContext from the execution context stack and restore the execution context that is at the top of the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                //    execution context stack as the running execution context.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                vm . pop_execution_context ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                // c. Let callerContext be the running execution context.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                // d. Resume callerContext passing undefined. If genContext is ever resumed again, let resumptionValue be the Completion Record with which it is resumed.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                // e. Assert: If control reaches here, then genContext is the running execution context again.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                // f. Return ? AsyncGeneratorUnwrapYieldResumption(resumptionValue).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                // NOTE: e-f are performed whenever someone calls `execute` again.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // 27.6.3.2 AsyncGeneratorStart ( generator, generatorBody ), https://tc39.es/ecma262/#sec-asyncgeneratorstart
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // 4.e. Assert: If we return here, the async generator either threw an exception or performed either an implicit or explicit return.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // 4.f. Remove acGenContext from the execution context stack and restore the execution context that is at the top of the execution context stack as the running execution context.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        vm . pop_execution_context ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // 4.g. Set acGenerator.[[AsyncGeneratorState]] to completed.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        m_async_generator_state  =  State : : Completed ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // 4.h. If result.[[Type]] is normal, set result to NormalCompletion(undefined).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // 4.i. If result.[[Type]] is return, set result to NormalCompletion(result.[[Value]]).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        Completion  result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ! result_value . is_throw_completion ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            result  =  normal_completion ( generated_value ( m_previous_value ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            result  =  result_value . release_error ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // 4.j. Perform AsyncGeneratorCompleteStep(acGenerator, result, true).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        complete_step ( result ,  true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // 4.k. Perform AsyncGeneratorDrainQueue(acGenerator).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        drain_queue ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // 4.l. Return undefined.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// 27.6.3.6 AsyncGeneratorResume ( generator, completion ), https://tc39.es/ecma262/#sec-asyncgeneratorresume
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								ThrowCompletionOr < void >  AsyncGenerator : : resume ( VM &  vm ,  Completion  completion ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 1. Assert: generator.[[AsyncGeneratorState]] is either suspendedStart or suspendedYield.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    VERIFY ( m_async_generator_state  = =  State : : SuspendedStart  | |  m_async_generator_state  = =  State : : SuspendedYield ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 2. Let genContext be generator.[[AsyncGeneratorContext]].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto &  generator_context  =  m_async_generator_context ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 3. Let callerContext be the running execution context.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto  const &  caller_context  =  vm . running_execution_context ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // FIXME: 4. Suspend callerContext.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 5. Set generator.[[AsyncGeneratorState]] to executing.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    m_async_generator_state  =  State : : Executing ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 6. Push genContext onto the execution context stack; genContext is now the running execution context.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-11-27 16:45:45 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    TRY ( vm . push_execution_context ( * generator_context ,  { } ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 21:57:49 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 7. Resume the suspended evaluation of genContext using completion as the result of the operation that suspended
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    //    it. Let result be the Completion Record returned by the resumed computation.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 8. Assert: result is never an abrupt completion.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    execute ( vm ,  completion ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 9. Assert: When we return here, genContext has already been removed from the execution context stack and
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    //    callerContext is the currently running execution context.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    VERIFY ( & vm . running_execution_context ( )  = =  & caller_context ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 10. Return unused.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// 27.6.3.9 AsyncGeneratorAwaitReturn ( generator ), https://tc39.es/ecma262/#sec-asyncgeneratorawaitreturn
 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 22:23:43 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								// With unmerged broken promise fixup from https://github.com/tc39/ecma262/pull/2683
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  AsyncGenerator : : await_return ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 21:57:49 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto &  vm  =  this - > vm ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto &  realm  =  * vm . current_realm ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 1. Let queue be generator.[[AsyncGeneratorQueue]].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto &  queue  =  m_async_generator_queue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 2. Assert: queue is not empty.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    VERIFY ( ! queue . is_empty ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 3. Let next be the first element of queue.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto &  next  =  m_async_generator_queue . first ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 4. Let completion be Completion(next.[[Completion]]).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto  completion  =  Completion ( next . completion ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 5. Assert: completion.[[Type]] is return.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    VERIFY ( completion . type ( )  = =  Completion : : Type : : Return ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 22:23:43 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    // 6. Let promiseCompletion be Completion(PromiseResolve(%Promise%, _completion_.[[Value]])).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto  promise_completion  =  promise_resolve ( vm ,  realm . intrinsics ( ) . promise_constructor ( ) ,  completion . value ( ) . value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 21:57:49 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 22:23:43 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    // 7. If promiseCompletion is an abrupt completion, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( promise_completion . is_throw_completion ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // a. Set generator.[[AsyncGeneratorState]] to completed.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        m_async_generator_state  =  State : : Completed ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // b. Perform AsyncGeneratorCompleteStep(generator, promiseCompletion, true).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        complete_step ( promise_completion . release_error ( ) ,  true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // c. Perform AsyncGeneratorDrainQueue(generator).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        drain_queue ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // d. Return unused.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 8. Assert: promiseCompletion.[[Type]] is normal.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    VERIFY ( ! promise_completion . is_throw_completion ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 9. Let promise be promiseCompletion.[[Value]].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto *  promise  =  promise_completion . release_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 10. Let fulfilledClosure be a new Abstract Closure with parameters (value) that captures generator and performs
 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 21:57:49 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    //    the following steps when called:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto  fulfilled_closure  =  [ this ] ( VM &  vm )  - >  ThrowCompletionOr < Value >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // a. Set generator.[[AsyncGeneratorState]] to completed.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        m_async_generator_state  =  State : : Completed ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // b. Let result be NormalCompletion(value).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        auto  result  =  normal_completion ( vm . argument ( 0 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // c. Perform AsyncGeneratorCompleteStep(generator, result, true).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        complete_step ( result ,  true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // d. Perform AsyncGeneratorDrainQueue(generator).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        drain_queue ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // e. Return undefined.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  js_undefined ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 22:23:43 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    // 11. Let onFulfilled be CreateBuiltinFunction(fulfilledClosure, 1, "", « »).
 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 21:57:49 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    auto  on_fulfilled  =  NativeFunction : : create ( realm ,  move ( fulfilled_closure ) ,  1 ,  " " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 22:23:43 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    // 12. Let rejectedClosure be a new Abstract Closure with parameters (reason) that captures generator and performs
 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 21:57:49 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    //    the following steps when called:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto  rejected_closure  =  [ this ] ( VM &  vm )  - >  ThrowCompletionOr < Value >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // a. Set generator.[[AsyncGeneratorState]] to completed.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        m_async_generator_state  =  State : : Completed ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // b. Let result be ThrowCompletion(reason).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        auto  result  =  throw_completion ( vm . argument ( 0 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // c. Perform AsyncGeneratorCompleteStep(generator, result, true).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        complete_step ( result ,  true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // d. Perform AsyncGeneratorDrainQueue(generator).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        drain_queue ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // e. Return undefined.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  js_undefined ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 22:23:43 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    // 13. Let onRejected be CreateBuiltinFunction(rejectedClosure, 1, "", « »).
 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 21:57:49 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    auto  on_rejected  =  NativeFunction : : create ( realm ,  move ( rejected_closure ) ,  1 ,  " " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 22:23:43 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    // 14. Perform PerformPromiseThen(promise, onFulfilled, onRejected).
 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 21:57:49 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    // NOTE: await_return should only be called when the generator is in SuspendedStart or Completed state,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    //       so an await shouldn't be running currently, so it should be safe to overwrite m_current_promise.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    m_current_promise  =  verify_cast < Promise > ( promise ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    m_current_promise - > perform_then ( on_fulfilled ,  on_rejected ,  { } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 22:23:43 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    // 15. Return unused.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 21:57:49 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// 27.6.3.5 AsyncGeneratorCompleteStep ( generator, completion, done [ , realm ] ), https://tc39.es/ecma262/#sec-asyncgeneratorcompletestep
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  AsyncGenerator : : complete_step ( Completion  completion ,  bool  done ,  Realm *  realm ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto &  vm  =  this - > vm ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 1. Assert: generator.[[AsyncGeneratorQueue]] is not empty.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    VERIFY ( ! m_async_generator_queue . is_empty ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 2. Let next be the first element of generator.[[AsyncGeneratorQueue]].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 3. Remove the first element from generator.[[AsyncGeneratorQueue]].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto  next  =  m_async_generator_queue . take_first ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 4. Let promiseCapability be next.[[Capability]].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto  promise_capability  =  next . capability ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 5. Let value be completion.[[Value]].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto  value  =  completion . value ( ) . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 6. If completion.[[Type]] is throw, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( completion . type ( )  = =  Completion : : Type : : Throw )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // a. Perform ! Call(promiseCapability.[[Reject]], undefined, « value »).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        MUST ( call ( vm ,  * promise_capability - > reject ( ) ,  js_undefined ( ) ,  value ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 7. Else,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // a. Assert: completion.[[Type]] is normal.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        VERIFY ( completion . type ( )  = =  Completion : : Type : : Normal ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        GCPtr < Object >  iterator_result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // b. If realm is present, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( realm )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            // i. Let oldRealm be the running execution context's Realm.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            auto  old_realm  =  vm . running_execution_context ( ) . realm ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            // ii. Set the running execution context's Realm to realm.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            vm . running_execution_context ( ) . realm  =  realm ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            // iii. Let iteratorResult be CreateIterResultObject(value, done).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            iterator_result  =  create_iterator_result_object ( vm ,  value ,  done ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            // iv. Set the running execution context's Realm to oldRealm.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            vm . running_execution_context ( ) . realm  =  old_realm ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // c. Else,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            // i. Let iteratorResult be CreateIterResultObject(value, done).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            iterator_result  =  create_iterator_result_object ( vm ,  value ,  done ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        VERIFY ( iterator_result ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // d. Perform ! Call(promiseCapability.[[Resolve]], undefined, « iteratorResult »).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        MUST ( call ( vm ,  * promise_capability - > resolve ( ) ,  js_undefined ( ) ,  iterator_result ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 8. Return unused.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// 27.6.3.10 AsyncGeneratorDrainQueue ( generator ), https://tc39.es/ecma262/#sec-asyncgeneratordrainqueue
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  AsyncGenerator : : drain_queue ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 1. Assert: generator.[[AsyncGeneratorState]] is completed.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    VERIFY ( m_async_generator_state  = =  State : : Completed ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 2. Let queue be generator.[[AsyncGeneratorQueue]].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto &  queue  =  m_async_generator_queue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 3. If queue is empty, return unused.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( queue . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 4. Let done be false.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    bool  done  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 5. Repeat, while done is false,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    while  ( ! done )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // a. Let next be the first element of queue.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        auto &  next  =  m_async_generator_queue . first ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // b. Let completion be Completion(next.[[Completion]]).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        auto  completion  =  Completion ( next . completion ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // c. If completion.[[Type]] is return, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( completion . type ( )  = =  Completion : : Type : : Return )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            // i. Set generator.[[AsyncGeneratorState]] to awaiting-return.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            m_async_generator_state  =  State : : AwaitingReturn ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 22:23:43 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            // ii. Perform AsyncGeneratorAwaitReturn(generator).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            await_return ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 21:57:49 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            // iii. Set done to true.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            done  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // d. Else,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            // i. If completion.[[Type]] is normal, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( completion . type ( )  = =  Completion : : Type : : Normal )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                // 1. Set completion to NormalCompletion(undefined).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                completion  =  normal_completion ( js_undefined ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            // ii. Perform AsyncGeneratorCompleteStep(generator, completion, true).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            complete_step ( completion ,  true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            // iii. If queue is empty, set done to true.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( queue . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                done  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 6. Return unused.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-05 08:47:36 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								}