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> 
 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <LibJS/Bytecode/BasicBlock.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> 
 
							 
						 
					
						
							
								
									
										
										
										
											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  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-05 15:53:36 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  Interpreter *  s_current ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-24 13:34:46 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								bool  g_dump_bytecode  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-05 15:53:36 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Interpreter *  Interpreter : : current ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  s_current ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-11 19:36:25 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								Interpreter : : Interpreter ( GlobalObject &  global_object ,  Realm &  realm ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 18:26:13 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    :  m_vm ( global_object . vm ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ,  m_global_object ( global_object ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-11 19:36:25 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    ,  m_realm ( realm ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 10:46:30 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-05 15:53:36 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    VERIFY ( ! s_current ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    s_current  =  this ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 10:46:30 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Interpreter : : ~ Interpreter ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-05 15:53:36 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    VERIFY ( s_current  = =  this ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    s_current  =  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 10:46:30 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-15 20:20:51 +04:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								Interpreter : : ValueAndFrame  Interpreter : : run_and_return_frame ( 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-02-07 14:36:45 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    VERIFY ( m_saved_exception . is_null ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											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.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-24 19:17:45 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        execution_context . this_value  =  & global_object ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-05 15:53:36 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        static  FlyString  global_execution_context_name  =  " (*BC* global execution context) " ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-24 19:17:45 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        execution_context . function_name  =  global_execution_context_name ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-11 20:27:36 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        execution_context . lexical_environment  =  & m_realm . global_environment ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        execution_context . variable_environment  =  & m_realm . global_environment ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-13 21:05:53 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        execution_context . realm  =  & m_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 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 01:38:30 +04:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    auto  block  =  entry_point  ? :  & executable . basic_blocks . first ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-15 20:20:51 +04:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( in_frame ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        m_register_windows . append ( in_frame ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    else 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:48:45 +03:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        m_register_windows . append ( make < RegisterWindow > ( MarkedVector < Value > ( vm ( ) . heap ( ) ) ,  MarkedVector < Environment * > ( vm ( ) . heap ( ) ) ,  MarkedVector < Environment * > ( vm ( ) . heap ( ) ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-11 00:34:44 +03:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    registers ( ) . resize ( executable . number_of_registers ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    registers ( ) [ Register : : global_object_index ]  =  Value ( & global_object ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    for  ( ; ; )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        Bytecode : : InstructionStreamIterator  pc ( block - > instruction_stream ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        bool  will_jump  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        bool  will_return  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        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 ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                m_saved_exception  =  make_handle ( exception_value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 15:04:38 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                if  ( m_unwind_contexts . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                auto &  unwind_context  =  m_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 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    block  =  unwind_context . handler ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    unwind_context . handler  =  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-14 02:20:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    // If there's no finalizer, there's nowhere for the handler block to unwind to, so the unwind context is no longer needed.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    if  ( ! unwind_context . finalizer ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                        m_unwind_contexts . take_last ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 15:04:38 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                    block  =  unwind_context . finalizer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    m_unwind_contexts . take_last ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    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 ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                block  =  m_pending_jump . release_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                will_jump  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( ! m_return_value . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                will_return  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            + + pc ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-04 12:07:38 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( will_return ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( pc . at_end ( )  & &  ! will_jump ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-05 15:53:36 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 18:19:11 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-07 14:36:45 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( ! m_saved_exception . is_null ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 18:19:11 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            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 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            String  value_string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( registers ( ) [ i ] . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                value_string  =  " (empty) " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                value_string  =  registers ( ) [ i ] . to_string_without_side_effects ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            dbgln ( " [{:3}] {} " ,  i ,  value_string ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 10:46:30 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-05 15:53:36 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-15 20:20:51 +04:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    auto  frame  =  m_register_windows . take_last ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-05 15:53:36 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 13:57:02 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    auto  return_value  =  m_return_value . value_or ( js_undefined ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    m_return_value  =  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											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 ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-07 14:36:45 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ! m_saved_exception . is_null ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        Value  thrown_value  =  m_saved_exception . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        m_saved_exception  =  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											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-04-15 20:20:51 +04:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( auto  register_window  =  frame . get_pointer < NonnullOwnPtr < RegisterWindow > > ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        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 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-25 12:30:54 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    m_unwind_contexts . empend ( m_current_executable ,  handler_target . has_value ( )  ?  & handler_target - > block ( )  :  nullptr ,  finalizer_target . has_value ( )  ?  & finalizer_target - > block ( )  :  nullptr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 15:04:38 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  Interpreter : : leave_unwind_context ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    m_unwind_contexts . take_last ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! m_saved_exception . is_null ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-07 14:36:45 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        auto  result  =  throw_completion ( m_saved_exception . value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 15:04:38 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        m_saved_exception  =  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-07 14:36:45 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        return  result ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 15:04:38 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-07 14:36:45 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    jump ( resume_label ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 15:04:38 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 20:40:20 +04:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-11 22:38:21 +03:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								VM : : InterpreterExecutionScope  Interpreter : : ast_interpreter_scope ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! m_ast_interpreter ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        m_ast_interpreter  =  JS : : Interpreter : : create_with_existing_realm ( m_realm ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  {  * m_ast_interpreter  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 20:40:20 +04:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								AK : : Array < OwnPtr < PassManager > ,  static_cast < UnderlyingType < Interpreter : : OptimizationLevel > > ( Interpreter : : OptimizationLevel : : __Count ) >  Interpreter : : s_optimization_pipelines  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Bytecode : : PassManager &  Interpreter : : optimization_pipeline ( Interpreter : : OptimizationLevel  level ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto  underlying_level  =  to_underlying ( level ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    VERIFY ( underlying_level  < =  to_underlying ( Interpreter : : OptimizationLevel : : __Count ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto &  entry  =  s_optimization_pipelines [ underlying_level ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( entry ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  * entry ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto  pm  =  make < PassManager > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( level  = =  OptimizationLevel : : Default )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        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 > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto &  passes  =  * pm ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    entry  =  move ( pm ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  passes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 10:46:30 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								}