2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2022 ,  David  Tuin  < davidot @ serenityos . org > 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-28 23:56:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2023 ,  networkException  < networkexception @ serenityos . org > 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  SPDX - License - Identifier :  BSD - 2 - Clause 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-23 14:18:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <AK/Debug.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <AK/TypeCasts.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# include  <LibJS/CyclicModule.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-11-23 14:18:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/ModuleRequest.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-10-02 10:59:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/PromiseCapability.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/PromiseConstructor.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-10-02 10:59:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/VM.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								namespace  JS  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-11-19 09:45:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								JS_DEFINE_ALLOCATOR ( CyclicModule ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-02 21:18:33 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								CyclicModule : : CyclicModule ( Realm &  realm ,  StringView  filename ,  bool  has_top_level_await ,  Vector < ModuleRequest >  requested_modules ,  Script : : HostDefined *  host_defined )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    :  Module ( realm ,  filename ,  host_defined ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    ,  m_requested_modules ( move ( requested_modules ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ,  m_has_top_level_await ( has_top_level_await ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-05 14:31:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  CyclicModule : : visit_edges ( Cell : : Visitor &  visitor )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Base : : visit_edges ( visitor ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    visitor . visit ( m_cycle_root ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-21 10:08:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    visitor . visit ( m_top_level_capability ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto  const &  module  :  m_async_parent_modules ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-05 14:31:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        visitor . visit ( module ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-28 23:56:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto  const &  loaded_module  :  m_loaded_modules ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        visitor . visit ( loaded_module . module ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-05 14:31:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-11-17 12:14:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  GraphLoadingState : : visit_edges ( Cell : : Visitor &  visitor )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Base : : visit_edges ( visitor ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    visitor . visit ( promise_capability ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    visitor . visit ( host_defined ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto *  module  :  visited ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        visitor . visit ( * module ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-10-29 02:53:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// 16.2.1.5.1 LoadRequestedModules ( [ hostDefined ] ), https://tc39.es/ecma262/#sec-LoadRequestedModules
  
						 
					
						
							
								
									
										
										
										
											2023-12-02 22:56:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								PromiseCapability &  CyclicModule : : load_requested_modules ( GCPtr < GraphLoadingState : : HostDefined >  host_defined )  
						 
					
						
							
								
									
										
										
										
											2023-10-29 02:53:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 1. If hostDefined is not present, let hostDefined be EMPTY.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // NOTE: The empty state is handled by hostDefined being an optional without value.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 2. Let pc be ! NewPromiseCapability(%Promise%).
 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-02 22:56:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  promise_capability  =  MUST ( new_promise_capability ( vm ( ) ,  vm ( ) . current_realm ( ) - > intrinsics ( ) . promise_constructor ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-29 02:53:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 3. Let state be the GraphLoadingState Record { [[IsLoading]]: true, [[PendingModulesCount]]: 1, [[Visited]]: « », [[PromiseCapability]]: pc, [[HostDefined]]: hostDefined }.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-11-17 12:14:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  state  =  heap ( ) . allocate_without_realm < GraphLoadingState > ( promise_capability ,  true ,  1 ,  HashTable < CyclicModule * >  { } ,  move ( host_defined ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-29 02:53:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 4. Perform InnerModuleLoading(state, module).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    inner_module_loading ( state ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // NOTE: This is likely a spec bug, see https://matrixlogs.bakkot.com/WHATWG/2023-02-13#L1
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // FIXME: 5. Return pc.[[Promise]].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  promise_capability ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// 16.2.1.5.1.1 InnerModuleLoading ( state, module ), https://tc39.es/ecma262/#sec-InnerModuleLoading
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  CyclicModule : : inner_module_loading ( JS : : GraphLoadingState &  state )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 1. Assert: state.[[IsLoading]] is true.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY ( state . is_loading ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 2. If module is a Cyclic Module Record, module.[[Status]] is NEW, and state.[[Visited]] does not contain module, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_status  = =  ModuleStatus : : New  & &  ! state . visited . contains ( this ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // a. Append module to state.[[Visited]].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        state . visited . set ( this ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // b. Let requestedModulesCount be the number of elements in module.[[RequestedModules]].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  requested_modules_count  =  m_requested_modules . size ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // c. Set state.[[PendingModulesCount]] to state.[[PendingModulesCount]] + requestedModulesCount.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        state . pending_module_count  + =  requested_modules_count ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // d. For each String required of module.[[RequestedModules]], do
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( auto  const &  required  :  m_requested_modules )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            bool  found_record_in_loaded_modules  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // i. If module.[[LoadedModules]] contains a Record whose [[Specifier]] is required, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for  ( auto  const &  record  :  m_loaded_modules )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( record . specifier  = =  required . module_specifier )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    // 1. Let record be that Record.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    // 2. Perform InnerModuleLoading(state, record.[[Module]]).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    static_cast < CyclicModule & > ( * record . module ) . inner_module_loading ( state ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    found_record_in_loaded_modules  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // ii. Else,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! found_record_in_loaded_modules )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // 1. Perform HostLoadImportedModule(module, required, state.[[HostDefined]], state).
 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-02 22:56:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                vm ( ) . host_load_imported_module ( NonnullGCPtr < CyclicModule >  {  * this  } ,  required ,  state . host_defined ,  NonnullGCPtr < GraphLoadingState >  {  state  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-29 02:53:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // 2. NOTE: HostLoadImportedModule will call FinishLoadingImportedModule, which re-enters the graph loading process through ContinueModuleLoading.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // iii. If state.[[IsLoading]] is false, return UNUSED.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! state . is_loading ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 3. Assert: state.[[PendingModulesCount]] ≥ 1.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY ( state . pending_module_count  > =  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 4. Set state.[[PendingModulesCount]] to state.[[PendingModulesCount]] - 1.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    - - state . pending_module_count ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 5. If state.[[PendingModulesCount]] = 0, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( state . pending_module_count  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // a. Set state.[[IsLoading]] to false.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        state . is_loading  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // b. For each Cyclic Module Record loaded of state.[[Visited]], do
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( auto  const &  loaded  :  state . visited )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // i. If loaded.[[Status]] is NEW, set loaded.[[Status]] to UNLINKED.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( loaded - > m_status  = =  ModuleStatus : : New ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-02 23:28:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                loaded - > m_status  =  ModuleStatus : : Unlinked ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-29 02:53:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // c. Perform ! Call(state.[[PromiseCapability]].[[Resolve]], undefined, « undefined »).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        MUST ( call ( vm ( ) ,  * state . promise_capability - > resolve ( ) ,  js_undefined ( ) ,  js_undefined ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 6. Return unused.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// 16.2.1.5.1.2 ContinueModuleLoading ( state, moduleCompletion ), https://tc39.es/ecma262/#sec-ContinueModuleLoading
  
						 
					
						
							
								
									
										
										
										
											2023-12-02 22:56:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  continue_module_loading ( GraphLoadingState &  state ,  ThrowCompletionOr < NonnullGCPtr < Module > >  const &  module_completion )  
						 
					
						
							
								
									
										
										
										
											2023-10-29 02:53:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 1. If state.[[IsLoading]] is false, return UNUSED.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-03 14:20:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! state . is_loading ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-29 02:53:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 2. If moduleCompletion is a normal completion, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! module_completion . is_error ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-02 22:56:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  module  =  module_completion . value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-29 02:53:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // a. Perform InnerModuleLoading(state, moduleCompletion.[[Value]]).
 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-02 22:56:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        verify_cast < CyclicModule > ( * module ) . inner_module_loading ( state ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-29 02:53:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 3. Else,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // a. Set state.[[IsLoading]] to false.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        state . is_loading  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  value  =  module_completion . throw_completion ( ) . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // b. Perform ! Call(state.[[PromiseCapability]].[[Reject]], undefined, « moduleCompletion.[[Value]] »).
 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-02 22:56:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        MUST ( call ( state . vm ( ) ,  * state . promise_capability - > reject ( ) ,  js_undefined ( ) ,  * value ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-29 02:53:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 4. Return UNUSED.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-12-06 10:28:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// 16.2.1.5.2 Link ( ), https://tc39.es/ecma262/#sec-moduledeclarationlinking
  
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								ThrowCompletionOr < void >  CyclicModule : : link ( VM &  vm )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    dbgln_if ( JS_MODULE_DEBUG ,  " [JS MODULE] link[{}]() " ,  this ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-06 10:28:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 1. Assert: module.[[Status]] is one of unlinked, linked, evaluating-async, or evaluated.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY ( m_status  = =  ModuleStatus : : Unlinked  | |  m_status  = =  ModuleStatus : : Linked  | |  m_status  = =  ModuleStatus : : EvaluatingAsync  | |  m_status  = =  ModuleStatus : : Evaluated ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    // 2. Let stack be a new empty List.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Vector < Module * >  stack ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-02 20:54:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 3. Let result be Completion(InnerModuleLinking(module, stack, 0)).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  result  =  inner_module_linking ( vm ,  stack ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 4. If result is an abrupt completion, then
 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-02 20:54:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( result . is_throw_completion ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        // a. For each Cyclic Module Record m of stack, do
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( auto *  module  :  stack )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( is < CyclicModule > ( module ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto &  cyclic_module  =  static_cast < CyclicModule & > ( * module ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // i. Assert: m.[[Status]] is linking.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                VERIFY ( cyclic_module . m_status  = =  ModuleStatus : : Linking ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // ii. Set m.[[Status]] to unlinked.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                cyclic_module . m_status  =  ModuleStatus : : Unlinked ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // b. Assert: module.[[Status]] is unlinked.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( m_status  = =  ModuleStatus : : Unlinked ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-12-06 10:28:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // c. Return ? result.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-02 20:54:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  result . release_error ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-12-06 10:28:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 5. Assert: module.[[Status]] is one of linked, evaluating-async, or evaluated.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    VERIFY ( m_status  = =  ModuleStatus : : Linked  | |  m_status  = =  ModuleStatus : : EvaluatingAsync  | |  m_status  = =  ModuleStatus : : Evaluated ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 6. Assert: stack is empty.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY ( stack . is_empty ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-02 20:54:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 7. Return unused.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// 16.2.1.5.1.1 InnerModuleLinking ( module, stack, index ), https://tc39.es/ecma262/#sec-InnerModuleLinking
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								ThrowCompletionOr < u32 >  CyclicModule : : inner_module_linking ( VM &  vm ,  Vector < Module * > &  stack ,  u32  index )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 1. If module is not a Cyclic Module Record, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //    a. Perform ? module.Link().
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //    b. Return index.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Note: Step 1, 1.a and 1.b are handled in Module.cpp
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-04 18:02:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    dbgln_if ( JS_MODULE_DEBUG ,  " [JS MODULE] inner_module_linking[{}](vm, {}, {}) " ,  this ,  DeprecatedString : : join ( ' , ' ,  stack ) ,  index ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 2. If module.[[Status]] is linking, linked, evaluating-async, or evaluated, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_status  = =  ModuleStatus : : Linking  | |  m_status  = =  ModuleStatus : : Linked  | |  m_status  = =  ModuleStatus : : EvaluatingAsync  | |  m_status  = =  ModuleStatus : : Evaluated )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // a. Return index.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  index ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 3. Assert: module.[[Status]] is unlinked.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY ( m_status  = =  ModuleStatus : : Unlinked ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 4. Set module.[[Status]] to linking.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_status  =  ModuleStatus : : Linking ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 5. Set module.[[DFSIndex]] to index.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_dfs_index  =  index ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 6. Set module.[[DFSAncestorIndex]] to index.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_dfs_ancestor_index  =  index ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 7. Set index to index + 1.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    + + index ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 8. Append module to stack.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    stack . append ( this ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-27 02:44:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# if JS_MODULE_DEBUG 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    StringBuilder  request_module_names ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto &  module_request  :  m_requested_modules )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        request_module_names . append ( module_request . module_specifier ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 17:32:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        request_module_names . append ( " ,  " sv ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-27 02:44:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    dbgln_if ( JS_MODULE_DEBUG ,  " [JS MODULE] module: {} has requested modules: [{}] " ,  filename ( ) ,  request_module_names . string_view ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 9. For each String required of module.[[RequestedModules]], do
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto &  required_string  :  m_requested_modules )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ModuleRequest  required  {  required_string  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-12-02 13:16:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // a. Let requiredModule be GetImportedModule(module, required).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  required_module  =  get_imported_module ( required ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // b. Set index to ? InnerModuleLinking(requiredModule, stack, index).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        index  =  TRY ( required_module - > inner_module_linking ( vm ,  stack ,  index ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // c. If requiredModule is a Cyclic Module Record, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( is < CyclicModule > ( * required_module ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto &  cyclic_module  =  static_cast < CyclicModule & > ( * required_module ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // i. Assert: requiredModule.[[Status]] is either linking, linked, evaluating-async, or evaluated.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            VERIFY ( cyclic_module . m_status  = =  ModuleStatus : : Linking  | |  cyclic_module . m_status  = =  ModuleStatus : : Linked  | |  cyclic_module . m_status  = =  ModuleStatus : : EvaluatingAsync  | |  cyclic_module . m_status  = =  ModuleStatus : : Evaluated ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // ii. Assert: requiredModule.[[Status]] is linking if and only if requiredModule is in stack.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            VERIFY ( ( cyclic_module . m_status  = =  ModuleStatus : : Linking )  = =  ( stack . contains_slow ( & cyclic_module ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // iii. If requiredModule.[[Status]] is linking, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( cyclic_module . m_status  = =  ModuleStatus : : Linking )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // 1. Set module.[[DFSAncestorIndex]] to min(module.[[DFSAncestorIndex]], requiredModule.[[DFSAncestorIndex]]).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                m_dfs_ancestor_index  =  min ( m_dfs_ancestor_index . value ( ) ,  cyclic_module . m_dfs_ancestor_index . value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 10. Perform ? module.InitializeEnvironment().
 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-02 20:54:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TRY ( initialize_environment ( vm ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 11. Assert: module occurs exactly once in stack.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-22 02:35:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    size_t  count  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    for  ( auto *  module  :  stack )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( module  = =  this ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            count + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY ( count  = =  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 12. Assert: module.[[DFSAncestorIndex]] ≤ module.[[DFSIndex]].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY ( m_dfs_ancestor_index . value ( )  < =  m_dfs_index . value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    dbgln_if ( JS_MODULE_DEBUG ,  " [JS MODULE] module {} after inner_linking has dfs {} and ancestor dfs {} " ,  filename ( ) ,  m_dfs_index . value ( ) ,  m_dfs_ancestor_index . value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 13. If module.[[DFSAncestorIndex]] = module.[[DFSIndex]], then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_dfs_ancestor_index  = =  m_dfs_index )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // a. Let done be false.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // b. Repeat, while done is false,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        while  ( true )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // i. Let requiredModule be the last element in stack.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // ii. Remove the last element of stack.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto *  required_module  =  stack . take_last ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // iii. Assert: requiredModule is a Cyclic Module Record.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            VERIFY ( is < CyclicModule > ( * required_module ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // iv. Set requiredModule.[[Status]] to linked.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            static_cast < CyclicModule & > ( * required_module ) . m_status  =  ModuleStatus : : Linked ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // v. If requiredModule and module are the same Module Record, set done to true.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( required_module  = =  this ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 14. Return index.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  index ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-12-02 22:56:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// 16.2.1.5.3 Evaluate ( ), https://tc39.es/ecma262/#sec-moduleevaluation
  
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								ThrowCompletionOr < Promise * >  CyclicModule : : evaluate ( VM &  vm )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    dbgln_if ( JS_MODULE_DEBUG ,  " [JS MODULE] evaluate[{}](vm) " ,  this ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 1. Assert: This call to Evaluate is not happening at the same time as another call to Evaluate within the surrounding agent.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // FIXME: Verify this somehow
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-12-02 22:56:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 2. Assert: module.[[Status]] is one of linked, evaluating-async, or evaluated.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    VERIFY ( m_status  = =  ModuleStatus : : Linked  | |  m_status  = =  ModuleStatus : : EvaluatingAsync  | |  m_status  = =  ModuleStatus : : Evaluated ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-26 13:37:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // NOTE: The spec does not catch the case where evaluate is called twice on a script which failed
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //       during evaluation. This means the script is evaluated but does not have a cycle root.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //       In that case we first check if this module itself has a top level capability.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //       See also: https://github.com/tc39/ecma262/issues/2823 .
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_top_level_capability  ! =  nullptr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  verify_cast < Promise > ( m_top_level_capability - > promise ( ) . ptr ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-12-02 22:56:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 3. If module.[[Status]] is either evaluating-async or evaluated, set module to module.[[CycleRoot]].
 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    if  ( m_status  = =  ModuleStatus : : EvaluatingAsync  | |  m_status  = =  ModuleStatus : : Evaluated )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Note: This will continue this function with module.[[CycleRoot]]
 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-26 13:37:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        VERIFY ( m_cycle_root ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( this  ! =  m_cycle_root ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( m_cycle_root - > m_status  = =  ModuleStatus : : Linked ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-26 16:09:02 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        dbgln_if ( JS_MODULE_DEBUG ,  " [JS MODULE] evaluate[{}](vm) deferring to cycle root at {} " ,  this ,  m_cycle_root . ptr ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        return  m_cycle_root - > evaluate ( vm ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 4. If module.[[TopLevelCapability]] is not empty, then
 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-02 12:11:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_top_level_capability  ! =  nullptr )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        // a. Return module.[[TopLevelCapability]].[[Promise]].
 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-02 12:11:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  verify_cast < Promise > ( m_top_level_capability - > promise ( ) . ptr ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 5. Let stack be a new empty List.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Vector < Module * >  stack ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-22 19:00:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto &  realm  =  * vm . current_realm ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 6. Let capability be ! NewPromiseCapability(%Promise%).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 7. Set module.[[TopLevelCapability]] to capability.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-27 00:54:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_top_level_capability  =  MUST ( new_promise_capability ( vm ,  realm . intrinsics ( ) . promise_constructor ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-02 20:54:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 8. Let result be Completion(InnerModuleEvaluation(module, stack, 0)).
 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    auto  result  =  inner_module_evaluation ( vm ,  stack ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 9. If result is an abrupt completion, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( result . is_throw_completion ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( ! m_evaluation_error . is_error ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // a. For each Cyclic Module Record m of stack, do
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( auto *  mod  :  stack )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! is < CyclicModule > ( * mod ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto &  cyclic_module  =  static_cast < CyclicModule & > ( * mod ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // i. Assert: m.[[Status]] is evaluating.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            VERIFY ( cyclic_module . m_status  = =  ModuleStatus : : Evaluating ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // ii. Set m.[[Status]] to evaluated.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            cyclic_module . m_status  =  ModuleStatus : : Evaluated ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // iii. Set m.[[EvaluationError]] to result.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            cyclic_module . m_evaluation_error  =  result . throw_completion ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // b. Assert: module.[[Status]] is evaluated.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( m_status  = =  ModuleStatus : : Evaluated ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // c. Assert: module.[[EvaluationError]] is result.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-02 12:38:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        VERIFY ( m_evaluation_error . is_error ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( same_value ( * m_evaluation_error . throw_completion ( ) . value ( ) ,  * result . throw_completion ( ) . value ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // d. Perform ! Call(capability.[[Reject]], undefined, « result.[[Value]] »).
 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-02 12:11:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        MUST ( call ( vm ,  * m_top_level_capability - > reject ( ) ,  js_undefined ( ) ,  * result . throw_completion ( ) . value ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 10. Else,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-02 22:56:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // a. Assert: module.[[Status]] is either evaluating-async or evaluated.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        VERIFY ( m_status  = =  ModuleStatus : : EvaluatingAsync  | |  m_status  = =  ModuleStatus : : Evaluated ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // b. Assert: module.[[EvaluationError]] is empty.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( ! m_evaluation_error . is_error ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // c. If module.[[AsyncEvaluation]] is false, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! m_async_evaluation )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // i. Assert: module.[[Status]] is evaluated.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            VERIFY ( m_status  = =  ModuleStatus : : Evaluated ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // ii. Perform ! Call(capability.[[Resolve]], undefined, « undefined »).
 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-02 12:11:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            MUST ( call ( vm ,  * m_top_level_capability - > resolve ( ) ,  js_undefined ( ) ,  js_undefined ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // d. Assert: stack is empty.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( stack . is_empty ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 11. Return capability.[[Promise]].
 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-02 12:11:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  verify_cast < Promise > ( m_top_level_capability - > promise ( ) . ptr ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// 16.2.1.5.2.1 InnerModuleEvaluation ( module, stack, index ), https://tc39.es/ecma262/#sec-innermoduleevaluation
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								ThrowCompletionOr < u32 >  CyclicModule : : inner_module_evaluation ( VM &  vm ,  Vector < Module * > &  stack ,  u32  index )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-12-04 18:02:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    dbgln_if ( JS_MODULE_DEBUG ,  " [JS MODULE] inner_module_evaluation[{}](vm, {}, {}) " ,  this ,  DeprecatedString : : join ( " ,  " sv ,  stack ) ,  index ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    // Note: Step 1 is performed in Module.cpp
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 2. If module.[[Status]] is evaluating-async or evaluated, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_status  = =  ModuleStatus : : EvaluatingAsync  | |  m_status  = =  ModuleStatus : : Evaluated )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // a. If module.[[EvaluationError]] is empty, return index.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! m_evaluation_error . is_error ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  index ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-02 20:54:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // b. Otherwise, return ? module.[[EvaluationError]].
 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        return  m_evaluation_error . throw_completion ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 3. If module.[[Status]] is evaluating, return index.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_status  = =  ModuleStatus : : Evaluating ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  index ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 4. Assert: module.[[Status]] is linked.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY ( m_status  = =  ModuleStatus : : Linked ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 5. Set module.[[Status]] to evaluating.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_status  =  ModuleStatus : : Evaluating ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 6. Set module.[[DFSIndex]] to index.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_dfs_index  =  index ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 7. Set module.[[DFSAncestorIndex]] to index.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_dfs_ancestor_index  =  index ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 8. Set module.[[PendingAsyncDependencies]] to 0.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_pending_async_dependencies  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 9. Set index to index + 1.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    + + index ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 10. Append module to stack.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    stack . append ( this ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 11. For each String required of module.[[RequestedModules]], do
 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-27 02:44:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto &  required  :  m_requested_modules )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-12-02 13:16:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // a. Let requiredModule be GetImportedModule(module, required).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  required_module  =  get_imported_module ( required ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-12-02 13:16:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // b. Set index to ? InnerModuleEvaluation(requiredModule, stack, index).
 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        index  =  TRY ( required_module - > inner_module_evaluation ( vm ,  stack ,  index ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-12-02 13:16:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // c. If requiredModule is a Cyclic Module Record, then
 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        if  ( ! is < CyclicModule > ( * required_module ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-12-02 13:16:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        JS : : NonnullGCPtr < CyclicModule >  cyclic_module  =  verify_cast < CyclicModule > ( * required_module ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        // i. Assert: requiredModule.[[Status]] is either evaluating, evaluating-async, or evaluated.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( cyclic_module - > m_status  = =  ModuleStatus : : Evaluating  | |  cyclic_module - > m_status  = =  ModuleStatus : : EvaluatingAsync  | |  cyclic_module - > m_status  = =  ModuleStatus : : Evaluated ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // ii. Assert: requiredModule.[[Status]] is evaluating if and only if requiredModule is in stack.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( cyclic_module - > m_status  ! =  ModuleStatus : : Evaluating  | |  stack . contains_slow ( cyclic_module ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // iii. If requiredModule.[[Status]] is evaluating, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( cyclic_module - > m_status  = =  ModuleStatus : : Evaluating )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // 1. Set module.[[DFSAncestorIndex]] to min(module.[[DFSAncestorIndex]], requiredModule.[[DFSAncestorIndex]]).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m_dfs_ancestor_index  =  min ( m_dfs_ancestor_index . value ( ) ,  cyclic_module - > m_dfs_ancestor_index . value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // iv. Else,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // 1. Set requiredModule to requiredModule.[[CycleRoot]].
 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-02 13:16:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            VERIFY ( cyclic_module - > m_cycle_root ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            cyclic_module  =  * cyclic_module - > m_cycle_root ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // 2. Assert: requiredModule.[[Status]] is evaluating-async or evaluated.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            VERIFY ( cyclic_module - > m_status  = =  ModuleStatus : : EvaluatingAsync  | |  cyclic_module - > m_status  = =  ModuleStatus : : Evaluated ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-02 20:54:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // 3. If requiredModule.[[EvaluationError]] is not empty, return ? requiredModule.[[EvaluationError]].
 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            if  ( cyclic_module - > m_evaluation_error . is_error ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  cyclic_module - > m_evaluation_error . throw_completion ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // v. If requiredModule.[[AsyncEvaluation]] is true, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( cyclic_module - > m_async_evaluation )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // 1. Set module.[[PendingAsyncDependencies]] to module.[[PendingAsyncDependencies]] + 1.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            + + m_pending_async_dependencies . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // 2. Append module to requiredModule.[[AsyncParentModules]].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            cyclic_module - > m_async_parent_modules . append ( this ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    dbgln_if ( JS_MODULE_DEBUG ,  " [JS MODULE] inner_module_evaluation on {} has tla: {} and pending async dep: {} dfs: {} ancestor dfs: {} " ,  filename ( ) ,  m_has_top_level_await ,  m_pending_async_dependencies . value ( ) ,  m_dfs_index . value ( ) ,  m_dfs_ancestor_index . value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 12. If module.[[PendingAsyncDependencies]] > 0 or module.[[HasTLA]] is true, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_pending_async_dependencies . value ( )  >  0  | |  m_has_top_level_await )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // a. Assert: module.[[AsyncEvaluation]] is false and was never previously set to true.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( ! m_async_evaluation ) ;  // FIXME: I don't think we can check previously?
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // b. Set module.[[AsyncEvaluation]] to true.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_async_evaluation  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // c. NOTE: The order in which module records have their [[AsyncEvaluation]] fields transition to true is significant. (See 16.2.1.5.2.4.)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-02 20:54:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // d. If module.[[PendingAsyncDependencies]] is 0, perform ExecuteAsyncModule(module).
 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        if  ( m_pending_async_dependencies . value ( )  = =  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-02 20:54:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            execute_async_module ( vm ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 13. Otherwise, perform ? module.ExecuteModule().
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-02 20:54:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        TRY ( execute_module ( vm ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 14. Assert: module occurs exactly once in stack.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  count  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto *  module  :  stack )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( module  = =  this ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            count + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY ( count  = =  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 15. Assert: module.[[DFSAncestorIndex]] ≤ module.[[DFSIndex]].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY ( m_dfs_ancestor_index . value ( )  < =  m_dfs_index . value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 16. If module.[[DFSAncestorIndex]] = module.[[DFSIndex]], then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_dfs_ancestor_index  = =  m_dfs_index )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // a. Let done be false.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        bool  done  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // b. Repeat, while done is false,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        while  ( ! done )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // i. Let requiredModule be the last element in stack.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // ii. Remove the last element of stack.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto *  required_module  =  stack . take_last ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // iii. Assert: requiredModule is a Cyclic Module Record.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            VERIFY ( is < CyclicModule > ( * required_module ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto &  cyclic_module  =  static_cast < CyclicModule & > ( * required_module ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // iv. If requiredModule.[[AsyncEvaluation]] is false, set requiredModule.[[Status]] to evaluated.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! cyclic_module . m_async_evaluation ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                cyclic_module . m_status  =  ModuleStatus : : Evaluated ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // v. Otherwise, set requiredModule.[[Status]] to evaluating-async.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                cyclic_module . m_status  =  ModuleStatus : : EvaluatingAsync ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // vi. If requiredModule and module are the same Module Record, set done to true.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( required_module  = =  this ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                done  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // vii. Set requiredModule.[[CycleRoot]] to module.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            cyclic_module . m_cycle_root  =  this ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 17. Return index.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  index ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-02 20:54:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								ThrowCompletionOr < void >  CyclicModule : : initialize_environment ( VM & )  
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Note: In ecma262 this is never called on a cyclic module only on SourceTextModules.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //       So this check is to make sure we don't accidentally call this.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-02 12:11:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								ThrowCompletionOr < void >  CyclicModule : : execute_module ( VM & ,  GCPtr < PromiseCapability > )  
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Note: In ecma262 this is never called on a cyclic module only on SourceTextModules.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //       So this check is to make sure we don't accidentally call this.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// 16.2.1.5.2.2 ExecuteAsyncModule ( module ), https://tc39.es/ecma262/#sec-execute-async-module
  
						 
					
						
							
								
									
										
										
										
											2022-05-02 20:54:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  CyclicModule : : execute_async_module ( VM &  vm )  
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-08-22 19:00:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto &  realm  =  * vm . current_realm ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-16 00:20:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    dbgln_if ( JS_MODULE_DEBUG ,  " [JS MODULE] executing async module {} " ,  filename ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 1. Assert: module.[[Status]] is evaluating or evaluating-async.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY ( m_status  = =  ModuleStatus : : Evaluating  | |  m_status  = =  ModuleStatus : : EvaluatingAsync ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 2. Assert: module.[[HasTLA]] is true.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY ( m_has_top_level_await ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 3. Let capability be ! NewPromiseCapability(%Promise%).
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-27 00:54:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  capability  =  MUST ( new_promise_capability ( vm ,  realm . intrinsics ( ) . promise_constructor ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 4. Let fulfilledClosure be a new Abstract Closure with no parameters that captures module and performs the following steps when called:
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-22 11:48:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  fulfilled_closure  =  [ & ] ( VM &  vm )  - >  ThrowCompletionOr < Value >  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-02 20:54:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // a. Perform AsyncModuleExecutionFulfilled(module).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        async_module_execution_fulfilled ( vm ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // b. Return undefined.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  js_undefined ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-02 20:54:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 5. Let onFulfilled be CreateBuiltinFunction(fulfilledClosure, 0, "", « »).
 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-13 20:49:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  on_fulfilled  =  NativeFunction : : create ( realm ,  move ( fulfilled_closure ) ,  0 ,  " " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 6. Let rejectedClosure be a new Abstract Closure with parameters (error) that captures module and performs the following steps when called:
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-22 11:48:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rejected_closure  =  [ & ] ( VM &  vm )  - >  ThrowCompletionOr < Value >  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        auto  error  =  vm . argument ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-02 20:54:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // a. Perform AsyncModuleExecutionRejected(module, error).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        async_module_execution_rejected ( vm ,  error ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // b. Return undefined.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  js_undefined ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-02 20:54:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 7. Let onRejected be CreateBuiltinFunction(rejectedClosure, 0, "", « »).
 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-13 20:49:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  on_rejected  =  NativeFunction : : create ( realm ,  move ( rejected_closure ) ,  0 ,  " " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-02 20:54:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 8. Perform PerformPromiseThen(capability.[[Promise]], onFulfilled, onRejected).
 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-02 12:11:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    verify_cast < Promise > ( capability - > promise ( ) . ptr ( ) ) - > perform_then ( on_fulfilled ,  on_rejected ,  { } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 9. Perform ! module.ExecuteModule(capability).
 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-02 20:54:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    MUST ( execute_module ( vm ,  capability ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-02 20:54:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 10. Return unused.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// 16.2.1.5.2.3 GatherAvailableAncestors ( module, execList ), https://tc39.es/ecma262/#sec-gather-available-ancestors
  
						 
					
						
							
								
									
										
										
										
											2022-05-02 20:54:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  CyclicModule : : gather_available_ancestors ( Vector < CyclicModule * > &  exec_list )  
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 1. For each Cyclic Module Record m of module.[[AsyncParentModules]], do
 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-26 16:09:02 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto  module  :  m_async_parent_modules )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        // a. If execList does not contain m and m.[[CycleRoot]].[[EvaluationError]] is empty, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! exec_list . contains_slow ( module )  & &  ! module - > m_cycle_root - > m_evaluation_error . is_error ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // i. Assert: m.[[Status]] is evaluating-async.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            VERIFY ( module - > m_status  = =  ModuleStatus : : EvaluatingAsync ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // ii. Assert: m.[[EvaluationError]] is empty.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            VERIFY ( ! module - > m_evaluation_error . is_error ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // iii. Assert: m.[[AsyncEvaluation]] is true.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            VERIFY ( module - > m_async_evaluation ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // iv. Assert: m.[[PendingAsyncDependencies]] > 0.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            VERIFY ( module - > m_pending_async_dependencies . value ( )  >  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // v. Set m.[[PendingAsyncDependencies]] to m.[[PendingAsyncDependencies]] - 1.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            module - > m_pending_async_dependencies . value ( ) - - ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // vi. If m.[[PendingAsyncDependencies]] = 0, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( module - > m_pending_async_dependencies . value ( )  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // 1. Append m to execList.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                exec_list . append ( module ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-02 20:54:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                // 2. If m.[[HasTLA]] is false, perform GatherAvailableAncestors(m, execList).
 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								                if  ( ! module - > m_has_top_level_await ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-02 20:54:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    module - > gather_available_ancestors ( exec_list ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-02 20:54:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 2. Return unused.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// 16.2.1.5.2.4 AsyncModuleExecutionFulfilled ( module ), https://tc39.es/ecma262/#sec-async-module-execution-fulfilled
  
						 
					
						
							
								
									
										
										
										
											2022-05-02 20:54:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  CyclicModule : : async_module_execution_fulfilled ( VM &  vm )  
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 1. If module.[[Status]] is evaluated, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_status  = =  ModuleStatus : : Evaluated )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // a. Assert: module.[[EvaluationError]] is not empty.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( m_evaluation_error . is_error ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-02 20:54:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // b. Return unused.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 2. Assert: module.[[Status]] is evaluating-async.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY ( m_status  = =  ModuleStatus : : EvaluatingAsync ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 3. Assert: module.[[AsyncEvaluation]] is true.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY ( m_async_evaluation ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 4. Assert: module.[[EvaluationError]] is empty.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY ( ! m_evaluation_error . is_error ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 5. Set module.[[AsyncEvaluation]] to false.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_async_evaluation  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 6. Set module.[[Status]] to evaluated.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_status  =  ModuleStatus : : Evaluated ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 7. If module.[[TopLevelCapability]] is not empty, then
 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-02 12:11:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_top_level_capability  ! =  nullptr )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        // a. Assert: module.[[CycleRoot]] is module.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( m_cycle_root  = =  this ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // b. Perform ! Call(module.[[TopLevelCapability]].[[Resolve]], undefined, « undefined »).
 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-02 12:11:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        MUST ( call ( vm ,  * m_top_level_capability - > resolve ( ) ,  js_undefined ( ) ,  js_undefined ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 8. Let execList be a new empty List.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Vector < CyclicModule * >  exec_list ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-02 20:54:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 9. Perform GatherAvailableAncestors(module, execList).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    gather_available_ancestors ( exec_list ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 10. Let sortedExecList be a List whose elements are the elements of execList, in the order in which they had their [[AsyncEvaluation]] fields set to true in InnerModuleEvaluation.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // FIXME: Sort the list. To do this we need to use more than an Optional<bool> to track [[AsyncEvaluation]].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 11. Assert: All elements of sortedExecList have their [[AsyncEvaluation]] field set to true, [[PendingAsyncDependencies]] field set to 0, and [[EvaluationError]] field set to empty.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY ( all_of ( exec_list ,  [ & ] ( CyclicModule *  module )  {  return  module - > m_async_evaluation  & &  module - > m_pending_async_dependencies . value ( )  = =  0  & &  ! module - > m_evaluation_error . is_error ( ) ;  } ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 12. For each Cyclic Module Record m of sortedExecList, do
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto *  module  :  exec_list )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // a. If m.[[Status]] is evaluated, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( module - > m_status  = =  ModuleStatus : : Evaluated )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // i. Assert: m.[[EvaluationError]] is not empty.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            VERIFY ( module - > m_evaluation_error . is_error ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // b. Else if m.[[HasTLA]] is true, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else  if  ( module - > m_has_top_level_await )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-02 20:54:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // i. Perform ExecuteAsyncModule(m).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            module - > execute_async_module ( vm ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // c. Else,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // i. Let result be m.ExecuteModule().
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  result  =  module - > execute_module ( vm ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // ii. If result is an abrupt completion, then
 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-02 20:54:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( result . is_throw_completion ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // 1. Perform AsyncModuleExecutionRejected(m, result.[[Value]]).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                module - > async_module_execution_rejected ( vm ,  * result . throw_completion ( ) . value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // iii. Else,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // 1. Set m.[[Status]] to evaluated.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                module - > m_status  =  ModuleStatus : : Evaluated ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // 2. If m.[[TopLevelCapability]] is not empty, then
 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-02 12:11:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  ( module - > m_top_level_capability  ! =  nullptr )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								                    // a. Assert: m.[[CycleRoot]] is m.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    VERIFY ( module - > m_cycle_root  = =  module ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    // b. Perform ! Call(m.[[TopLevelCapability]].[[Resolve]], undefined, « undefined »).
 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-02 12:11:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    MUST ( call ( vm ,  * module - > m_top_level_capability - > resolve ( ) ,  js_undefined ( ) ,  js_undefined ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-02 20:54:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 13. Return unused.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// 16.2.1.5.2.5 AsyncModuleExecutionRejected ( module, error ), https://tc39.es/ecma262/#sec-async-module-execution-rejected
  
						 
					
						
							
								
									
										
										
										
											2022-05-02 20:54:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  CyclicModule : : async_module_execution_rejected ( VM &  vm ,  Value  error )  
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 1. If module.[[Status]] is evaluated, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_status  = =  ModuleStatus : : Evaluated )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // a. Assert: module.[[EvaluationError]] is not empty.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( m_evaluation_error . is_error ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-02 20:54:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // b. Return unused.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 2. Assert: module.[[Status]] is evaluating-async.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY ( m_status  = =  ModuleStatus : : EvaluatingAsync ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 3. Assert: module.[[AsyncEvaluation]] is true.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY ( m_async_evaluation ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 4. Assert: module.[[EvaluationError]] is empty.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY ( ! m_evaluation_error . is_error ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 5. Set module.[[EvaluationError]] to ThrowCompletion(error)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_evaluation_error  =  throw_completion ( error ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 6. Set module.[[Status]] to evaluated.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_status  =  ModuleStatus : : Evaluated ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 7. For each Cyclic Module Record m of module.[[AsyncParentModules]], do
 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-26 16:09:02 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto  module  :  m_async_parent_modules )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-02 20:54:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // a. Perform AsyncModuleExecutionRejected(m, error).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        module - > async_module_execution_rejected ( vm ,  error ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 8. If module.[[TopLevelCapability]] is not empty, then
 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-02 12:11:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_top_level_capability  ! =  nullptr )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        // a. Assert: module.[[CycleRoot]] is module.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( m_cycle_root  = =  this ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // b. Perform ! Call(module.[[TopLevelCapability]].[[Reject]], undefined, « error »).
 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-02 12:11:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        MUST ( call ( vm ,  * m_top_level_capability - > reject ( ) ,  js_undefined ( ) ,  error ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-02 20:54:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 9. Return unused.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-12-02 13:16:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// 16.2.1.7 GetImportedModule ( referrer, specifier ), https://tc39.es/ecma262/#sec-GetImportedModule
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								NonnullGCPtr < Module >  CyclicModule : : get_imported_module ( ModuleRequest  const &  request )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 1. Assert: Exactly one element of referrer.[[LoadedModules]] is a Record whose [[Specifier]] is specifier,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //    since LoadRequestedModules has completed successfully on referrer prior to invoking this abstract operation.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    size_t  element_with_specifier_count  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto  const &  loaded_module  :  m_loaded_modules )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( loaded_module . specifier  = =  request . module_specifier ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            + + element_with_specifier_count ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY ( element_with_specifier_count  = =  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto  const &  loaded_module  :  m_loaded_modules )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( loaded_module . specifier  = =  request . module_specifier )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // 2. Let record be the Record in referrer.[[LoadedModules]] whose [[Specifier]] is specifier.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // 3. Return record.[[Module]].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  loaded_module . module ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-12-02 22:56:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// 13.3.10.1.1 ContinueDynamicImport ( promiseCapability, moduleCompletion ), https://tc39.es/ecma262/#sec-ContinueDynamicImport
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  continue_dynamic_import ( NonnullGCPtr < PromiseCapability >  promise_capability ,  ThrowCompletionOr < NonnullGCPtr < Module > >  const &  module_completion )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  vm  =  promise_capability - > vm ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 1. If moduleCompletion is an abrupt completion, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( module_completion . is_throw_completion ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // a. Perform ! Call(promiseCapability.[[Reject]], undefined, « moduleCompletion.[[Value]] »).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        MUST ( call ( vm ,  * promise_capability - > reject ( ) ,  js_undefined ( ) ,  * module_completion . throw_completion ( ) . value ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // b. Return unused.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 2. Let module be moduleCompletion.[[Value]].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  module  =  * module_completion . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 3. Let loadPromise be module.LoadRequestedModules().
 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-03 11:25:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto &  load_promise  =  module . load_requested_modules ( { } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-02 22:56:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 4. Let rejectedClosure be a new Abstract Closure with parameters (reason) that captures promiseCapability and performs the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //    following steps when called:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  reject_closure  =  [ promise_capability ] ( VM &  vm )  - >  ThrowCompletionOr < Value >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  reason  =  vm . argument ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // a. Perform ! Call(promiseCapability.[[Reject]], undefined, « reason »).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        MUST ( call ( vm ,  * promise_capability - > reject ( ) ,  js_undefined ( ) ,  reason ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // b. Return unused.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  js_undefined ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 5. Let onRejected be CreateBuiltinFunction(rejectedClosure, 1, "", « »).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  on_rejected  =  NativeFunction : : create ( * vm . current_realm ( ) ,  move ( reject_closure ) ,  1 ,  " " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 6. Let linkAndEvaluateClosure be a new Abstract Closure with no parameters that captures module, promiseCapability,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //    and onRejected and performs the following steps when called:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  link_and_evaluate_closure  =  [ & module ,  promise_capability ,  on_rejected ] ( VM &  vm )  - >  ThrowCompletionOr < Value >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // a. Let link be Completion(module.Link()).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  link  =  module . link ( vm ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // b. If link is an abrupt completion, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( link . is_throw_completion ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // i. Perform ! Call(promiseCapability.[[Reject]], undefined, « link.[[Value]] »).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            MUST ( call ( vm ,  * promise_capability - > reject ( ) ,  js_undefined ( ) ,  * link . throw_completion ( ) . value ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // ii. Return unused.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  js_undefined ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // c. Let evaluatePromise be module.Evaluate().
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  evaluate_promise  =  module . evaluate ( vm ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // d. Let fulfilledClosure be a new Abstract Closure with no parameters that captures module and
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //    promiseCapability and performs the following steps when called:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  fulfilled_closure  =  [ & module ,  promise_capability ] ( VM &  vm )  - >  ThrowCompletionOr < Value >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // i. Let namespace be GetModuleNamespace(module).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  namespace_  =  module . get_module_namespace ( vm ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // ii. Perform ! Call(promiseCapability.[[Resolve]], undefined, « namespace »).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            MUST ( call ( vm ,  * promise_capability - > resolve ( ) ,  js_undefined ( ) ,  namespace_ . value ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // iii. Return unused.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  js_undefined ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // e. Let onFulfilled be CreateBuiltinFunction(fulfilledClosure, 0, "", « »).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  on_fulfilled  =  NativeFunction : : create ( * vm . current_realm ( ) ,  move ( fulfilled_closure ) ,  0 ,  " " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // f. Perform PerformPromiseThen(evaluatePromise, onFulfilled, onRejected).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        evaluate_promise . value ( ) - > perform_then ( on_fulfilled ,  on_rejected ,  { } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // g. Return unused.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  js_undefined ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 7. Let linkAndEvaluate be CreateBuiltinFunction(linkAndEvaluateClosure, 0, "", « »).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  link_and_evaluate  =  NativeFunction : : create ( * vm . current_realm ( ) ,  move ( link_and_evaluate_closure ) ,  0 ,  " " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 8. Perform PerformPromiseThen(loadPromise, linkAndEvaluate, onRejected).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // FIXME: This is likely a spec bug, see load_requested_modules.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    verify_cast < Promise > ( * load_promise . promise ( ) ) . perform_then ( link_and_evaluate ,  on_rejected ,  { } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 9. Return unused.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-18 19:29:17 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}