2022-10-02 10:59:22 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Copyright  ( c )  2021 - 2022 ,  Linus  Groh  < linusg @ serenityos . org > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  SPDX - License - Identifier :  BSD - 2 - Clause 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <LibJS/Runtime/AbstractOperations.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <LibJS/Runtime/Error.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <LibJS/Runtime/NativeFunction.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <LibJS/Runtime/PromiseCapability.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								namespace  JS  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-02 12:11:30 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								NonnullGCPtr < PromiseCapability >  PromiseCapability : : create ( VM &  vm ,  GCPtr < Object >  promise ,  GCPtr < FunctionObject >  resolve ,  GCPtr < FunctionObject >  reject ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-14 17:40:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    return  vm . heap ( ) . allocate_without_realm < PromiseCapability > ( promise ,  resolve ,  reject ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-02 12:11:30 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								PromiseCapability : : PromiseCapability ( GCPtr < Object >  promise ,  GCPtr < FunctionObject >  resolve ,  GCPtr < FunctionObject >  reject ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    :  m_promise ( promise ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ,  m_resolve ( resolve ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ,  m_reject ( reject ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  PromiseCapability : : visit_edges ( Cell : : Visitor &  visitor ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-20 13:37:11 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    Base : : visit_edges ( visitor ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-02 12:11:30 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    visitor . visit ( m_promise ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    visitor . visit ( m_resolve ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    visitor . visit ( m_reject ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-02 10:59:22 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								// 27.2.1.5 NewPromiseCapability ( C ), https://tc39.es/ecma262/#sec-newpromisecapability
 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-02 12:11:30 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								ThrowCompletionOr < NonnullGCPtr < PromiseCapability > >  new_promise_capability ( VM &  vm ,  Value  constructor ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-02 10:59:22 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto &  realm  =  * vm . current_realm ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 1. If IsConstructor(C) is false, throw a TypeError exception.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! constructor . is_constructor ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-12 21:26:14 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        return  vm . throw_completion < TypeError > ( ErrorType : : NotAConstructor ,  TRY_OR_THROW_OOM ( vm ,  constructor . to_string_without_side_effects ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-02 10:59:22 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 2. NOTE: C is assumed to be a constructor function that supports the parameter conventions of the Promise constructor (see 27.2.3.1).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 3. Let promiseCapability be the PromiseCapability Record { [[Promise]]: undefined, [[Resolve]]: undefined, [[Reject]]: undefined }.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-02 18:44:30 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    auto  promise_capability  =  PromiseCapability : : create ( vm ,  nullptr ,  nullptr ,  nullptr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-02 10:59:22 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 4. Let executorClosure be a new Abstract Closure with parameters (resolve, reject) that captures promiseCapability and performs the following steps when called:
 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-02 18:44:30 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    // NOTE: Additionally to capturing the GC-allocated promise capability, we also create handles for
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // the resolve and reject values to keep them alive within the closure, as it may outlive the former.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto  executor_closure  =  [ & promise_capability ,  resolve_handle  =  make_handle ( { } ) ,  reject_handle  =  make_handle ( { } ) ] ( auto &  vm )  mutable  - >  ThrowCompletionOr < Value >  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-02 10:59:22 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        auto  resolve  =  vm . argument ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        auto  reject  =  vm . argument ( 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // No idea what other engines say here.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // a. If promiseCapability.[[Resolve]] is not undefined, throw a TypeError exception.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-02 18:44:30 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( ! resolve_handle . is_null ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-02 10:59:22 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								            return  vm . template  throw_completion < TypeError > ( ErrorType : : GetCapabilitiesExecutorCalledMultipleTimes ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // b. If promiseCapability.[[Reject]] is not undefined, throw a TypeError exception.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-02 18:44:30 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( ! reject_handle . is_null ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-02 10:59:22 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								            return  vm . template  throw_completion < TypeError > ( ErrorType : : GetCapabilitiesExecutorCalledMultipleTimes ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // c. Set promiseCapability.[[Resolve]] to resolve.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-02 18:44:30 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        resolve_handle  =  make_handle ( resolve ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( resolve . is_function ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            promise_capability - > set_resolve ( resolve . as_function ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-02 10:59:22 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // d. Set promiseCapability.[[Reject]] to reject.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-02 18:44:30 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        reject_handle  =  make_handle ( reject ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( reject . is_function ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            promise_capability - > set_reject ( reject . as_function ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-02 10:59:22 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // e. Return undefined.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  js_undefined ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 5. Let executor be CreateBuiltinFunction(executorClosure, 2, "", « »).
 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-13 20:49:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    auto  executor  =  NativeFunction : : create ( realm ,  move ( executor_closure ) ,  2 ,  " " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-02 10:59:22 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 6. Let promise be ? Construct(C, « executor »).
 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-13 20:49:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    auto  promise  =  TRY ( construct ( vm ,  constructor . as_function ( ) ,  executor ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-02 10:59:22 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 7. If IsCallable(promiseCapability.[[Resolve]]) is false, throw a TypeError exception.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-02 18:44:30 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    // NOTE: We only assign a value in the executor closure if it is a function.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( promise_capability - > resolve ( )  = =  nullptr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  vm . throw_completion < TypeError > ( ErrorType : : NotAFunction ,  " Promise capability resolve value " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-02 10:59:22 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 8. If IsCallable(promiseCapability.[[Reject]]) is false, throw a TypeError exception.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-02 18:44:30 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    // NOTE: We only assign a value in the executor closure if it is a function.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( promise_capability - > reject ( )  = =  nullptr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  vm . throw_completion < TypeError > ( ErrorType : : NotAFunction ,  " Promise capability reject value " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-02 10:59:22 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 9. Set promiseCapability.[[Promise]] to promise.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-02 18:44:30 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    promise_capability - > set_promise ( * promise ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-02 10:59:22 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    // 10. Return promiseCapability.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-02 18:44:30 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    return  promise_capability ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-02 10:59:22 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								}