2021-06-03 10:46:30 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Copyright  ( c )  2021 ,  Andreas  Kling  < kling @ serenityos . org > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  SPDX - License - Identifier :  BSD - 2 - Clause 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 15:17:37 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <AK/Debug.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 10:02:01 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <AK/TemporaryChange.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-15 12:36:57 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <LibJS/AST.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <LibJS/Bytecode/BasicBlock.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-17 13:16:35 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <LibJS/Bytecode/Generator.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 10:46:30 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								# include  <LibJS/Bytecode/Instruction.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <LibJS/Bytecode/Interpreter.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 09:19:34 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <LibJS/Bytecode/Op.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-17 13:16:35 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <LibJS/Bytecode/PassManager.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-11 22:38:21 +03:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <LibJS/Interpreter.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-01 12:24:46 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <LibJS/Runtime/GlobalEnvironment.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 18:26:13 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <LibJS/Runtime/GlobalObject.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-11 20:27:36 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <LibJS/Runtime/Realm.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 10:46:30 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								namespace  JS : : Bytecode  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-17 13:16:35 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  bool  s_bytecode_interpreter_enabled  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								bool  Interpreter : : enabled ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  s_bytecode_interpreter_enabled ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  Interpreter : : set_enabled ( bool  enabled ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    s_bytecode_interpreter_enabled  =  enabled ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-26 19:50:33 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  bool  s_optimizations_enabled  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  Interpreter : : set_optimizations_enabled ( bool  enabled ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    s_optimizations_enabled  =  enabled ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-24 13:34:46 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								bool  g_dump_bytecode  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-05 15:53:36 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-22 15:59:18 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								Interpreter : : Interpreter ( VM &  vm ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    :  m_vm ( vm ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-05 15:53:36 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 10:46:30 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Interpreter : : ~ Interpreter ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-02 12:53:10 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  Interpreter : : visit_edges ( Cell : : Visitor &  visitor ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( m_return_value . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        visitor . visit ( * m_return_value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( m_saved_return_value . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        visitor . visit ( * m_saved_return_value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( m_saved_exception . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        visitor . visit ( * m_saved_exception ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    for  ( auto &  window  :  m_register_windows )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        window . visit ( [ & ] ( auto &  value )  {  value - > visit_edges ( visitor ) ;  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-15 12:36:57 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								// 16.1.6 ScriptEvaluation ( scriptRecord ), https://tc39.es/ecma262/#sec-runtime-semantics-scriptevaluation
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								ThrowCompletionOr < Value >  Interpreter : : run ( Script &  script_record ,  JS : : GCPtr < Environment >  lexical_environment_override ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto &  vm  =  this - > vm ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 1. Let globalEnv be scriptRecord.[[Realm]].[[GlobalEnv]].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto &  global_environment  =  script_record . realm ( ) . global_environment ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 2. Let scriptContext be a new ECMAScript code execution context.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ExecutionContext  script_context ( vm . heap ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 3. Set the Function of scriptContext to null.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // NOTE: This was done during execution context construction.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 4. Set the Realm of scriptContext to scriptRecord.[[Realm]].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    script_context . realm  =  & script_record . realm ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 5. Set the ScriptOrModule of scriptContext to scriptRecord.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    script_context . script_or_module  =  NonnullGCPtr < Script > ( script_record ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 6. Set the VariableEnvironment of scriptContext to globalEnv.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    script_context . variable_environment  =  & global_environment ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 7. Set the LexicalEnvironment of scriptContext to globalEnv.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    script_context . lexical_environment  =  & global_environment ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // Non-standard: Override the lexical environment if requested.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( lexical_environment_override ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        script_context . lexical_environment  =  lexical_environment_override ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 8. Set the PrivateEnvironment of scriptContext to null.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // NOTE: This isn't in the spec, but we require it.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    script_context . is_strict_mode  =  script_record . parse_node ( ) . is_strict_mode ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // FIXME: 9. Suspend the currently running execution context.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 10. Push scriptContext onto the execution context stack; scriptContext is now the running execution context.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    TRY ( vm . push_execution_context ( script_context ,  { } ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 11. Let script be scriptRecord.[[ECMAScriptCode]].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto &  script  =  script_record . parse_node ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 12. Let result be Completion(GlobalDeclarationInstantiation(script, globalEnv)).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto  instantiation_result  =  script . global_declaration_instantiation ( vm ,  global_environment ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    Completion  result  =  instantiation_result . is_throw_completion ( )  ?  instantiation_result . throw_completion ( )  :  normal_completion ( { } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 13. If result.[[Type]] is normal, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( result . type ( )  = =  Completion : : Type : : Normal )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        auto  executable_result  =  JS : : Bytecode : : Generator : : generate ( script ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( executable_result . is_error ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( auto  error_string  =  executable_result . error ( ) . to_string ( ) ;  error_string . is_error ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                result  =  vm . template  throw_completion < JS : : InternalError > ( vm . error_message ( JS : : VM : : ErrorMessage : : OutOfMemory ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            else  if  ( error_string  =  String : : formatted ( " TODO({}) " , error_string.value()) ;  error_string . is_error ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                result  =  vm . template  throw_completion < JS : : InternalError > ( vm . error_message ( JS : : VM : : ErrorMessage : : OutOfMemory ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                result  =  JS : : throw_completion ( JS : : InternalError : : create ( realm ( ) ,  error_string . release_value ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            auto  executable  =  executable_result . release_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-26 19:50:33 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            if  ( s_optimizations_enabled )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-15 12:36:57 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                auto &  passes  =  optimization_pipeline ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                passes . perform ( * executable ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( g_dump_bytecode ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                executable - > dump ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            // a. Set result to the result of evaluating script.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-22 15:59:18 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            auto  result_or_error  =  run_and_return_frame ( script_record . realm ( ) ,  * executable ,  nullptr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-15 12:36:57 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            if  ( result_or_error . value . is_error ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                result  =  result_or_error . value . release_error ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                result  =  result_or_error . frame - > registers [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 14. If result.[[Type]] is normal and result.[[Value]] is empty, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( result . type ( )  = =  Completion : : Type : : Normal  & &  ! result . value ( ) . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // a. Set result to NormalCompletion(undefined).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        result  =  normal_completion ( js_undefined ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // FIXME: 15. Suspend scriptContext and remove it from the execution context stack.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    vm . pop_execution_context ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 16. Assert: The execution context stack is not empty.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    VERIFY ( ! vm . execution_context_stack ( ) . is_empty ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // FIXME: 17. Resume the context that is now on the top of the execution context stack as the running execution context.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // At this point we may have already run any queued promise jobs via on_call_stack_emptied,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // in which case this is a no-op.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // FIXME: These three should be moved out of Interpreter::run and give the host an option to run these, as it's up to the host when these get run.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    //        https://tc39.es/ecma262/#sec-jobs for jobs and https://tc39.es/ecma262/#_ref_3508 for ClearKeptObjects
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    //        finish_execution_generation is particularly an issue for LibWeb, as the HTML spec wants to run it specifically after performing a microtask checkpoint.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    //        The promise and registry cleanup queues don't cause LibWeb an issue, as LibWeb overrides the hooks that push onto these queues.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    vm . run_queued_promise_jobs ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    vm . run_queued_finalization_registry_cleanup_jobs ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    vm . finish_execution_generation ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 18. Return ? result.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( result . is_abrupt ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        VERIFY ( result . type ( )  = =  Completion : : Type : : Throw ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  result . release_error ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    VERIFY ( result . value ( ) . has_value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  * result . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								ThrowCompletionOr < Value >  Interpreter : : run ( SourceTextModule &  module ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // FIXME: This is not a entry point as defined in the spec, but is convenient.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    //        To avoid work we use link_and_eval_module however that can already be
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    //        dangerous if the vm loaded other modules.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto &  vm  =  this - > vm ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    TRY ( vm . link_and_eval_module ( Badge < Bytecode : : Interpreter >  { } ,  module ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    vm . run_queued_promise_jobs ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    vm . run_queued_finalization_registry_cleanup_jobs ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  js_undefined ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-22 15:59:18 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								Interpreter : : ValueAndFrame  Interpreter : : run_and_return_frame ( Realm &  realm ,  Executable  const &  executable ,  BasicBlock  const *  entry_point ,  RegisterWindow *  in_frame ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 10:46:30 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 09:11:20 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    dbgln_if ( JS_BYTECODE_DEBUG ,  " Bytecode::Interpreter will run unit {:p} " ,  & executable ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 10:46:30 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 10:02:01 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    TemporaryChange  restore_executable  {  m_current_executable ,  & executable  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-25 16:15:34 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    TemporaryChange  restore_saved_jump  {  m_scheduled_jump ,  static_cast < BasicBlock  const * > ( nullptr )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-25 16:35:39 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    TemporaryChange  restore_saved_exception  {  m_saved_exception ,  { }  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 10:02:01 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-07 17:12:09 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    bool  pushed_execution_context  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-09 17:09:48 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    ExecutionContext  execution_context ( vm ( ) . heap ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-22 13:03:06 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( vm ( ) . execution_context_stack ( ) . is_empty ( )  | |  ! vm ( ) . running_execution_context ( ) . lexical_environment )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // The "normal" interpreter pushes an execution context without environment so in that case we also want to push one.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-22 15:59:18 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        execution_context . this_value  =  & realm . global_object ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-08 19:23:00 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        static  DeprecatedFlyString  global_execution_context_name  =  " (*BC* global execution context) " ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-24 19:17:45 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        execution_context . function_name  =  global_execution_context_name ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-22 15:59:18 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        execution_context . lexical_environment  =  & realm . global_environment ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        execution_context . variable_environment  =  & realm . global_environment ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        execution_context . realm  =  realm ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-17 18:56:36 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        execution_context . is_strict_mode  =  executable . is_strict_mode ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-17 22:40:17 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        vm ( ) . push_execution_context ( execution_context ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-07 17:12:09 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pushed_execution_context  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-05 15:53:36 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-05 15:11:00 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-03-06 17:16:25 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    TemporaryChange  restore_current_block  {  m_current_block ,  entry_point  ? :  executable . basic_blocks . first ( )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-08 19:38:57 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-15 20:20:51 +04:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( in_frame ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-01 13:56:40 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        push_register_window ( in_frame ,  executable . number_of_registers ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-15 20:20:51 +04:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    else 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-02 15:05:17 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        push_register_window ( make < RegisterWindow > ( ) ,  executable . number_of_registers ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-11 00:34:44 +03:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    for  ( ; ; )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 11:58:46 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        Bytecode : : InstructionStreamIterator  pc ( m_current_block - > instruction_stream ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        TemporaryChange  temp_change  {  m_pc ,  & pc  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 20:45:38 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        // FIXME: This is getting kinda spaghetti-y
 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        bool  will_jump  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        bool  will_return  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 20:45:38 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        bool  will_yield  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        while  ( ! pc . at_end ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            auto &  instruction  =  * pc ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-07 14:36:45 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            auto  ran_or_error  =  instruction . execute ( * this ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( ran_or_error . is_error ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                auto  exception_value  =  * ran_or_error . throw_completion ( ) . value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-02 12:53:10 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                m_saved_exception  =  exception_value ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-25 23:15:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                if  ( unwind_contexts ( ) . is_empty ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 15:04:38 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                    break ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-25 23:15:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                auto &  unwind_context  =  unwind_contexts ( ) . last ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-25 12:30:54 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                if  ( unwind_context . executable  ! =  m_current_executable ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 15:04:38 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                if  ( unwind_context . handler )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-13 18:53:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                    vm ( ) . running_execution_context ( ) . lexical_environment  =  unwind_context . lexical_environment ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 11:58:46 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                    m_current_block  =  unwind_context . handler ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 15:04:38 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                    unwind_context . handler  =  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-14 02:20:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-07 14:36:45 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                    accumulator ( )  =  exception_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    m_saved_exception  =  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 15:04:38 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                    will_jump  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-24 23:52:39 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                if  ( unwind_context . finalizer )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 11:58:46 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                    m_current_block  =  unwind_context . finalizer ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 15:04:38 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                    will_jump  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-24 23:52:39 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                    break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 15:04:38 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-14 02:20:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                // An unwind context with no handler or finalizer? We have nowhere to jump, and continuing on will make us crash on the next `Call` to a non-native function if there's an exception! So let's crash here instead.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                // If you run into this, you probably forgot to remove the current unwind_context somewhere.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 15:04:38 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            if  ( m_pending_jump . has_value ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 11:58:46 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                m_current_block  =  m_pending_jump . release_value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                will_jump  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-02 12:53:10 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            if  ( m_return_value . has_value ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                will_return  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 20:45:38 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                // Note: A `yield` statement will not go through a finally statement,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                //       hence we need to set a flag to not do so,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                //       but we generate a Yield Operation in the case of returns in
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                //       generators as well, so we need to check if it will actually
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                //       continue or is a `return` in disguise
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                will_yield  =  instruction . type ( )  = =  Instruction : : Type : : Yield  & &  static_cast < Op : : Yield  const & > ( instruction ) . continuation ( ) . has_value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            + + pc ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-04 12:07:38 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-13 20:56:53 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( will_jump ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 20:45:38 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( ! unwind_contexts ( ) . is_empty ( )  & &  ! will_yield )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-13 20:56:53 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            auto &  unwind_context  =  unwind_contexts ( ) . last ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( unwind_context . executable  = =  m_current_executable  & &  unwind_context . finalizer )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-02 12:53:10 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                m_saved_return_value  =  m_return_value ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-13 20:56:53 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                m_return_value  =  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                m_current_block  =  unwind_context . finalizer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                // the unwind_context will be pop'ed when entering the finally block
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-13 20:56:53 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( pc . at_end ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-05 15:53:36 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 18:19:11 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-02 12:53:10 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( m_saved_exception . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 18:19:11 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            break ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-13 20:56:53 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( will_return ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-04 12:07:38 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 10:46:30 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 09:11:20 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    dbgln_if ( JS_BYTECODE_DEBUG ,  " Bytecode::Interpreter did run unit {:p} " ,  & executable ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 15:17:37 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  constexpr  ( JS_BYTECODE_DEBUG )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        for  ( size_t  i  =  0 ;  i  <  registers ( ) . size ( ) ;  + + i )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-12 21:54:02 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            String  value_string ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 15:17:37 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            if  ( registers ( ) [ i ] . is_empty ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-25 16:40:37 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                value_string  =  MUST ( " (empty) " _string ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 15:17:37 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            else 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-12 21:54:02 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                value_string  =  MUST ( registers ( ) [ i ] . to_string_without_side_effects ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 15:17:37 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            dbgln ( " [{:3}] {} " ,  i ,  value_string ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 10:46:30 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-05 15:53:36 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-01 13:56:40 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    auto  frame  =  pop_register_window ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-05 15:53:36 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-13 20:56:53 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    Value  return_value  =  js_undefined ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-02 12:53:10 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( m_return_value . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return_value  =  m_return_value . release_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  else  if  ( m_saved_return_value . has_value ( )  & &  ! m_saved_exception . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return_value  =  m_saved_return_value . release_value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-13 20:56:53 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-05 15:53:36 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // NOTE: The return value from a called function is put into $0 in the caller context.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! m_register_windows . is_empty ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-15 20:20:51 +04:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        window ( ) . registers [ 0 ]  =  return_value ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-05 15:53:36 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-11 00:44:56 +03:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    // At this point we may have already run any queued promise jobs via on_call_stack_emptied,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // in which case this is a no-op.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    vm ( ) . run_queued_promise_jobs ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-07 17:12:09 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( pushed_execution_context )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        VERIFY ( & vm ( ) . running_execution_context ( )  = =  & execution_context ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-24 19:17:45 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        vm ( ) . pop_execution_context ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-07 17:12:09 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-05 15:53:36 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-12 17:32:54 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    vm ( ) . finish_execution_generation ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-02 12:53:10 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( m_saved_exception . has_value ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-07 14:36:45 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        Value  thrown_value  =  m_saved_exception . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        m_saved_exception  =  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-25 17:15:29 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        m_saved_return_value  =  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-15 20:20:51 +04:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( auto *  register_window  =  frame . get_pointer < NonnullOwnPtr < RegisterWindow > > ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            return  {  throw_completion ( thrown_value ) ,  move ( * register_window )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  {  throw_completion ( thrown_value ) ,  nullptr  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-07 14:36:45 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-11 04:11:56 +03:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-13 20:56:53 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( auto *  register_window  =  frame . get_pointer < NonnullOwnPtr < RegisterWindow > > ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-15 20:20:51 +04:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        return  {  return_value ,  move ( * register_window )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  {  return_value ,  nullptr  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 10:46:30 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 15:04:38 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  Interpreter : : enter_unwind_context ( Optional < Label >  handler_target ,  Optional < Label >  finalizer_target ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-13 18:53:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    unwind_contexts ( ) . empend ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        m_current_executable , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        handler_target . has_value ( )  ?  & handler_target - > block ( )  :  nullptr , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        finalizer_target . has_value ( )  ?  & finalizer_target - > block ( )  :  nullptr , 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-02 15:05:17 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        vm ( ) . running_execution_context ( ) . lexical_environment ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 15:04:38 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  Interpreter : : leave_unwind_context ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-25 23:15:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    unwind_contexts ( ) . take_last ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 15:04:38 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-07 14:36:45 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								ThrowCompletionOr < void >  Interpreter : : continue_pending_unwind ( Label  const &  resume_label ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 15:04:38 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-02 12:53:10 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( m_saved_exception . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  throw_completion ( m_saved_exception . release_value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 15:04:38 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-07 14:36:45 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-02 12:53:10 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( m_saved_return_value . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        do_return ( m_saved_return_value . release_value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-13 20:56:53 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-25 16:15:34 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( m_scheduled_jump )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // FIXME: If we `break` or `continue` in the finally, we need to clear
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        //        this field
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        jump ( Label  {  * m_scheduled_jump  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        m_scheduled_jump  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        jump ( resume_label ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-07 14:36:45 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 15:04:38 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 20:40:20 +04:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-22 15:59:18 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								VM : : InterpreterExecutionScope  Interpreter : : ast_interpreter_scope ( Realm &  realm ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-11 22:38:21 +03:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! m_ast_interpreter ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-22 15:59:18 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        m_ast_interpreter  =  JS : : Interpreter : : create_with_existing_realm ( realm ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-11 22:38:21 +03:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  {  * m_ast_interpreter  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-26 20:10:11 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								Bytecode : : PassManager &  Interpreter : : optimization_pipeline ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 20:40:20 +04:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-26 20:10:11 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    static  auto  s_optimization_pipeline  =  [ ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        auto  pm  =  make < Bytecode : : PassManager > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 20:40:20 +04:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pm - > add < Passes : : GenerateCFG > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pm - > add < Passes : : UnifySameBlocks > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pm - > add < Passes : : GenerateCFG > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pm - > add < Passes : : MergeBlocks > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pm - > add < Passes : : GenerateCFG > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pm - > add < Passes : : UnifySameBlocks > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pm - > add < Passes : : GenerateCFG > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pm - > add < Passes : : MergeBlocks > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pm - > add < Passes : : GenerateCFG > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pm - > add < Passes : : PlaceBlocks > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-22 20:23:47 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pm - > add < Passes : : EliminateLoads > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-26 20:10:11 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        return  pm ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  * s_optimization_pipeline ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 20:40:20 +04:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-17 13:16:35 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								size_t  Interpreter : : pc ( )  const 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  m_pc  ?  m_pc - > offset ( )  :  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								DeprecatedString  Interpreter : : debug_position ( )  const 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  DeprecatedString : : formatted ( " {}:{:2}:{:4x} " ,  m_current_executable - > name ,  m_current_block - > name ( ) ,  pc ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-22 15:59:18 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								ThrowCompletionOr < NonnullOwnPtr < Bytecode : : Executable > >  compile ( VM &  vm ,  ASTNode  const &  node ,  FunctionKind  kind ,  DeprecatedFlyString  const &  name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto  executable_result  =  Bytecode : : Generator : : generate ( node ,  kind ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( executable_result . is_error ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  vm . throw_completion < InternalError > ( ErrorType : : NotImplemented ,  TRY_OR_THROW_OOM ( vm ,  executable_result . error ( ) . to_string ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto  bytecode_executable  =  executable_result . release_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    bytecode_executable - > name  =  name ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-26 20:10:11 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( s_optimizations_enabled )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        auto &  passes  =  Bytecode : : Interpreter : : optimization_pipeline ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        passes . perform ( * bytecode_executable ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  constexpr  ( JS_BYTECODE_DEBUG )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            dbgln ( " Optimisation passes took {}us " ,  passes . elapsed ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            dbgln ( " Compiled Bytecode::Block for function '{}': " ,  name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-22 15:59:18 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-26 20:10:11 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-22 15:59:18 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( Bytecode : : g_dump_bytecode ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        bytecode_executable - > dump ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  bytecode_executable ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Realm &  Interpreter : : realm ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  * m_vm . current_realm ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-01 13:56:40 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  Interpreter : : push_register_window ( Variant < NonnullOwnPtr < RegisterWindow > ,  RegisterWindow * >  window ,  size_t  register_count ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    m_register_windows . append ( move ( window ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    this - > window ( ) . registers . resize ( register_count ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    m_current_register_window  =  this - > window ( ) . registers ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Variant < NonnullOwnPtr < RegisterWindow > ,  RegisterWindow * >  Interpreter : : pop_register_window ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto  window  =  m_register_windows . take_last ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    m_current_register_window  =  m_register_windows . is_empty ( )  ?  Span < Value >  { }  :  this - > window ( ) . registers ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  window ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 10:46:30 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								}