2020-03-07 19:42:11 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
									
										
										
										
											2021-06-03 10:46:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2020 - 2021 ,  Andreas  Kling  < kling @ serenityos . org > 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-22 22:51:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2020 - 2021 ,  Linus  Groh  < linusg @ serenityos . org > 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-03 14:16:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2021 ,  David  Tuin  < davidot @ serenityos . org > 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-07 19:42:11 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-22 01:24:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  SPDX - License - Identifier :  BSD - 2 - Clause 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-07 19:42:11 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-17 09:21:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <AK/Demangle.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-03-12 19:22:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <AK/HashMap.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-09-18 18:00:57 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <AK/HashTable.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-04-05 00:24:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <AK/ScopeGuard.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-03-12 19:22:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <AK/StringBuilder.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-11-28 16:14:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <AK/TemporaryChange.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-06-06 01:14:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibCrypto/BigInt/SignedBigInteger.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-03-07 19:42:11 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# include  <LibJS/AST.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibJS/Interpreter.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-06-22 01:14:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/AbstractOperations.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-05-21 17:28:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/Accessor.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-03-20 20:29:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/Array.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-06-06 01:14:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/BigInt.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-09-24 22:40:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/ECMAScriptFunctionObject.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-03-24 14:37:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/Error.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-07-01 12:24:46 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/FunctionEnvironment.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-04-08 11:05:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/GlobalObject.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-07-13 08:27:20 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/IteratorOperations.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-04-19 17:24:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/MarkedValueList.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-04-01 18:31:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/NativeFunction.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-07-01 12:24:46 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/ObjectEnvironment.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-03-16 14:20:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/PrimitiveString.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-11-09 22:52:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/PromiseConstructor.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/PromiseReaction.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-04-27 12:10:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/Reference.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-06-03 16:05:49 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/RegExpObject.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-04-27 21:52:47 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/Shape.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-02-10 12:21:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <typeinfo> 
  
						 
					
						
							
								
									
										
										
										
											2020-03-07 19:42:11 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								namespace  JS  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								class  InterpreterNodeScope  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    AK_MAKE_NONCOPYABLE ( InterpreterNodeScope ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    AK_MAKE_NONMOVABLE ( InterpreterNodeScope ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								public :  
						 
					
						
							
								
									
										
										
										
											2021-06-11 02:13:06 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope ( Interpreter &  interpreter ,  ASTNode  const &  node ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        :  m_interpreter ( interpreter ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-21 17:38:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        ,  m_chain_node  {  nullptr ,  node  } 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-24 19:17:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_interpreter . vm ( ) . running_execution_context ( ) . current_node  =  & node ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-21 17:38:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_interpreter . push_ast_node ( m_chain_node ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ~ InterpreterNodeScope ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-21 17:38:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_interpreter . pop_ast_node ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								private :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Interpreter &  m_interpreter ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-21 17:38:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ExecutingASTNodeChain  m_chain_node ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-17 09:21:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								String  ASTNode : : class_name ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // NOTE: We strip the "JS::" prefix.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  demangle ( typeid ( * this ) . name ( ) ) . substring ( 4 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 02:13:06 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  update_function_name ( Value  value ,  FlyString  const &  name )  
						 
					
						
							
								
									
										
										
										
											2020-09-18 18:00:57 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-21 17:14:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! value . is_function ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  function  =  value . as_function ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-24 22:40:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( is < ECMAScriptFunctionObject > ( function )  & &  function . name ( ) . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        static_cast < ECMAScriptFunctionObject & > ( function ) . set_name ( name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-18 18:00:57 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-12 17:49:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  ThrowCompletionOr < String >  get_function_name ( GlobalObject &  global_object ,  Value  value )  
						 
					
						
							
								
									
										
										
										
											2020-07-07 21:38:46 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( value . is_symbol ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-04 15:18:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  String : : formatted ( " [{}] " ,  value . as_symbol ( ) . description ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-07 21:38:46 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( value . is_string ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  value . as_string ( ) . string ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-27 18:36:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  value . to_string ( global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-07 21:38:46 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  ScopeNode : : evaluate_statements ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // FIXME: This should use completions but for now we just use the vm to communicate things.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  vm  =  interpreter . vm ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Value  last_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto &  node  :  children ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  value  =  node . execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! value . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            last_value  =  value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( vm . should_unwind ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  last_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Value  FunctionBody : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
									
										
										
										
											2020-03-07 19:42:11 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Note: Scoping should have already been setup by whoever is calling this FunctionBody.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  function_result  =  evaluate_statements ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( interpreter . vm ( ) . unwind_until ( )  ! =  ScopeType : : Function ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        function_result  =  js_undefined ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        interpreter . vm ( ) . stop_unwind ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  function_result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// 14.2.2 Runtime Semantics: Evaluation, https://tc39.es/ecma262/#sec-block-runtime-semantics-evaluation
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Value  BlockStatement : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  vm  =  interpreter . vm ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-05 12:59:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Environment *  old_environment  {  nullptr  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ArmedScopeGuard  restore_environment  =  [ & ]  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        vm . running_execution_context ( ) . lexical_environment  =  old_environment ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-05 12:59:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Optimization: We only need a new lexical environment if there are any lexical declarations. :^)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( has_lexical_declarations ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        old_environment  =  vm . running_execution_context ( ) . lexical_environment ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto *  block_environment  =  new_declarative_environment ( * old_environment ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        block_declaration_instantiation ( global_object ,  block_environment ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        vm . running_execution_context ( ) . lexical_environment  =  block_environment ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        restore_environment . disarm ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  block_value  =  evaluate_statements ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! labels ( ) . is_empty ( )  & &  vm . should_unwind_until ( ScopeType : : Breakable ,  labels ( ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        vm . stop_unwind ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( vm . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  block_value ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-07 19:42:11 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-03 17:02:43 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  Program : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-10-13 21:40:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // FIXME: This tries to be "ScriptEvaluation" and "evaluating scriptBody" at once. It shouldn't.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //        Clean this up and update perform_eval() / perform_shadow_realm_eval()
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY ( interpreter . lexical_environment ( )  & &  interpreter . lexical_environment ( ) - > is_global_environment ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  global_env  =  static_cast < GlobalEnvironment & > ( * interpreter . lexical_environment ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    TRY_OR_DISCARD ( global_declaration_instantiation ( interpreter ,  global_object ,  global_env ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  evaluate_statements ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-03 17:02:43 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  FunctionDeclaration : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
									
										
										
										
											2020-03-07 19:42:11 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_is_hoisted )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Perform special annexB steps see step 3 of: https://tc39.es/ecma262/#sec-web-compat-functiondeclarationinstantiation
 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-09 19:34:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto *  variable_environment  =  interpreter . vm ( ) . running_execution_context ( ) . variable_environment ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto *  lexical_environment  =  interpreter . vm ( ) . running_execution_context ( ) . lexical_environment ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-09 19:43:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  function_object  =  MUST ( lexical_environment - > get_binding_value ( global_object ,  name ( ) ,  false ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-09 19:34:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        MUST ( variable_environment - > set_mutable_binding ( global_object ,  name ( ) ,  function_object ,  false ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-16 09:12:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-07 19:42:11 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  FunctionExpression : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
									
										
										
										
											2020-03-19 11:12:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  instantiate_ordinary_function_expression ( interpreter ,  global_object ,  name ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// 15.2.5 Runtime Semantics: InstantiateOrdinaryFunctionExpression, https://tc39.es/ecma262/#sec-runtime-semantics-instantiateordinaryfunctionexpression
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Value  FunctionExpression : : instantiate_ordinary_function_expression ( Interpreter &  interpreter ,  GlobalObject &  global_object ,  FlyString  given_name )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( given_name . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        given_name  =  " " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  has_own_name  =  ! name ( ) . is_empty ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-07 22:53:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  const &  used_name  =  has_own_name  ?  name ( )  :  given_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto *  scope  =  interpreter . lexical_environment ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( has_own_name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( scope ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        scope  =  new_declarative_environment ( * scope ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-09 19:00:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        MUST ( scope - > create_immutable_binding ( global_object ,  name ( ) ,  false ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-07 22:53:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-11 20:29:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto *  private_scope  =  interpreter . vm ( ) . running_execution_context ( ) . private_environment ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  closure  =  ECMAScriptFunctionObject : : create ( global_object ,  used_name ,  body ( ) ,  parameters ( ) ,  function_length ( ) ,  scope ,  private_scope ,  kind ( ) ,  is_strict_mode ( ) ,  might_need_arguments_object ( ) ,  contains_direct_call_to_eval ( ) ,  is_arrow_function ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-07 22:53:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // FIXME: 6. Perform SetFunctionName(closure, name).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // FIXME: 7. Perform MakeConstructor(closure).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( has_own_name ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-09 19:16:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        MUST ( scope - > initialize_binding ( global_object ,  name ( ) ,  closure ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-07 22:53:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  closure ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-19 11:12:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  ExpressionStatement : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  m_expression - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-14 06:56:31 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								CallExpression : : ThisAndCallee  CallExpression : : compute_this_and_callee ( Interpreter &  interpreter ,  GlobalObject &  global_object ,  Reference  const &  callee_reference )  const  
						 
					
						
							
								
									
										
										
										
											2020-04-01 18:51:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-09-14 06:56:31 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( callee_reference . is_property_reference ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  this_value  =  callee_reference . get_this_value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-02 18:49:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  callee  =  TRY_OR_DISCARD ( callee_reference . get_value ( global_object ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-01 18:51:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  {  this_value ,  callee  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-04 11:52:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 01:37:51 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // [[Call]] will handle that in non-strict mode the this value becomes the global object
 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-14 06:56:31 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        js_undefined ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        callee_reference . is_unresolvable ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            ?  m_callee - > execute ( interpreter ,  global_object ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-02 18:49:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            :  TRY_OR_DISCARD ( callee_reference . get_value ( global_object ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-14 06:56:31 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-01 18:51:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 14:24:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// 13.3.8.1 Runtime Semantics: ArgumentListEvaluation, https://tc39.es/ecma262/#sec-runtime-semantics-argumentlistevaluation
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  argument_list_evaluation ( Interpreter &  interpreter ,  GlobalObject &  global_object ,  Vector < CallExpression : : Argument >  const &  arguments ,  MarkedValueList &  list )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  vm  =  global_object . vm ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    list . ensure_capacity ( arguments . size ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto &  argument  :  arguments )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  value  =  argument . value - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( vm . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( argument . is_spread )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-20 12:10:23 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto  result  =  get_iterator_values ( global_object ,  value ,  [ & ] ( Value  iterator_value )  - >  Optional < Completion >  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 14:24:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                list . append ( iterator_value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-20 12:10:23 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 14:24:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-20 12:10:23 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( result . is_error ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 14:24:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            list . append ( value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 18:25:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  NewExpression : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
									
										
										
										
											2020-03-07 19:42:11 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-13 19:00:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto &  vm  =  interpreter . vm ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 18:25:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 18:43:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  callee_value  =  m_callee - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-13 19:00:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( vm . exception ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-24 14:37:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-25 09:52:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! callee_value . is_function ( )  | |  ! callee_value . as_function ( ) . has_constructor ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 18:43:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        throw_type_error_for_callee ( interpreter ,  global_object ,  callee_value ,  " constructor " sv ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 18:25:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-06 20:24:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 18:25:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    MarkedValueList  arg_list ( vm . heap ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    argument_list_evaluation ( interpreter ,  global_object ,  m_arguments ,  arg_list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 18:43:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto &  function  =  callee_value . as_function ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-23 01:49:10 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  TRY_OR_DISCARD ( construct ( global_object ,  function ,  move ( arg_list ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 18:25:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  CallExpression : : throw_type_error_for_callee ( Interpreter &  interpreter ,  GlobalObject &  global_object ,  Value  callee_value ,  StringView  call_type )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  vm  =  interpreter . vm ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( is < Identifier > ( * m_callee )  | |  is < MemberExpression > ( * m_callee ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        String  expression_string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( is < Identifier > ( * m_callee ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            expression_string  =  static_cast < Identifier  const & > ( * m_callee ) . string ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-19 01:12:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 18:25:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            expression_string  =  static_cast < MemberExpression  const & > ( * m_callee ) . to_string_approximation ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-19 01:12:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 18:25:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        vm . throw_exception < TypeError > ( global_object ,  ErrorType : : IsNotAEvaluatedFrom ,  callee_value . to_string_without_side_effects ( ) ,  call_type ,  expression_string ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        vm . throw_exception < TypeError > ( global_object ,  ErrorType : : IsNotA ,  callee_value . to_string_without_side_effects ( ) ,  call_type ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-01 18:31:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 18:25:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2020-04-01 18:31:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 18:25:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  CallExpression : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  vm  =  interpreter . vm ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-14 06:56:31 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  callee_reference  =  m_callee - > to_reference ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( vm . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  [ this_value ,  callee ]  =  compute_this_and_callee ( interpreter ,  global_object ,  callee_reference ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 18:25:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( vm . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY ( ! callee . is_empty ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 14:24:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    MarkedValueList  arg_list ( vm . heap ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    argument_list_evaluation ( interpreter ,  global_object ,  m_arguments ,  arg_list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 19:22:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-13 17:44:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! callee . is_function ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        throw_type_error_for_callee ( interpreter ,  global_object ,  callee ,  " function " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 18:25:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto &  function  =  callee . as_function ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-14 06:56:31 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( & function  = =  global_object . eval_function ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        & &  callee_reference . is_environment_reference ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        & &  callee_reference . name ( ) . is_string ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        & &  callee_reference . name ( ) . as_string ( )  = =  vm . names . eval . as_string ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 14:24:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  script_value  =  arg_list . size ( )  = =  0  ?  js_undefined ( )  :  arg_list [ 0 ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-21 22:16:08 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  TRY_OR_DISCARD ( perform_eval ( script_value ,  global_object ,  vm . in_strict_mode ( )  ?  CallerMode : : Strict  :  CallerMode : : NonStrict ,  EvalMode : : Direct ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 20:13:53 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-23 20:56:28 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  TRY_OR_DISCARD ( vm . call ( function ,  this_value ,  move ( arg_list ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 19:30:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// 13.3.7.1 Runtime Semantics: Evaluation, https://tc39.es/ecma262/#sec-super-keyword-runtime-semantics-evaluation
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// SuperCall : super Arguments
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Value  SuperCall : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  vm  =  interpreter . vm ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 1. Let newTarget be GetNewTarget().
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  new_target  =  vm . get_new_target ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( vm . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 2. Assert: Type(newTarget) is Object.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY ( new_target . is_function ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 19:30:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 3. Let func be ! GetSuperConstructor().
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto *  func  =  get_super_constructor ( interpreter . vm ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY ( ! vm . exception ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 18:25:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 19:30:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 4. Let argList be ? ArgumentListEvaluation of Arguments.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MarkedValueList  arg_list ( vm . heap ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    argument_list_evaluation ( interpreter ,  global_object ,  m_arguments ,  arg_list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 5. If IsConstructor(func) is false, throw a TypeError exception.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-10 22:50:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! func  | |  ! Value ( func ) . is_constructor ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 18:25:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        vm . throw_exception < TypeError > ( global_object ,  ErrorType : : NotAConstructor ,  " Super constructor " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-24 14:37:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 19:30:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 6. Let result be ? Construct(func, argList, newTarget).
 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-23 01:49:10 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto *  result  =  TRY_OR_DISCARD ( construct ( global_object ,  static_cast < FunctionObject & > ( * func ) ,  move ( arg_list ) ,  & new_target . as_function ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 18:25:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 19:30:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 7. Let thisER be GetThisEnvironment().
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  this_er  =  verify_cast < FunctionEnvironment > ( get_this_environment ( interpreter . vm ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-15 15:01:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 19:30:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 8. Perform ? thisER.BindThisValue(result).
 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-09 16:55:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TRY_OR_DISCARD ( this_er . bind_this_value ( global_object ,  result ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-06 20:24:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 19:30:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 9. Let F be thisER.[[FunctionObject]].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 10. Assert: F is an ECMAScript function object. (NOTE: This is implied by the strong C++ type.)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    [[maybe_unused]]  auto &  f  =  this_er . function_object ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 11. Perform ? InitializeInstanceElements(result, F).
 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-23 01:49:10 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TRY_OR_DISCARD ( vm . initialize_instance_elements ( * result ,  f ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 19:30:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 12. Return result.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-15 15:01:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  result ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-07 19:42:11 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 01:38:30 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  YieldExpression : : execute ( Interpreter & ,  GlobalObject & )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // This should be transformed to a return.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-09 22:52:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// 15.8.5 Runtime Semantics: Evaluation, https://tc39.es/ecma262/#sec-async-function-definitions-runtime-semantics-evaluation
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Value  AwaitExpression : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 1. Let exprRef be the result of evaluating UnaryExpression.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 2. Let value be ? GetValue(exprRef).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  value  =  m_argument - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 3. Return ? Await(value).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  TRY_OR_DISCARD ( await ( global_object ,  value ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  ReturnStatement : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
									
										
										
										
											2020-03-07 19:42:11 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  value  =  argument ( )  ?  argument ( ) - > execute ( interpreter ,  global_object )  :  js_undefined ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-27 15:35:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-27 15:18:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    interpreter . vm ( ) . unwind ( ScopeType : : Function ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-07 19:42:11 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    return  value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  IfStatement : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
									
										
										
										
											2020-03-08 07:58:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  predicate_result  =  m_predicate - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-27 15:35:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-08 07:58:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-10 08:46:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( predicate_result . to_boolean ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  m_consequent - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-21 18:40:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_alternate ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  m_alternate - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-21 18:40:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-06 20:24:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  js_undefined ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-08 07:58:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-04 17:22:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// 14.11.2 Runtime Semantics: Evaluation, https://tc39.es/ecma262/#sec-with-statement-runtime-semantics-evaluation
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// WithStatement : with ( Expression ) Statement
  
						 
					
						
							
								
									
										
										
										
											2020-11-28 16:14:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  WithStatement : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
									
										
										
										
											2020-11-28 15:05:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-04 17:22:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 1. Let value be the result of evaluating Expression.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  value  =  m_object - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-28 16:14:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-04 17:22:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 2. Let obj be ? ToObject(? GetValue(value)).
 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-12 19:24:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto *  object  =  TRY_OR_DISCARD ( value . to_object ( global_object ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-28 16:14:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-04 17:22:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 3. Let oldEnv be the running execution context's LexicalEnvironment.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto *  old_environment  =  interpreter . vm ( ) . running_execution_context ( ) . lexical_environment ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-28 16:14:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-04 17:22:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 4. Let newEnv be NewObjectEnvironment(obj, true, oldEnv).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto *  new_environment  =  new_object_environment ( * object ,  true ,  old_environment ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 5. Set the running execution context's LexicalEnvironment to newEnv.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    interpreter . vm ( ) . running_execution_context ( ) . lexical_environment  =  new_environment ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 6. Let C be the result of evaluating Statement.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  result  =  m_body - > execute ( interpreter ,  global_object ) . value_or ( js_undefined ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-04 17:22:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 7. Set the running execution context's LexicalEnvironment to oldEnv.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    interpreter . vm ( ) . running_execution_context ( ) . lexical_environment  =  old_environment ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-08 20:46:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-04 17:22:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 8. Return Completion(UpdateEmpty(C, undefined)).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  result ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-28 15:05:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  WhileStatement : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
									
										
										
										
											2020-03-09 03:22:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-16 09:12:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  last_value  =  js_undefined ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-23 00:40:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( ; ; )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  test_result  =  m_test - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-27 15:35:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-23 00:40:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ! test_result . to_boolean ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        last_value  =  m_body - > execute ( interpreter ,  global_object ) . value_or ( last_value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-27 15:35:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-08 13:12:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( interpreter . vm ( ) . should_unwind ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-26 18:16:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( interpreter . vm ( ) . should_unwind_until ( ScopeType : : Continuable ,  m_labels ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-08 13:12:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                interpreter . vm ( ) . stop_unwind ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-26 18:16:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            }  else  if  ( interpreter . vm ( ) . should_unwind_until ( ScopeType : : Breakable ,  m_labels ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-08 13:12:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                interpreter . vm ( ) . stop_unwind ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-08 13:17:40 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  last_value ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-08 13:12:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-09 03:22:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  last_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  DoWhileStatement : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
									
										
										
										
											2020-04-04 21:29:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-16 09:12:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  last_value  =  js_undefined ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-23 00:40:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( ; ; )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-04 21:29:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        last_value  =  m_body - > execute ( interpreter ,  global_object ) . value_or ( last_value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-04 21:29:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-08 13:12:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( interpreter . vm ( ) . should_unwind ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-26 18:16:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( interpreter . vm ( ) . should_unwind_until ( ScopeType : : Continuable ,  m_labels ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-08 13:12:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                interpreter . vm ( ) . stop_unwind ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-26 18:16:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            }  else  if  ( interpreter . vm ( ) . should_unwind_until ( ScopeType : : Breakable ,  m_labels ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-08 13:12:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                interpreter . vm ( ) . stop_unwind ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-08 13:17:40 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  last_value ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-08 13:12:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-23 00:40:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  test_result  =  m_test - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! test_result . to_boolean ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-04 21:29:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  last_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  ForStatement : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:12:12 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Note we don't always set a new environment but to use RAII we must do this here.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto *  old_environment  =  interpreter . lexical_environment ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ScopeGuard  restore_old_environment  =  [ & ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        interpreter . vm ( ) . running_execution_context ( ) . lexical_environment  =  old_environment ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 13:56:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Vector < FlyString >  let_declarations ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 00:24:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-27 15:35:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_init )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( is < VariableDeclaration > ( * m_init )  & &  static_cast < VariableDeclaration  const & > ( * m_init ) . declaration_kind ( )  ! =  DeclarationKind : : Var )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto *  loop_environment  =  new_declarative_environment ( * old_environment ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto &  declaration  =  static_cast < VariableDeclaration  const & > ( * m_init ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            declaration . for_each_bound_name ( [ & ] ( auto  const &  name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( declaration . declaration_kind ( )  = =  DeclarationKind : : Const )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-09 19:00:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    MUST ( loop_environment - > create_immutable_binding ( global_object ,  name ,  true ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-09 18:53:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    MUST ( loop_environment - > create_mutable_binding ( global_object ,  name ,  false ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    let_declarations . append ( name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  IterationDecision : : Continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            interpreter . vm ( ) . running_execution_context ( ) . lexical_environment  =  loop_environment ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_init - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-27 15:35:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:12:12 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  last_value  =  js_undefined ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 14.7.4.4 CreatePerIterationEnvironment ( perIterationBindings ), https://tc39.es/ecma262/#sec-createperiterationenvironment
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  create_per_iteration_environment  =  [ & ] ( )  - >  ThrowCompletionOr < void >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( let_declarations . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto *  last_iteration_env  =  interpreter . lexical_environment ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto *  outer  =  last_iteration_env - > outer_environment ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( outer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto *  this_iteration_env  =  new_declarative_environment ( * outer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( auto &  name  :  let_declarations )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-09 18:53:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            MUST ( this_iteration_env - > create_mutable_binding ( global_object ,  name ,  false ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-09 19:43:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto  last_value  =  TRY ( last_iteration_env - > get_binding_value ( global_object ,  name ,  true ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            VERIFY ( ! last_value . is_empty ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-09 19:16:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            MUST ( this_iteration_env - > initialize_binding ( global_object ,  name ,  last_value ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        interpreter . vm ( ) . running_execution_context ( ) . lexical_environment  =  this_iteration_env ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    TRY_OR_DISCARD ( create_per_iteration_environment ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  test_empty_or_true  =  [ & ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! m_test ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  test_result  =  m_test - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  test_result . to_boolean ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    while  ( true )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! test_empty_or_true ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        last_value  =  m_body - > execute ( interpreter ,  global_object ) . value_or ( last_value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( interpreter . vm ( ) . should_unwind ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( interpreter . vm ( ) . should_unwind_until ( ScopeType : : Continuable ,  m_labels ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                interpreter . vm ( ) . stop_unwind ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  if  ( interpreter . vm ( ) . should_unwind_until ( ScopeType : : Breakable ,  m_labels ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                interpreter . vm ( ) . stop_unwind ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-28 20:16:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  last_value ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-27 15:35:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:12:12 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        TRY_OR_DISCARD ( create_per_iteration_environment ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( m_update )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m_update - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-27 15:35:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  last_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								struct  ForInOfHeadState  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    explicit  ForInOfHeadState ( Variant < NonnullRefPtr < ASTNode > ,  NonnullRefPtr < BindingPattern > >  lhs ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        lhs . visit ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            [ & ] ( NonnullRefPtr < ASTNode > &  ast_node )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                expression_lhs  =  ast_node . ptr ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            [ & ] ( NonnullRefPtr < BindingPattern > &  pattern )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                pattern_lhs  =  pattern . ptr ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                destructuring  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                lhs_kind  =  Assignment ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ASTNode *  expression_lhs  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    BindingPattern *  pattern_lhs  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    enum  LhsKind  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Assignment , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VarBinding , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        LexicalBinding 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    LhsKind  lhs_kind  =  Assignment ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    bool  destructuring  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Value  rhs_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 14.7.5.7 ForIn/OfBodyEvaluation ( lhs, stmt, iteratorRecord, iterationKind, lhsKind, labelSet [ , iteratorKind ] ), https://tc39.es/ecma262/#sec-runtime-semantics-forin-div-ofbodyevaluation-lhs-stmt-iterator-lhskind-labelset
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Note: This is only steps 6.g through 6.j of the method because we currently implement for-in without an iterator so to prevent duplicated code we do this part here.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ThrowCompletionOr < void >  execute_head ( Interpreter &  interpreter ,  GlobalObject &  global_object ,  Value  next_value )  const 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( ! next_value . is_empty ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Optional < Reference >  lhs_reference ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Environment *  iteration_environment  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // g. If lhsKind is either assignment or varBinding, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( lhs_kind  = =  Assignment  | |  lhs_kind  = =  VarBinding )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! destructuring )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                VERIFY ( expression_lhs ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( is < VariableDeclaration > ( * expression_lhs ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    auto &  declaration  =  static_cast < VariableDeclaration  const & > ( * expression_lhs ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    VERIFY ( declaration . declarations ( ) . first ( ) . target ( ) . has < NonnullRefPtr < Identifier > > ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    lhs_reference  =  declaration . declarations ( ) . first ( ) . target ( ) . get < NonnullRefPtr < Identifier > > ( ) - > to_reference ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 00:22:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    VERIFY ( is < Identifier > ( * expression_lhs )  | |  is < MemberExpression > ( * expression_lhs ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    auto &  expression  =  static_cast < Expression  const & > ( * expression_lhs ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    lhs_reference  =  expression . to_reference ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 00:22:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // h. Else,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            VERIFY ( expression_lhs  & &  is < VariableDeclaration > ( * expression_lhs ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            iteration_environment  =  new_declarative_environment ( * interpreter . lexical_environment ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto &  for_declaration  =  static_cast < VariableDeclaration  const & > ( * expression_lhs ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for_declaration . for_each_bound_name ( [ & ] ( auto  const &  name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( for_declaration . declaration_kind ( )  = =  DeclarationKind : : Const ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-09 19:00:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    MUST ( iteration_environment - > create_immutable_binding ( global_object ,  name ,  false ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                else 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-09 18:53:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    MUST ( iteration_environment - > create_mutable_binding ( global_object ,  name ,  true ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            interpreter . vm ( ) . running_execution_context ( ) . lexical_environment  =  iteration_environment ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! destructuring )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                VERIFY ( for_declaration . declarations ( ) . first ( ) . target ( ) . has < NonnullRefPtr < Identifier > > ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                lhs_reference  =  interpreter . vm ( ) . resolve_binding ( for_declaration . declarations ( ) . first ( ) . target ( ) . get < NonnullRefPtr < Identifier > > ( ) - > string ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-27 15:35:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:12:12 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( auto *  exception  =  interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  throw_completion ( exception - > value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:12:12 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // i. If destructuring is false, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! destructuring )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            VERIFY ( lhs_reference . has_value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( lhs_kind  = =  LexicalBinding ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-02 19:27:29 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  lhs_reference - > initialize_referenced_binding ( global_object ,  next_value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            else 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-02 19:27:29 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  lhs_reference - > put_value ( global_object ,  next_value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // j. Else,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( lhs_kind  = =  Assignment )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            VERIFY ( pattern_lhs ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  interpreter . vm ( ) . destructuring_assignment_evaluation ( * pattern_lhs ,  next_value ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-21 19:21:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        VERIFY ( expression_lhs  & &  is < VariableDeclaration > ( * expression_lhs ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  for_declaration  =  static_cast < VariableDeclaration  const & > ( * expression_lhs ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  binding_pattern  =  for_declaration . declarations ( ) . first ( ) . target ( ) . get < NonnullRefPtr < BindingPattern > > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( lhs_kind  = =  VarBinding  | |  iteration_environment ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // At this point iteration_environment is undefined if lhs_kind == VarBinding which means this does both
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // branch j.ii and j.iii because ForBindingInitialization is just a forwarding call to BindingInitialization.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  interpreter . vm ( ) . binding_initialization ( binding_pattern ,  next_value ,  iteration_environment ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// 14.7.5.5 Runtime Semantics: ForInOfLoopEvaluation, https://tc39.es/ecma262/#sec-runtime-semantics-forinofloopevaluation
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// 14.7.5.6 ForIn/OfHeadEvaluation ( uninitializedBoundNames, expr, iterationKind ), https://tc39.es/ecma262/#sec-runtime-semantics-forinofheadevaluation
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This method combines ForInOfLoopEvaluation and ForIn/OfHeadEvaluation for similar reason as ForIn/OfBodyEvaluation, to prevent code duplication.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// For the same reason we also skip step 6 and 7 of ForIn/OfHeadEvaluation as this is done by the appropriate for loop type.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  ThrowCompletionOr < ForInOfHeadState >  for_in_of_head_execute ( Interpreter &  interpreter ,  GlobalObject &  global_object ,  Variant < NonnullRefPtr < ASTNode > ,  NonnullRefPtr < BindingPattern > >  lhs ,  Expression  const &  rhs )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ForInOfHeadState  state ( lhs ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( auto *  ast_ptr  =  lhs . get_pointer < NonnullRefPtr < ASTNode > > ( ) ;  ast_ptr  & &  is < VariableDeclaration > ( * ( * ast_ptr ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Runtime Semantics: ForInOfLoopEvaluation, for any of:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //  ForInOfStatement : for ( var ForBinding in Expression ) Statement
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //  ForInOfStatement : for ( ForDeclaration in Expression ) Statement
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //  ForInOfStatement : for ( var ForBinding of AssignmentExpression ) Statement
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //  ForInOfStatement : for ( ForDeclaration of AssignmentExpression ) Statement
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 14.7.5.6 ForIn/OfHeadEvaluation ( uninitializedBoundNames, expr, iterationKind ), https://tc39.es/ecma262/#sec-runtime-semantics-forinofheadevaluation
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Environment *  new_environment  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  variable_declaration  =  static_cast < VariableDeclaration  const & > ( * ( * ast_ptr ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( variable_declaration . declarations ( ) . size ( )  = =  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        state . destructuring  =  variable_declaration . declarations ( ) . first ( ) . target ( ) . has < NonnullRefPtr < BindingPattern > > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( variable_declaration . declaration_kind ( )  = =  DeclarationKind : : Var )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            state . lhs_kind  =  ForInOfHeadState : : VarBinding ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto &  variable  =  variable_declaration . declarations ( ) . first ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // B.3.5 Initializers in ForIn Statement Heads, https://tc39.es/ecma262/#sec-initializers-in-forin-statement-heads
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( variable . init ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                VERIFY ( variable . target ( ) . has < NonnullRefPtr < Identifier > > ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto &  binding_id  =  variable . target ( ) . get < NonnullRefPtr < Identifier > > ( ) - > string ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto  reference  =  interpreter . vm ( ) . resolve_binding ( binding_id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( auto *  exception  =  interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    return  throw_completion ( exception - > value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto  result  =  TRY ( interpreter . vm ( ) . named_evaluation_if_anonymous_function ( global_object ,  * variable . init ( ) ,  binding_id ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-02 19:20:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                TRY ( reference . put_value ( global_object ,  result ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            state . lhs_kind  =  ForInOfHeadState : : LexicalBinding ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            new_environment  =  new_declarative_environment ( * interpreter . lexical_environment ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            variable_declaration . for_each_bound_name ( [ & ] ( auto  const &  name )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-09 18:53:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                MUST ( new_environment - > create_mutable_binding ( global_object ,  name ,  false ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( new_environment )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // 2.d Set the running execution context's LexicalEnvironment to newEnv.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            TemporaryChange < Environment * >  scope_change ( interpreter . vm ( ) . running_execution_context ( ) . lexical_environment ,  new_environment ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // 3. Let exprRef be the result of evaluating expr.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // 5. Let exprValue be ? GetValue(exprRef).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            state . rhs_value  =  rhs . execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Note that since a reference stores it's environment it doesn't matter we only reset
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // this after step 5. (Also we have no way of separating these steps at this point)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // 4. Set the running execution context's LexicalEnvironment to oldEnv.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // 3. Let exprRef be the result of evaluating expr.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // 5. Let exprValue be ? GetValue(exprRef).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            state . rhs_value  =  rhs . execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( auto *  exception  =  interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  throw_completion ( exception - > value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  state ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-21 19:21:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Runtime Semantics: ForInOfLoopEvaluation, for any of:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //  ForInOfStatement : for ( LeftHandSideExpression in Expression ) Statement
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //  ForInOfStatement : for ( LeftHandSideExpression of AssignmentExpression ) Statement
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 14.7.5.6 ForIn/OfHeadEvaluation ( uninitializedBoundNames, expr, iterationKind ), https://tc39.es/ecma262/#sec-runtime-semantics-forinofheadevaluation
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // We can skip step 1, 2 and 4 here (on top of already skipping step 6 and 7).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 3. Let exprRef be the result of evaluating expr.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 5. Let exprValue be ? GetValue(exprRef).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    state . rhs_value  =  rhs . execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( auto *  exception  =  interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  throw_completion ( exception - > value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  state ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-21 19:21:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  ForInStatement : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
									
										
										
										
											2020-04-21 19:21:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  for_in_head_state  =  TRY_OR_DISCARD ( for_in_of_head_execute ( interpreter ,  global_object ,  m_lhs ,  * m_rhs ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  rhs_result  =  for_in_head_state . rhs_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 14.7.5.6 ForIn/OfHeadEvaluation ( uninitializedBoundNames, expr, iterationKind ), https://tc39.es/ecma262/#sec-runtime-semantics-forinofheadevaluation
 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-10 18:47:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( rhs_result . is_nullish ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  js_undefined ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-12 19:24:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto *  object  =  MUST ( rhs_result . to_object ( global_object ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 14.7.5.7 ForIn/OfBodyEvaluation ( lhs, stmt, iteratorRecord, iterationKind, lhsKind, labelSet [ , iteratorKind ] ), https://tc39.es/ecma262/#sec-runtime-semantics-forin-div-ofbodyevaluation-lhs-stmt-iterator-lhskind-labelset
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Environment *  old_environment  =  interpreter . lexical_environment ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  restore_scope  =  ScopeGuard ( [ & ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        interpreter . vm ( ) . running_execution_context ( ) . lexical_environment  =  old_environment ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  last_value  =  js_undefined ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-21 19:21:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    while  ( object )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-03 02:25:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  property_names  =  TRY_OR_DISCARD ( object - > enumerable_own_property_names ( Object : : PropertyKind : : Key ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-06 21:39:17 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        for  ( auto &  value  :  property_names )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            TRY_OR_DISCARD ( for_in_head_state . execute_head ( interpreter ,  global_object ,  value ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            last_value  =  m_body - > execute ( interpreter ,  global_object ) . value_or ( last_value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            interpreter . vm ( ) . running_execution_context ( ) . lexical_environment  =  old_environment ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-21 19:21:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-27 15:18:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( interpreter . vm ( ) . should_unwind ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-26 18:16:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  ( interpreter . vm ( ) . should_unwind_until ( ScopeType : : Continuable ,  m_labels ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-27 15:18:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    interpreter . vm ( ) . stop_unwind ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-26 18:16:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                }  else  if  ( interpreter . vm ( ) . should_unwind_until ( ScopeType : : Breakable ,  m_labels ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-27 15:18:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    interpreter . vm ( ) . stop_unwind ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-21 19:21:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-08 13:17:40 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    return  last_value ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-21 19:21:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-28 23:30:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        object  =  TRY_OR_DISCARD ( object - > internal_get_prototype_of ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-21 19:21:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  last_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  ForOfStatement : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
									
										
										
										
											2020-04-21 19:21:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  for_of_head_state  =  TRY_OR_DISCARD ( for_in_of_head_execute ( interpreter ,  global_object ,  m_lhs ,  m_rhs ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  rhs_result  =  for_of_head_state . rhs_value ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-21 19:21:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  last_value  =  js_undefined ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 14.7.5.7 ForIn/OfBodyEvaluation ( lhs, stmt, iteratorRecord, iterationKind, lhsKind, labelSet [ , iteratorKind ] ), https://tc39.es/ecma262/#sec-runtime-semantics-forin-div-ofbodyevaluation-lhs-stmt-iterator-lhskind-labelset
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // We use get_iterator_values which behaves like ForIn/OfBodyEvaluation with iteratorKind iterate.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Environment *  old_environment  =  interpreter . lexical_environment ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  restore_scope  =  ScopeGuard ( [ & ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        interpreter . vm ( ) . running_execution_context ( ) . lexical_environment  =  old_environment ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-21 19:21:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-20 12:10:23 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TRY_OR_DISCARD ( get_iterator_values ( global_object ,  rhs_result ,  [ & ] ( Value  value )  - >  Optional < Completion >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        TRY ( for_of_head_state . execute_head ( interpreter ,  global_object ,  value ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        last_value  =  m_body - > execute ( interpreter ,  global_object ) . value_or ( last_value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        interpreter . vm ( ) . running_execution_context ( ) . lexical_environment  =  old_environment ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-20 12:10:23 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( auto *  exception  =  interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  throw_completion ( exception - > value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-27 15:18:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( interpreter . vm ( ) . should_unwind ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-26 18:16:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( interpreter . vm ( ) . should_unwind_until ( ScopeType : : Continuable ,  m_labels ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-27 15:18:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                interpreter . vm ( ) . stop_unwind ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-26 18:16:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            }  else  if  ( interpreter . vm ( ) . should_unwind_until ( ScopeType : : Breakable ,  m_labels ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-27 15:18:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                interpreter . vm ( ) . stop_unwind ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-20 12:10:23 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  normal_completion ( last_value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-21 19:21:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-20 12:10:23 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  normal_completion ( last_value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-21 19:21:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-13 08:27:20 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-20 12:10:23 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-13 08:27:20 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-21 19:21:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  last_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-23 16:09:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  ForAwaitOfStatement : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 14.7.5.6 ForIn/OfHeadEvaluation ( uninitializedBoundNames, expr, iterationKind ), https://tc39.es/ecma262/#sec-runtime-semantics-forinofheadevaluation
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Note: Performs only steps 1 through 5.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  for_of_head_state  =  TRY_OR_DISCARD ( for_in_of_head_execute ( interpreter ,  global_object ,  m_lhs ,  m_rhs ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  rhs_result  =  for_of_head_state . rhs_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // NOTE: Perform step 7 from ForIn/OfHeadEvaluation. And since this is always async we only have to do step 7.d.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // d. Return ? GetIterator(exprValue, iteratorHint).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto *  iterator  =  TRY_OR_DISCARD ( get_iterator ( global_object ,  rhs_result ,  IteratorHint : : Async ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY ( iterator ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  vm  =  interpreter . vm ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 14.7.5.7 ForIn/OfBodyEvaluation ( lhs, stmt, iteratorRecord, iterationKind, lhsKind, labelSet [ , iteratorKind ] ), https://tc39.es/ecma262/#sec-runtime-semantics-forin-div-ofbodyevaluation-lhs-stmt-iterator-lhskind-labelset
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // NOTE: Here iteratorKind is always async.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 2. Let oldEnv be the running execution context's LexicalEnvironment.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Environment *  old_environment  =  interpreter . lexical_environment ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  restore_scope  =  ScopeGuard ( [ & ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        interpreter . vm ( ) . running_execution_context ( ) . lexical_environment  =  old_environment ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 3. Let V be undefined.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  last_value  =  js_undefined ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // NOTE: Step 4 and 5 are just extracting properties from the head which is done already in for_in_of_head_execute.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //       And these are only used in step 6.g through 6.k which is done with for_of_head_state.execute_head.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 6. Repeat,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    while  ( true )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // NOTE: Since we don't have iterator records yet we have to extract the function first.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  next_method  =  TRY_OR_DISCARD ( iterator - > get ( vm . names . next ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! next_method . is_function ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            vm . throw_exception < TypeError > ( global_object ,  ErrorType : : IterableNextNotAFunction ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // a. Let nextResult be ? Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]]).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  next_result  =  TRY_OR_DISCARD ( call ( global_object ,  next_method ,  iterator ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // b. If iteratorKind is async, set nextResult to ? Await(nextResult).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        next_result  =  TRY_OR_DISCARD ( await ( global_object ,  next_result ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // c. If Type(nextResult) is not Object, throw a TypeError exception.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! next_result . is_object ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            vm . throw_exception < TypeError > ( global_object ,  ErrorType : : IterableNextBadReturn ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // d. Let done be ? IteratorComplete(nextResult).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  done  =  TRY_OR_DISCARD ( iterator_complete ( global_object ,  next_result . as_object ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // e. If done is true, return NormalCompletion(V).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( done ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  last_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // f. Let nextValue be ? IteratorValue(nextResult).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  next_value  =  TRY_OR_DISCARD ( iterator_value ( global_object ,  next_result . as_object ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // NOTE: This performs steps g. through to k.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        TRY_OR_DISCARD ( for_of_head_state . execute_head ( interpreter ,  global_object ,  next_value ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // l. Let result be the result of evaluating stmt.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  result  =  m_body - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // m. Set the running execution context's LexicalEnvironment to oldEnv.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        interpreter . vm ( ) . running_execution_context ( ) . lexical_environment  =  old_environment ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // NOTE: Since execute does not return a completion we have to have a number of checks here.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // n. If LoopContinues(result, labelSet) is false, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( auto *  exception  =  vm . exception ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // FIXME: We should return the result of AsyncIteratorClose but cannot return completions yet.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // 3. If iteratorKind is async, return ? AsyncIteratorClose(iteratorRecord, status).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            TRY_OR_DISCARD ( async_iterator_close ( * iterator ,  throw_completion ( exception - > value ( ) ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( interpreter . vm ( ) . should_unwind ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( interpreter . vm ( ) . should_unwind_until ( ScopeType : : Continuable ,  m_labels ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // NOTE: In this case LoopContinues is not actually false so we don't perform step 6.n.ii.3.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                interpreter . vm ( ) . stop_unwind ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  if  ( interpreter . vm ( ) . should_unwind_until ( ScopeType : : Breakable ,  m_labels ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                interpreter . vm ( ) . stop_unwind ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // 2. Set status to UpdateEmpty(result, V).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( ! result . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    last_value  =  result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // 3. If iteratorKind is async, return ? AsyncIteratorClose(iteratorRecord, status).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                TRY_OR_DISCARD ( async_iterator_close ( * iterator ,  normal_completion ( last_value ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  last_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // 2. Set status to UpdateEmpty(result, V).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( ! result . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    last_value  =  result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // 3. If iteratorKind is async, return ? AsyncIteratorClose(iteratorRecord, status).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                TRY_OR_DISCARD ( async_iterator_close ( * iterator ,  normal_completion ( last_value ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  last_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // o. If result.[[Value]] is not empty, set V to result.[[Value]].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! result . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            last_value  =  result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  BinaryExpression : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
									
										
										
										
											2020-03-07 19:42:11 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 02:05:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Special case in which we cannot execute the lhs.  RelationalExpression : PrivateIdentifier in ShiftExpression
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //  RelationalExpression : PrivateIdentifier in ShiftExpression, https://tc39.es/ecma262/#sec-relational-operators-runtime-semantics-evaluation
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_op  = =  BinaryOp : : In  & &  is < PrivateIdentifier > ( * m_lhs ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  private_identifier  =  static_cast < PrivateIdentifier  const & > ( * m_lhs ) . string ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  rhs_result  =  m_rhs - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! rhs_result . is_object ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            interpreter . vm ( ) . throw_exception < TypeError > ( global_object ,  ErrorType : : InOperatorWithObject ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto *  private_environment  =  interpreter . vm ( ) . running_execution_context ( ) . private_environment ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( private_environment ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  private_name  =  private_environment - > resolve_private_identifier ( private_identifier ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  Value ( rhs_result . as_object ( ) . private_element_find ( private_name )  ! =  nullptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  lhs_result  =  m_lhs - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-27 15:35:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rhs_result  =  m_rhs - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-27 15:35:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-07 19:42:11 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    switch  ( m_op )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 12:56:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : Addition : 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-19 00:13:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  TRY_OR_DISCARD ( add ( global_object ,  lhs_result ,  rhs_result ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 12:56:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : Subtraction : 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-19 00:13:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  TRY_OR_DISCARD ( sub ( global_object ,  lhs_result ,  rhs_result ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 12:56:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : Multiplication : 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-19 00:13:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  TRY_OR_DISCARD ( mul ( global_object ,  lhs_result ,  rhs_result ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 12:56:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : Division : 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-19 00:13:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  TRY_OR_DISCARD ( div ( global_object ,  lhs_result ,  rhs_result ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-04 21:17:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : Modulo : 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-19 00:13:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  TRY_OR_DISCARD ( mod ( global_object ,  lhs_result ,  rhs_result ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 13:40:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : Exponentiation : 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-19 00:13:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  TRY_OR_DISCARD ( exp ( global_object ,  lhs_result ,  rhs_result ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-24 00:06:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : StrictlyEquals : 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-23 23:43:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  Value ( is_strictly_equal ( lhs_result ,  rhs_result ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-24 00:06:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : StrictlyInequals : 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-23 23:43:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  Value ( ! is_strictly_equal ( lhs_result ,  rhs_result ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-24 00:06:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : LooselyEquals : 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-18 23:46:42 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  Value ( TRY_OR_DISCARD ( is_loosely_equal ( global_object ,  lhs_result ,  rhs_result ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-24 00:06:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : LooselyInequals : 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-18 23:46:42 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  Value ( ! TRY_OR_DISCARD ( is_loosely_equal ( global_object ,  lhs_result ,  rhs_result ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-10 11:35:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : GreaterThan : 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-19 00:13:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  TRY_OR_DISCARD ( greater_than ( global_object ,  lhs_result ,  rhs_result ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:07:08 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : GreaterThanEquals : 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-19 00:13:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  TRY_OR_DISCARD ( greater_than_equals ( global_object ,  lhs_result ,  rhs_result ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-10 11:35:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : LessThan : 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-19 00:13:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  TRY_OR_DISCARD ( less_than ( global_object ,  lhs_result ,  rhs_result ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:07:08 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : LessThanEquals : 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-19 00:13:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  TRY_OR_DISCARD ( less_than_equals ( global_object ,  lhs_result ,  rhs_result ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-10 11:35:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : BitwiseAnd : 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-19 00:13:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  TRY_OR_DISCARD ( bitwise_and ( global_object ,  lhs_result ,  rhs_result ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-10 11:35:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : BitwiseOr : 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-19 00:13:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  TRY_OR_DISCARD ( bitwise_or ( global_object ,  lhs_result ,  rhs_result ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-10 11:35:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : BitwiseXor : 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-19 00:13:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  TRY_OR_DISCARD ( bitwise_xor ( global_object ,  lhs_result ,  rhs_result ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-10 11:35:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : LeftShift : 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-19 00:13:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  TRY_OR_DISCARD ( left_shift ( global_object ,  lhs_result ,  rhs_result ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-10 11:35:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : RightShift : 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-19 00:13:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  TRY_OR_DISCARD ( right_shift ( global_object ,  lhs_result ,  rhs_result ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-23 15:43:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : UnsignedRightShift : 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-19 00:13:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  TRY_OR_DISCARD ( unsigned_right_shift ( global_object ,  lhs_result ,  rhs_result ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-23 16:06:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : In : 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-19 00:13:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  TRY_OR_DISCARD ( in ( global_object ,  lhs_result ,  rhs_result ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-28 16:56:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : InstanceOf : 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-19 00:13:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  TRY_OR_DISCARD ( instance_of ( global_object ,  lhs_result ,  rhs_result ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-08 07:53:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-02-23 20:42:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-08 07:53:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2020-03-08 07:55:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  LogicalExpression : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
									
										
										
										
											2020-03-08 07:55:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  lhs_result  =  m_lhs - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-27 15:35:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-03 19:11:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-08 07:55:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    switch  ( m_op )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  LogicalOp : : And : 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-03 19:11:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( lhs_result . to_boolean ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto  rhs_result  =  m_rhs - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-03 19:11:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-18 00:49:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  rhs_result ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-03 19:11:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-18 00:49:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  lhs_result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  LogicalOp : : Or :  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-03 14:33:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( lhs_result . to_boolean ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-18 00:49:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  lhs_result ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  rhs_result  =  m_rhs - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-03 19:11:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-18 00:49:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  rhs_result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  LogicalOp : : NullishCoalescing : 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-02 16:00:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( lhs_result . is_nullish ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto  rhs_result  =  m_rhs - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-18 00:49:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  rhs_result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  lhs_result ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-07 19:42:11 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-02-23 20:42:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-07 19:42:11 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Reference  Expression : : to_reference ( Interpreter & ,  GlobalObject & )  const  
						 
					
						
							
								
									
										
										
										
											2020-04-27 12:10:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 21:54:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Reference  Identifier : : to_reference ( Interpreter &  interpreter ,  GlobalObject & )  const  
						 
					
						
							
								
									
										
										
										
											2020-04-27 12:37:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:06:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_cached_environment_coordinate . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto *  environment  =  interpreter . vm ( ) . running_execution_context ( ) . lexical_environment ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( size_t  i  =  0 ;  i  <  m_cached_environment_coordinate - > hops ;  + + i ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            environment  =  environment - > outer_environment ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( environment ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( environment - > is_declarative_environment ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 20:13:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ! environment - > is_permanently_screwed_by_eval ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:06:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  Reference  {  * environment ,  string ( ) ,  interpreter . vm ( ) . in_strict_mode ( ) ,  m_cached_environment_coordinate  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 20:13:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:06:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_cached_environment_coordinate  =  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 20:13:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:06:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  reference  =  interpreter . vm ( ) . resolve_binding ( string ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( reference . environment_coordinate ( ) . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 20:12:32 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_cached_environment_coordinate  =  reference . environment_coordinate ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:06:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  reference ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-27 12:37:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Reference  MemberExpression : : to_reference ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
									
										
										
										
											2020-04-27 12:10:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-07-03 00:20:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 13.3.7.1 Runtime Semantics: Evaluation
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // SuperProperty : super [ Expression ]
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // SuperProperty : super . IdentifierName
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // https://tc39.es/ecma262/#sec-super-keyword-runtime-semantics-evaluation
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( is < SuperExpression > ( object ( ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 1. Let env be GetThisEnvironment().
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  environment  =  get_this_environment ( interpreter . vm ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 2. Let actualThis be ? env.GetThisBinding().
 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-09 16:52:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  actual_this  =  TRY_OR_DISCARD ( environment . get_this_binding ( global_object ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 00:20:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-24 16:06:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        PropertyKey  property_key ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 00:20:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( is_computed ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // SuperProperty : super [ Expression ]
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // 3. Let propertyNameReference be the result of evaluating Expression.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // 4. Let propertyNameValue be ? GetValue(propertyNameReference).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  property_name_value  =  m_property - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // 5. Let propertyKey be ? ToPropertyKey(propertyNameValue).
 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-16 22:20:23 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            property_key  =  TRY_OR_DISCARD ( property_name_value . to_property_key ( global_object ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 00:20:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // SuperProperty : super . IdentifierName
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // 3. Let propertyKey be StringValue of IdentifierName.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            VERIFY ( is < Identifier > ( property ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            property_key  =  static_cast < Identifier  const & > ( property ( ) ) . string ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 6. If the code matched by this SuperProperty is strict mode code, let strict be true; else let strict be false.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        bool  strict  =  interpreter . vm ( ) . in_strict_mode ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 7. Return ? MakeSuperPropertyReference(actualThis, propertyKey, strict).
 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-21 21:52:09 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  TRY_OR_DISCARD ( make_super_property_reference ( global_object ,  actual_this ,  property_key ,  strict ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 00:20:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  base_reference  =  m_object - > to_reference ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Value  base_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( base_reference . is_valid_reference ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-02 18:49:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        base_value  =  TRY_OR_DISCARD ( base_reference . get_value ( global_object ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        base_value  =  m_object - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-28 17:48:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-27 12:10:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    VERIFY ( ! base_value . is_empty ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-25 16:27:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Rewrite most of Object for spec compliance :^)
This is a huge patch, I know. In hindsight this perhaps could've been
done slightly more incremental, but I started and then fixed everything
until it worked, and here we are. I tried splitting of some completely
unrelated changes into separate commits, however. Anyway.
This is a rewrite of most of Object, and by extension large parts of
Array, Proxy, Reflect, String, TypedArray, and some other things.
What we already had worked fine for about 90% of things, but getting the
last 10% right proved to be increasingly difficult with the current code
that sort of grew organically and is only very loosely based on the
spec - this became especially obvious when we started fixing a large
number of test262 failures.
Key changes include:
- 1:1 matching function names and parameters of all object-related
  functions, to avoid ambiguity. Previously we had things like put(),
  which the spec doesn't have - as a result it wasn't always clear which
  need to be used.
- Better separation between object abstract operations and internal
  methods - the former are always the same, the latter can be overridden
  (and are therefore virtual). The internal methods (i.e. [[Foo]] in the
  spec) are now prefixed with 'internal_' for clarity - again, it was
  previously not always clear which AO a certain method represents,
  get() could've been both Get and [[Get]] (I don't know which one it
  was closer to right now).
  Note that some of the old names have been kept until all code relying
  on them is updated, but they are now simple wrappers around the
  closest matching standard abstract operation.
- Simplifications of the storage layer: functions that write values to
  storage are now prefixed with 'storage_' to make their purpose clear,
  and as they are not part of the spec they should not contain any steps
  specified by it. Much functionality is now covered by the layers above
  it and was removed (e.g. handling of accessors, attribute checks).
- PropertyAttributes has been greatly simplified, and is being replaced
  by PropertyDescriptor - a concept similar to the current
  implementation, but more aligned with the actual spec. See the commit
  message of the previous commit where it was introduced for details.
- As a bonus, and since I had to look at the spec a whole lot anyway, I
  introduced more inline comments with the exact steps from the spec -
  this makes it super easy to verify correctness.
- East-const all the things.
As a result of all of this, things are much more correct but a bit
slower now. Retaining speed wasn't a consideration at all, I have done
no profiling of the new code - there might be low hanging fruits, which
we can then harvest separately.
Special thanks to Idan for helping me with this by tracking down bugs,
updating everything outside of LibJS to work with these changes (LibWeb,
Spreadsheet, HackStudio), as well as providing countless patches to fix
regressions I introduced - there still are very few (we got it down to
5), but we also get many new passing test262 tests in return. :^)
Co-authored-by: Idan Horowitz <idan.horowitz@gmail.com>
											 
										 
										
											2021-07-04 18:14:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // From here on equivalent to
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 13.3.4 EvaluatePropertyAccessWithIdentifierKey ( baseValue, identifierName, strict ), https://tc39.es/ecma262/#sec-evaluate-property-access-with-identifier-key
 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-24 16:01:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    PropertyKey  property_name ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( is_computed ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Weird order which I can't quite find from the specs.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  value  =  m_property - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  Reference  { } ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Rewrite most of Object for spec compliance :^)
This is a huge patch, I know. In hindsight this perhaps could've been
done slightly more incremental, but I started and then fixed everything
until it worked, and here we are. I tried splitting of some completely
unrelated changes into separate commits, however. Anyway.
This is a rewrite of most of Object, and by extension large parts of
Array, Proxy, Reflect, String, TypedArray, and some other things.
What we already had worked fine for about 90% of things, but getting the
last 10% right proved to be increasingly difficult with the current code
that sort of grew organically and is only very loosely based on the
spec - this became especially obvious when we started fixing a large
number of test262 failures.
Key changes include:
- 1:1 matching function names and parameters of all object-related
  functions, to avoid ambiguity. Previously we had things like put(),
  which the spec doesn't have - as a result it wasn't always clear which
  need to be used.
- Better separation between object abstract operations and internal
  methods - the former are always the same, the latter can be overridden
  (and are therefore virtual). The internal methods (i.e. [[Foo]] in the
  spec) are now prefixed with 'internal_' for clarity - again, it was
  previously not always clear which AO a certain method represents,
  get() could've been both Get and [[Get]] (I don't know which one it
  was closer to right now).
  Note that some of the old names have been kept until all code relying
  on them is updated, but they are now simple wrappers around the
  closest matching standard abstract operation.
- Simplifications of the storage layer: functions that write values to
  storage are now prefixed with 'storage_' to make their purpose clear,
  and as they are not part of the spec they should not contain any steps
  specified by it. Much functionality is now covered by the layers above
  it and was removed (e.g. handling of accessors, attribute checks).
- PropertyAttributes has been greatly simplified, and is being replaced
  by PropertyDescriptor - a concept similar to the current
  implementation, but more aligned with the actual spec. See the commit
  message of the previous commit where it was introduced for details.
- As a bonus, and since I had to look at the spec a whole lot anyway, I
  introduced more inline comments with the exact steps from the spec -
  this makes it super easy to verify correctness.
- East-const all the things.
As a result of all of this, things are much more correct but a bit
slower now. Retaining speed wasn't a consideration at all, I have done
no profiling of the new code - there might be low hanging fruits, which
we can then harvest separately.
Special thanks to Idan for helping me with this by tracking down bugs,
updating everything outside of LibJS to work with these changes (LibWeb,
Spreadsheet, HackStudio), as well as providing countless patches to fix
regressions I introduced - there still are very few (we got it down to
5), but we also get many new passing test262 tests in return. :^)
Co-authored-by: Idan Horowitz <idan.horowitz@gmail.com>
											 
										 
										
											2021-07-04 18:14:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        TRY_OR_DISCARD ( require_object_coercible ( global_object ,  base_value ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-25 16:27:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        VERIFY ( ! value . is_empty ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-24 16:01:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        property_name  =  PropertyKey : : from_value ( global_object ,  value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  Reference  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-12 22:45:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else  if  ( is < PrivateIdentifier > ( * m_property ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  private_identifier  =  static_cast < PrivateIdentifier  const & > ( * m_property ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  make_private_reference ( interpreter . vm ( ) ,  base_value ,  private_identifier . string ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        property_name  =  verify_cast < Identifier > ( * m_property ) . string ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        TRY_OR_DISCARD ( require_object_coercible ( global_object ,  base_value ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-27 12:10:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! property_name . is_valid ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-25 16:27:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  Reference  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Rewrite most of Object for spec compliance :^)
This is a huge patch, I know. In hindsight this perhaps could've been
done slightly more incremental, but I started and then fixed everything
until it worked, and here we are. I tried splitting of some completely
unrelated changes into separate commits, however. Anyway.
This is a rewrite of most of Object, and by extension large parts of
Array, Proxy, Reflect, String, TypedArray, and some other things.
What we already had worked fine for about 90% of things, but getting the
last 10% right proved to be increasingly difficult with the current code
that sort of grew organically and is only very loosely based on the
spec - this became especially obvious when we started fixing a large
number of test262 failures.
Key changes include:
- 1:1 matching function names and parameters of all object-related
  functions, to avoid ambiguity. Previously we had things like put(),
  which the spec doesn't have - as a result it wasn't always clear which
  need to be used.
- Better separation between object abstract operations and internal
  methods - the former are always the same, the latter can be overridden
  (and are therefore virtual). The internal methods (i.e. [[Foo]] in the
  spec) are now prefixed with 'internal_' for clarity - again, it was
  previously not always clear which AO a certain method represents,
  get() could've been both Get and [[Get]] (I don't know which one it
  was closer to right now).
  Note that some of the old names have been kept until all code relying
  on them is updated, but they are now simple wrappers around the
  closest matching standard abstract operation.
- Simplifications of the storage layer: functions that write values to
  storage are now prefixed with 'storage_' to make their purpose clear,
  and as they are not part of the spec they should not contain any steps
  specified by it. Much functionality is now covered by the layers above
  it and was removed (e.g. handling of accessors, attribute checks).
- PropertyAttributes has been greatly simplified, and is being replaced
  by PropertyDescriptor - a concept similar to the current
  implementation, but more aligned with the actual spec. See the commit
  message of the previous commit where it was introduced for details.
- As a bonus, and since I had to look at the spec a whole lot anyway, I
  introduced more inline comments with the exact steps from the spec -
  this makes it super easy to verify correctness.
- East-const all the things.
As a result of all of this, things are much more correct but a bit
slower now. Retaining speed wasn't a consideration at all, I have done
no profiling of the new code - there might be low hanging fruits, which
we can then harvest separately.
Special thanks to Idan for helping me with this by tracking down bugs,
updating everything outside of LibJS to work with these changes (LibWeb,
Spreadsheet, HackStudio), as well as providing countless patches to fix
regressions I introduced - there still are very few (we got it down to
5), but we also get many new passing test262 tests in return. :^)
Co-authored-by: Idan Horowitz <idan.horowitz@gmail.com>
											 
										 
										
											2021-07-04 18:14:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  strict  =  interpreter . vm ( ) . in_strict_mode ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  Reference  {  base_value ,  move ( property_name ) ,  { } ,  strict  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-27 12:10:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  UnaryExpression : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
									
										
										
										
											2020-03-08 23:27:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-27 18:36:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto &  vm  =  interpreter . vm ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-26 13:53:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_op  = =  UnaryOp : : Delete )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  reference  =  m_lhs - > to_reference ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-26 13:53:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-02 18:38:51 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  Value ( TRY_OR_DISCARD ( reference . delete_ ( global_object ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-26 13:53:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-02 23:26:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Value  lhs_result ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-01 19:34:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_op  = =  UnaryOp : : Typeof  & &  is < Identifier > ( * m_lhs ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  reference  =  m_lhs - > to_reference ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-02 23:26:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-02 18:49:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( reference . is_unresolvable ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-25 16:27:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            lhs_result  =  js_undefined ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-02 18:49:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            lhs_result  =  TRY_OR_DISCARD ( reference . get_value ( global_object ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        VERIFY ( ! lhs_result . is_empty ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-02 23:26:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        lhs_result  =  m_lhs - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-02 23:26:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-08 23:27:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    switch  ( m_op )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 20:43:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  UnaryOp : : BitwiseNot : 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-19 00:13:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  TRY_OR_DISCARD ( bitwise_not ( global_object ,  lhs_result ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-09 19:04:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  UnaryOp : : Not : 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-10 11:08:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  Value ( ! lhs_result . to_boolean ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 17:58:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  UnaryOp : : Plus : 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-19 00:13:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  TRY_OR_DISCARD ( unary_plus ( global_object ,  lhs_result ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 17:58:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  UnaryOp : : Minus : 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-19 00:13:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  TRY_OR_DISCARD ( unary_minus ( global_object ,  lhs_result ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-18 06:33:32 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  UnaryOp : : Typeof : 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-02 20:33:03 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  js_string ( vm ,  lhs_result . typeof ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-15 17:55:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  UnaryOp : : Void : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  js_undefined ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-26 13:53:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  UnaryOp : : Delete : 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-23 20:42:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-08 23:27:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-02-23 20:42:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-08 23:27:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 19:30:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  SuperExpression : : execute ( Interpreter & ,  GlobalObject & )  const  
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-07-02 19:30:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // The semantics for SuperExpression are handled in CallExpression and SuperCall.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-23 20:42:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:09:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  ClassElement : : execute ( Interpreter & ,  GlobalObject & )  const  
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:09:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Note: The semantics of class element are handled in class_element_evaluation
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-12 22:45:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  ThrowCompletionOr < ClassElement : : ClassElementName >  class_key_to_property_name ( Interpreter &  interpreter ,  GlobalObject &  global_object ,  Expression  const &  key )  
						 
					
						
							
								
									
										
										
										
											2021-08-28 17:11:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-10-12 22:45:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( is < PrivateIdentifier > ( key ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  private_identifier  =  static_cast < PrivateIdentifier  const & > ( key ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto *  private_environment  =  interpreter . vm ( ) . running_execution_context ( ) . private_environment ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( private_environment ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  ClassElement : : ClassElementName  {  private_environment - > resolve_private_identifier ( private_identifier . string ( ) )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:09:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  prop_key  =  key . execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( auto *  exception  =  interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  throw_completion ( exception - > value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( prop_key . is_object ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        prop_key  =  TRY ( prop_key . to_primitive ( global_object ,  Value : : PreferredType : : String ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-24 16:01:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  property_key  =  PropertyKey : : from_value ( global_object ,  prop_key ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:09:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( auto *  exception  =  interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  throw_completion ( exception - > value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-12 22:45:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  ClassElement : : ClassElementName  {  property_key  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:09:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// 15.4.5 Runtime Semantics: MethodDefinitionEvaluation, https://tc39.es/ecma262/#sec-runtime-semantics-methoddefinitionevaluation
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								ThrowCompletionOr < ClassElement : : ClassValue >  ClassMethod : : class_element_evaluation ( Interpreter &  interpreter ,  GlobalObject &  global_object ,  Object &  target )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  property_key  =  TRY ( class_key_to_property_name ( interpreter ,  global_object ,  * m_key ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  method_value  =  m_function - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( auto *  exception  =  interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  throw_completion ( exception - > value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  method_function  =  static_cast < ECMAScriptFunctionObject & > ( method_value . as_function ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    method_function . set_home_object ( & target ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-12 22:45:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  set_function_name  =  [ & ] ( String  prefix  =  " " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  property_name  =  property_key . visit ( 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-24 16:01:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            [ & ] ( PropertyKey  const &  property_name )  - >  String  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-12 22:45:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  ( property_name . is_symbol ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    auto  description  =  property_name . as_symbol ( ) - > description ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( description . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        return  " " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    return  String : : formatted ( " [{}] " ,  description ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    return  property_name . to_string ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            [ & ] ( PrivateName  const &  private_name )  - >  String  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  private_name . description ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        update_function_name ( method_value ,  String : : formatted ( " {}{}{} " ,  prefix ,  prefix . is_empty ( )  ?  " "  :  "   " ,  property_name ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:09:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-24 16:01:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( property_key . has < PropertyKey > ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  property_name  =  property_key . get < PropertyKey > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-12 22:45:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        switch  ( kind ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  ClassMethod : : Kind : : Method : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            set_function_name ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            TRY ( target . define_property_or_throw ( property_name ,  {  . value  =  method_value ,  . writable  =  true ,  . enumerable  =  false ,  . configurable  =  true  } ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  ClassMethod : : Kind : : Getter : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            set_function_name ( " get " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            TRY ( target . define_property_or_throw ( property_name ,  {  . get  =  & method_function ,  . enumerable  =  true ,  . configurable  =  true  } ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  ClassMethod : : Kind : : Setter : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            set_function_name ( " set " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            TRY ( target . define_property_or_throw ( property_name ,  {  . set  =  & method_function ,  . enumerable  =  true ,  . configurable  =  true  } ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:09:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-12 22:45:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  ClassValue  {  normal_completion ( { } )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  private_name  =  property_key . get < PrivateName > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        switch  ( kind ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  Kind : : Method : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            set_function_name ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  ClassValue  {  PrivateElement  {  private_name ,  PrivateElement : : Kind : : Method ,  method_value  }  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  Kind : : Getter : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            set_function_name ( " get " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  ClassValue  {  PrivateElement  {  private_name ,  PrivateElement : : Kind : : Accessor ,  Accessor : : create ( interpreter . vm ( ) ,  & method_function ,  nullptr )  }  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  Kind : : Setter : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            set_function_name ( " set " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  ClassValue  {  PrivateElement  {  private_name ,  PrivateElement : : Kind : : Accessor ,  Accessor : : create ( interpreter . vm ( ) ,  nullptr ,  & method_function )  }  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:09:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-13 19:59:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// We use this class to mimic  Initializer : = AssignmentExpression of
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// 10.2.1.3 Runtime Semantics: EvaluateBody, https://tc39.es/ecma262/#sec-runtime-semantics-evaluatebody
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								class  ClassFieldInitializerStatement  :  public  Statement  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								public :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ClassFieldInitializerStatement ( SourceRange  source_range ,  NonnullRefPtr < Expression >  expression ,  FlyString  field_name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        :  Statement ( source_range ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ,  m_expression ( move ( expression ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ,  m_class_field_identifier_name ( move ( field_name ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Value  execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  override 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( interpreter . vm ( ) . argument_count ( )  = =  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( ! m_class_field_identifier_name . is_empty ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  TRY_OR_DISCARD ( interpreter . vm ( ) . named_evaluation_if_anonymous_function ( global_object ,  m_expression ,  m_class_field_identifier_name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    void  dump ( int )  const  override 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // This should not be dumped as it is never part of an actual AST.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								private :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    NonnullRefPtr < Expression >  m_expression ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    FlyString  m_class_field_identifier_name ;  // [[ClassFieldIdentifierName]]
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:09:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// 15.7.10 Runtime Semantics: ClassFieldDefinitionEvaluation, https://tc39.es/ecma262/#sec-runtime-semantics-classfielddefinitionevaluation
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								ThrowCompletionOr < ClassElement : : ClassValue >  ClassField : : class_element_evaluation ( Interpreter &  interpreter ,  GlobalObject &  global_object ,  Object &  target )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  property_key  =  TRY ( class_key_to_property_name ( interpreter ,  global_object ,  * m_key ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ECMAScriptFunctionObject *  initializer  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_initializer )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  copy_initializer  =  m_initializer ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-12 22:45:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  name  =  property_key . visit ( 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-24 16:01:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            [ & ] ( PropertyKey  const &  property_name )  - >  String  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-12 22:45:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  property_name . is_number ( )  ?  property_name . to_string ( )  :  property_name . to_string_or_symbol ( ) . to_display_string ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            [ & ] ( PrivateName  const &  private_name )  - >  String  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  private_name . description ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-13 19:59:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:09:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // FIXME: A potential optimization is not creating the functions here since these are never directly accessible.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-13 19:59:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  function_code  =  create_ast_node < ClassFieldInitializerStatement > ( m_initializer - > source_range ( ) ,  copy_initializer . release_nonnull ( ) ,  name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        initializer  =  ECMAScriptFunctionObject : : create ( interpreter . global_object ( ) ,  String : : empty ( ) ,  * function_code ,  { } ,  0 ,  interpreter . lexical_environment ( ) ,  interpreter . vm ( ) . running_execution_context ( ) . private_environment ,  FunctionKind : : Regular ,  true ,  false ,  m_contains_direct_call_to_eval ,  false ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:09:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        initializer - > set_home_object ( & target ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  ClassValue  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ClassFieldDefinition  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            property_key , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            initializer , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 17:11:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-12 22:45:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  Optional < FlyString >  nullopt_or_private_identifier_description ( Expression  const &  expression )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( is < PrivateIdentifier > ( expression ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  static_cast < PrivateIdentifier  const & > ( expression ) . string ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Optional < FlyString >  ClassField : : private_bound_identifier ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  nullopt_or_private_identifier_description ( * m_key ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Optional < FlyString >  ClassMethod : : private_bound_identifier ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  nullopt_or_private_identifier_description ( * m_key ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-20 21:29:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// 15.7.11 Runtime Semantics: ClassStaticBlockDefinitionEvaluation, https://tc39.es/ecma262/#sec-runtime-semantics-classstaticblockdefinitionevaluation
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								ThrowCompletionOr < ClassElement : : ClassValue >  StaticInitializer : : class_element_evaluation ( Interpreter &  interpreter ,  GlobalObject &  global_object ,  Object &  home_object )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto *  lexical_environment  =  interpreter . vm ( ) . running_execution_context ( ) . lexical_environment ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-11 20:29:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto *  private_scope  =  interpreter . vm ( ) . running_execution_context ( ) . private_environment ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-20 21:29:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Note: The function bodyFunction is never directly accessible to ECMAScript code.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-11 20:29:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto *  body_function  =  ECMAScriptFunctionObject : : create ( global_object ,  " " ,  * m_function_body ,  { } ,  0 ,  lexical_environment ,  private_scope ,  FunctionKind : : Regular ,  true ,  false ,  m_contains_direct_call_to_eval ,  false ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-20 21:29:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    body_function - > set_home_object ( & home_object ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  ClassValue  {  normal_completion ( body_function )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  ClassExpression : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // FIXME: Set value.[[SourceText]] to the source text matched by ClassExpression.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  TRY_OR_DISCARD ( class_definition_evaluation ( interpreter ,  global_object ,  m_name ,  m_name . is_null ( )  ?  " "  :  m_name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Value  ClassDeclaration : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  name  =  m_class_expression - > name ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY ( ! name . is_empty ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  class_constructor  =  TRY_OR_DISCARD ( m_class_expression - > class_definition_evaluation ( interpreter ,  global_object ,  name ,  name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( interpreter . lexical_environment ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-09 19:16:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        MUST ( interpreter . lexical_environment ( ) - > initialize_binding ( global_object ,  name ,  class_constructor ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  reference  =  interpreter . vm ( ) . resolve_binding ( name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-02 19:20:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        TRY_OR_DISCARD ( reference . put_value ( global_object ,  class_constructor ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// 15.7.14 Runtime Semantics: ClassDefinitionEvaluation, https://tc39.es/ecma262/#sec-runtime-semantics-classdefinitionevaluation
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								ThrowCompletionOr < Value >  ClassExpression : : class_definition_evaluation ( Interpreter &  interpreter ,  GlobalObject &  global_object ,  FlyString  const &  binding_name ,  FlyString  const &  class_name )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-10-13 23:49:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto &  vm  =  interpreter . vm ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto *  environment  =  vm . lexical_environment ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY ( environment ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto *  class_scope  =  new_declarative_environment ( * environment ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:09:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // We might not set the lexical environment but we always want to restore it eventually.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ArmedScopeGuard  restore_environment  =  [ & ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        vm . running_execution_context ( ) . lexical_environment  =  environment ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:09:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! binding_name . is_null ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        MUST ( class_scope - > create_immutable_binding ( global_object ,  binding_name ,  true ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-11 20:29:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto *  outer_private_environment  =  vm . running_execution_context ( ) . private_environment ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto *  class_private_environment  =  new_private_environment ( vm ,  outer_private_environment ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-12 22:45:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto  const &  element  :  m_elements )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  opt_private_name  =  element . private_bound_identifier ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( opt_private_name . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            class_private_environment - > add_private_name ( { } ,  opt_private_name . release_value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:09:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto *  proto_parent  =  vm . current_realm ( ) - > global_object ( ) . object_prototype ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:09:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto *  constructor_parent  =  vm . current_realm ( ) - > global_object ( ) . function_prototype ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:09:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! m_super_class . is_null ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        vm . running_execution_context ( ) . lexical_environment  =  class_scope ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:09:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // Note: Since our execute does evaluation and GetValue in once we must check for a valid reference first
 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:09:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        Value  super_class ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:09:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  reference  =  m_super_class - > to_reference ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( auto *  exception  =  interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  throw_completion ( exception - > value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:09:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( reference . is_valid_reference ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-02 18:49:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            super_class  =  TRY ( reference . get_value ( global_object ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:09:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            super_class  =  m_super_class - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( auto *  exception  =  interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  throw_completion ( exception - > value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        vm . running_execution_context ( ) . lexical_environment  =  environment ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:09:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( super_class . is_null ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            proto_parent  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  if  ( ! super_class . is_constructor ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  vm . throw_completion < TypeError > ( global_object ,  ErrorType : : ClassExtendsValueNotAConstructorOrNull ,  super_class . to_string_without_side_effects ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  super_class_prototype  =  TRY ( super_class . get ( global_object ,  vm . names . prototype ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! super_class_prototype . is_null ( )  & &  ! super_class_prototype . is_object ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  vm . throw_completion < TypeError > ( global_object ,  ErrorType : : ClassExtendsValueInvalidPrototype ,  super_class_prototype . to_string_without_side_effects ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:09:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( super_class_prototype . is_null ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                proto_parent  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                proto_parent  =  & super_class_prototype . as_object ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:09:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            constructor_parent  =  & super_class . as_object ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:09:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto *  prototype  =  Object : : create ( global_object ,  proto_parent ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY ( prototype ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:09:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    vm . running_execution_context ( ) . lexical_environment  =  class_scope ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-11 20:29:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    vm . running_execution_context ( ) . private_environment  =  class_private_environment ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ScopeGuard  restore_private_environment  =  [ & ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        vm . running_execution_context ( ) . private_environment  =  outer_private_environment ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-17 01:32:08 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:09:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // FIXME: Step 14.a is done in the parser. But maybe it shouldn't?
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Value  class_constructor_value  =  m_constructor - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( auto *  exception  =  interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  throw_completion ( exception - > value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:09:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    update_function_name ( class_constructor_value ,  class_name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:09:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    VERIFY ( class_constructor_value . is_function ( )  & &  is < ECMAScriptFunctionObject > ( class_constructor_value . as_function ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto *  class_constructor  =  static_cast < ECMAScriptFunctionObject * > ( & class_constructor_value . as_function ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    class_constructor - > set_home_object ( prototype ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    class_constructor - > set_is_class_constructor ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    class_constructor - > define_direct_property ( vm . names . prototype ,  prototype ,  Attribute : : Writable ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    TRY ( class_constructor - > internal_set_prototype_of ( constructor_parent ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 17:11:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:09:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! m_super_class . is_null ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        class_constructor - > set_constructor_kind ( ECMAScriptFunctionObject : : ConstructorKind : : Derived ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 17:11:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:09:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    prototype - > define_direct_property ( vm . names . constructor ,  class_constructor ,  Attribute : : Writable  |  Attribute : : Configurable ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 17:11:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-20 21:29:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    using  StaticElement  =  Variant < ClassElement : : ClassFieldDefinition ,  ECMAScriptFunctionObject * > ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-12 22:45:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Vector < PrivateElement >  static_private_methods ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Vector < PrivateElement >  instance_private_methods ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:09:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Vector < ClassElement : : ClassFieldDefinition >  instance_fields ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-20 21:29:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Vector < StaticElement >  static_elements ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 17:11:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:09:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto  const &  element  :  m_elements )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Note: All ClassElementEvaluation start with evaluating the name (or we fake it).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  element_value  =  TRY ( element . class_element_evaluation ( interpreter ,  global_object ,  element . is_static ( )  ?  * class_constructor  :  * prototype ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-12 22:45:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( element_value . has < PrivateElement > ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto &  container  =  element . is_static ( )  ?  static_private_methods  :  instance_private_methods ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto &  private_element  =  element_value . get < PrivateElement > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  added_to_existing  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // FIXME: We can skip this loop in most cases.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for  ( auto &  existing  :  container )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( existing . key  = =  private_element . key )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    VERIFY ( existing . kind  = =  PrivateElement : : Kind : : Accessor ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    VERIFY ( private_element . kind  = =  PrivateElement : : Kind : : Accessor ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    auto &  accessor  =  private_element . value . as_accessor ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( ! accessor . getter ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        existing . value . as_accessor ( ) . set_setter ( accessor . setter ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        existing . value . as_accessor ( ) . set_getter ( accessor . getter ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    added_to_existing  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! added_to_existing ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                container . append ( move ( element_value . get < PrivateElement > ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  if  ( auto *  class_field_definition_ptr  =  element_value . get_pointer < ClassElement : : ClassFieldDefinition > ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:09:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( element . is_static ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-20 21:29:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                static_elements . append ( move ( * class_field_definition_ptr ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:09:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                instance_fields . append ( move ( * class_field_definition_ptr ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-20 21:29:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  if  ( element . class_element_kind ( )  = =  ClassElement : : ElementKind : : StaticInitializer )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // We use Completion to hold the ClassStaticBlockDefinition Record.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            VERIFY ( element_value . has < Completion > ( )  & &  element_value . get < Completion > ( ) . has_value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  element_object  =  element_value . get < Completion > ( ) . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            VERIFY ( is < ECMAScriptFunctionObject > ( element_object . as_object ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            static_elements . append ( static_cast < ECMAScriptFunctionObject * > ( & element_object . as_object ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 17:11:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    vm . running_execution_context ( ) . lexical_environment  =  environment ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    restore_environment . disarm ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:09:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! binding_name . is_null ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-09 19:16:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        MUST ( class_scope - > initialize_binding ( global_object ,  binding_name ,  class_constructor ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:09:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto &  field  :  instance_fields ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        class_constructor - > add_field ( field . name ,  field . initializer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-12 22:45:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto &  private_method  :  instance_private_methods ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        class_constructor - > add_private_method ( private_method ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto &  method  :  static_private_methods ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        class_constructor - > private_method_or_accessor_add ( move ( method ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-20 21:29:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto &  element  :  static_elements )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        TRY ( element . visit ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            [ & ] ( ClassElement : : ClassFieldDefinition  const &  field )  - >  ThrowCompletionOr < void >  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-12 22:45:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  TRY ( class_constructor - > define_field ( field . name ,  field . initializer ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-20 21:29:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            [ & ] ( ECMAScriptFunctionObject *  static_block_function )  - >  ThrowCompletionOr < void >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // We discard any value returned here.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                TRY ( call ( global_object ,  static_block_function ,  class_constructor_value ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:09:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  Value ( class_constructor ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-07 19:42:11 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								static  void  print_indent ( int  indent )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    out ( " {} " ,  String : : repeated ( '   ' ,  indent  *  2 ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-07 19:42:11 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  ASTNode : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    outln ( " {} " ,  class_name ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-07 19:42:11 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  ScopeNode : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ASTNode : : dump ( indent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! m_lexical_declarations . is_empty ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-13 16:42:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        print_indent ( indent  +  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        outln ( " (Lexical declarations) " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( auto &  declaration  :  m_lexical_declarations ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            declaration . dump ( indent  +  2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-13 16:42:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! m_var_declarations . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        print_indent ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        outln ( " (Variable declarations) " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( auto &  declaration  :  m_var_declarations ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            declaration . dump ( indent  +  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! m_functions_hoistable_with_annexB_extension . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        print_indent ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        outln ( " (Hoisted functions via annexB extension) " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( auto &  declaration  :  m_functions_hoistable_with_annexB_extension ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            declaration . dump ( indent  +  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-13 16:42:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! m_children . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        print_indent ( indent  +  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        outln ( " (Children) " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-13 16:42:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        for  ( auto &  child  :  children ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            child . dump ( indent  +  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-07 19:42:11 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  BinaryExpression : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-03-07 23:16:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  char *  op_string  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    switch  ( m_op )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 12:56:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : Addition : 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-07 23:16:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        op_string  =  " + " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 12:56:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : Subtraction : 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-07 23:16:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        op_string  =  " - " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 12:56:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : Multiplication : 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:04:52 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        op_string  =  " * " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 12:56:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : Division : 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:04:52 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        op_string  =  " / " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-04 21:17:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : Modulo : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        op_string  =  " % " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 13:40:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : Exponentiation : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        op_string  =  " ** " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-24 00:06:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : StrictlyEquals : 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-08 07:53:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        op_string  =  " === " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-24 00:06:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : StrictlyInequals : 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-08 23:27:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        op_string  =  " !== " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-24 00:06:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : LooselyEquals : 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-16 00:23:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        op_string  =  " == " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-24 00:06:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : LooselyInequals : 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-16 00:23:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        op_string  =  " != " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-10 11:35:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : GreaterThan : 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-08 23:27:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        op_string  =  " > " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:07:08 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : GreaterThanEquals : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        op_string  =  " >= " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-10 11:35:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : LessThan : 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-08 23:27:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        op_string  =  " < " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:07:08 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : LessThanEquals : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        op_string  =  " <= " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-10 11:35:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : BitwiseAnd : 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-08 23:27:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        op_string  =  " & " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-10 11:35:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : BitwiseOr : 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-08 23:27:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        op_string  =  " | " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-10 11:35:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : BitwiseXor : 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-08 23:27:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        op_string  =  " ^ " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-10 11:35:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : LeftShift : 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-08 23:27:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        op_string  =  " << " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-10 11:35:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : RightShift : 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-08 23:27:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        op_string  =  " >> " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-23 15:43:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : UnsignedRightShift : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        op_string  =  " >>> " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-23 16:06:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : In : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        op_string  =  " in " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-28 16:56:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : InstanceOf : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        op_string  =  " instanceof " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-08 07:53:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    outln ( " {} " ,  class_name ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-08 07:53:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_lhs - > dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent  +  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    outln ( " {} " ,  op_string ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-08 07:53:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_rhs - > dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-08 07:55:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  LogicalExpression : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  char *  op_string  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    switch  ( m_op )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  LogicalOp : : And : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        op_string  =  " && " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  LogicalOp : : Or : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        op_string  =  " || " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-18 00:49:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  LogicalOp : : NullishCoalescing : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        op_string  =  " ?? " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-07 23:16:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    outln ( " {} " ,  class_name ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-07 19:42:11 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    m_lhs - > dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-07 23:16:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    print_indent ( indent  +  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    outln ( " {} " ,  op_string ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-07 19:42:11 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    m_rhs - > dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-08 23:27:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  UnaryExpression : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  char *  op_string  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    switch  ( m_op )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 20:43:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  UnaryOp : : BitwiseNot : 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-08 23:27:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        op_string  =  " ~ " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-09 19:04:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  UnaryOp : : Not : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        op_string  =  " ! " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 17:58:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  UnaryOp : : Plus : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        op_string  =  " + " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  UnaryOp : : Minus : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        op_string  =  " - " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-18 06:33:32 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  UnaryOp : : Typeof : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        op_string  =  " typeof  " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-15 17:55:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  UnaryOp : : Void : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        op_string  =  " void  " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-26 13:53:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  UnaryOp : : Delete : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        op_string  =  " delete  " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-08 23:27:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    outln ( " {} " ,  class_name ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-08 23:27:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    print_indent ( indent  +  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    outln ( " {} " ,  op_string ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-08 23:27:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_lhs - > dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-07 19:42:11 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								void  CallExpression : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-04-06 20:24:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    print_indent ( indent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-01 19:34:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( is < NewExpression > ( * this ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        outln ( " CallExpression [new] " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        outln ( " CallExpression " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:02:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_callee - > dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 19:34:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto &  argument  :  m_arguments ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-05 22:36:24 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        argument . value - > dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-07 19:42:11 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 19:30:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  SuperCall : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    outln ( " SuperCall " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto &  argument  :  m_arguments ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        argument . value - > dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  ClassDeclaration : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ASTNode : : dump ( indent ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_class_expression - > dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  ClassDeclaration : : for_each_bound_name ( IteratorOrVoidFunction < FlyString  const & >  callback )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! m_class_expression - > name ( ) . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        callback ( m_class_expression - > name ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  ClassExpression : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    outln ( " ClassExpression:  \" {} \" " ,  m_name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    outln ( " (Constructor) " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_constructor - > dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! m_super_class . is_null ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        print_indent ( indent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        outln ( " (Super Class) " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_super_class - > dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:09:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    outln ( " (Elements) " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto &  method  :  m_elements ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        method . dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  ClassMethod : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ASTNode : : dump ( indent ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    outln ( " (Key) " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_key - > dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  char *  kind_string  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    switch  ( m_kind )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  Kind : : Method : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        kind_string  =  " Method " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  Kind : : Getter : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        kind_string  =  " Getter " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  Kind : : Setter : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        kind_string  =  " Setter " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    outln ( " Kind: {} " ,  kind_string ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:09:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    outln ( " Static: {} " ,  is_static ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    outln ( " (Function) " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_function - > dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 17:11:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  ClassField : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ASTNode : : dump ( indent ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    outln ( " (Key) " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_key - > dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:09:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    outln ( " Static: {} " ,  is_static ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 17:11:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_initializer )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        print_indent ( indent ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        outln ( " (Initializer) " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_initializer - > dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-20 21:29:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  StaticInitializer : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ASTNode : : dump ( indent ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_function_body - > dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 12:19:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  StringLiteral : : dump ( int  indent )  const  
						 
					
						
							
								
									
										
										
										
											2020-03-07 19:42:11 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    outln ( " StringLiteral  \" {} \" " ,  m_value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 12:19:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  SuperExpression : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    outln ( " super " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 12:19:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  NumericLiteral : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    outln ( " NumericLiteral {} " ,  m_value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 12:19:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-06 01:14:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  BigIntLiteral : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    outln ( " BigIntLiteral {} " ,  m_value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-06 01:14:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 12:19:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  BooleanLiteral : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    outln ( " BooleanLiteral {} " ,  m_value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-07 19:42:11 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-15 23:32:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  NullLiteral : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    outln ( " null " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-15 23:32:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  BindingPattern : : contains_expression ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto &  entry  :  entries )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( entry . initializer ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( auto  binding_ptr  =  entry . alias . get_pointer < NonnullRefPtr < BindingPattern > > ( ) ;  binding_ptr  & &  ( * binding_ptr ) - > contains_expression ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  BindingPattern : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    outln ( " BindingPattern {} " ,  kind  = =  Kind : : Array  ?  " Array "  :  " Object " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-12 18:04:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto &  entry  :  entries )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        print_indent ( indent  +  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-12 18:04:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        outln ( " (Property) " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( kind  = =  Kind : : Object )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            print_indent ( indent  +  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            outln ( " (Identifier) " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( entry . name . has < NonnullRefPtr < Identifier > > ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                entry . name . get < NonnullRefPtr < Identifier > > ( ) - > dump ( indent  +  3 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                entry . name . get < NonnullRefPtr < Expression > > ( ) - > dump ( indent  +  3 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  if  ( entry . is_elision ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            print_indent ( indent  +  2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-12 18:04:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            outln ( " (Elision) " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-12 18:04:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        print_indent ( indent  +  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        outln ( " (Pattern{}) " ,  entry . is_rest  ?  "  rest=true "  :  " " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( entry . alias . has < NonnullRefPtr < Identifier > > ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            entry . alias . get < NonnullRefPtr < Identifier > > ( ) - > dump ( indent  +  3 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  if  ( entry . alias . has < NonnullRefPtr < BindingPattern > > ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            entry . alias . get < NonnullRefPtr < BindingPattern > > ( ) - > dump ( indent  +  3 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 01:11:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  if  ( entry . alias . has < NonnullRefPtr < MemberExpression > > ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            entry . alias . get < NonnullRefPtr < MemberExpression > > ( ) - > dump ( indent  +  3 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-12 18:04:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            print_indent ( indent  +  3 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            outln ( " <empty> " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-12 18:04:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( entry . initializer )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            print_indent ( indent  +  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            outln ( " (Initializer) " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            entry . initializer - > dump ( indent  +  3 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 02:13:06 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  FunctionNode : : dump ( int  indent ,  String  const &  class_name )  const  
						 
					
						
							
								
									
										
										
										
											2020-03-07 19:42:11 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-15 01:53:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  is_async  =  m_kind  = =  FunctionKind : : Async  | |  m_kind  = =  FunctionKind : : AsyncGenerator ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  is_generator  =  m_kind  = =  FunctionKind : : Generator  | |  m_kind  = =  FunctionKind : : AsyncGenerator ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    outln ( " {}{}{} '{}' " ,  class_name ,  is_async  ?  "  async "  :  " " ,  is_generator  ?  " * "  :  " " ,  name ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 12:43:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_contains_direct_call_to_eval )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        print_indent ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        outln ( " \033 [31;1m(direct eval) \033 [0m " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-02 11:46:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! m_parameters . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        print_indent ( indent  +  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 22:49:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        outln ( " (Parameters) " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-02 11:46:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( auto &  parameter  :  m_parameters )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            print_indent ( indent  +  2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-04 16:05:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( parameter . is_rest ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                out ( " ... " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            parameter . binding . visit ( 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 02:13:06 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                [ & ] ( FlyString  const &  name )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    outln ( " {} " ,  name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } , 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 02:13:06 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                [ & ] ( BindingPattern  const &  pattern )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    pattern . dump ( indent  +  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-04 16:05:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( parameter . default_value ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-02 11:46:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                parameter . default_value - > dump ( indent  +  3 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-13 16:42:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    print_indent ( indent  +  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    outln ( " (Body) " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-13 16:42:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    body ( ) . dump ( indent  +  2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-07 19:42:11 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-19 11:12:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  FunctionDeclaration : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    FunctionNode : : dump ( indent ,  class_name ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  FunctionDeclaration : : for_each_bound_name ( IteratorOrVoidFunction < FlyString  const & >  callback )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! name ( ) . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        callback ( name ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-19 11:12:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  FunctionExpression : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    FunctionNode : : dump ( indent ,  class_name ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 01:38:30 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  YieldExpression : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ASTNode : : dump ( indent ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( argument ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        argument ( ) - > dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-09 22:52:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  AwaitExpression : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ASTNode : : dump ( indent ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_argument - > dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-07 19:42:11 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								void  ReturnStatement : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ASTNode : : dump ( indent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( argument ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        argument ( ) - > dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-07 19:42:11 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-08 07:58:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  IfStatement : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ASTNode : : dump ( indent ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    outln ( " If " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-08 07:58:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    predicate ( ) . dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    consequent ( ) . dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-21 18:40:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( alternate ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        print_indent ( indent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        outln ( " Else " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-21 18:40:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        alternate ( ) - > dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-08 07:58:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-09 03:22:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  WhileStatement : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ASTNode : : dump ( indent ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    outln ( " While " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-04 21:21:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    test ( ) . dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-09 03:22:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    body ( ) . dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-28 15:05:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  WithStatement : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ASTNode : : dump ( indent ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent  +  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    outln ( " Object " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-28 15:05:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    object ( ) . dump ( indent  +  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent  +  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    outln ( " Body " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-28 15:05:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    body ( ) . dump ( indent  +  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-04 21:29:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  DoWhileStatement : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ASTNode : : dump ( indent ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    outln ( " DoWhile " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-04 21:29:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    test ( ) . dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    body ( ) . dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:12:12 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  ForStatement : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ASTNode : : dump ( indent ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    outln ( " For " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:12:12 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( init ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        init ( ) - > dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( test ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        test ( ) - > dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( update ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        update ( ) - > dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    body ( ) . dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-21 19:21:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  ForInStatement : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ASTNode : : dump ( indent ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    outln ( " ForIn " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    lhs ( ) . visit ( [ & ] ( auto &  lhs )  {  lhs - > dump ( indent  +  1 ) ;  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-21 19:21:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    rhs ( ) . dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    body ( ) . dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  ForOfStatement : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ASTNode : : dump ( indent ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    outln ( " ForOf " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    lhs ( ) . visit ( [ & ] ( auto &  lhs )  {  lhs - > dump ( indent  +  1 ) ;  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-21 19:21:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    rhs ( ) . dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    body ( ) . dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-23 16:09:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  ForAwaitOfStatement : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ASTNode : : dump ( indent ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    outln ( " ForAwaitOf " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_lhs . visit ( [ & ] ( auto &  lhs )  {  lhs - > dump ( indent  +  1 ) ;  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_rhs - > dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_body - > dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 21:25:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  Identifier : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
									
										
										
										
											2020-03-09 21:13:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  reference  =  to_reference ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Rewrite most of Object for spec compliance :^)
This is a huge patch, I know. In hindsight this perhaps could've been
done slightly more incremental, but I started and then fixed everything
until it worked, and here we are. I tried splitting of some completely
unrelated changes into separate commits, however. Anyway.
This is a rewrite of most of Object, and by extension large parts of
Array, Proxy, Reflect, String, TypedArray, and some other things.
What we already had worked fine for about 90% of things, but getting the
last 10% right proved to be increasingly difficult with the current code
that sort of grew organically and is only very loosely based on the
spec - this became especially obvious when we started fixing a large
number of test262 failures.
Key changes include:
- 1:1 matching function names and parameters of all object-related
  functions, to avoid ambiguity. Previously we had things like put(),
  which the spec doesn't have - as a result it wasn't always clear which
  need to be used.
- Better separation between object abstract operations and internal
  methods - the former are always the same, the latter can be overridden
  (and are therefore virtual). The internal methods (i.e. [[Foo]] in the
  spec) are now prefixed with 'internal_' for clarity - again, it was
  previously not always clear which AO a certain method represents,
  get() could've been both Get and [[Get]] (I don't know which one it
  was closer to right now).
  Note that some of the old names have been kept until all code relying
  on them is updated, but they are now simple wrappers around the
  closest matching standard abstract operation.
- Simplifications of the storage layer: functions that write values to
  storage are now prefixed with 'storage_' to make their purpose clear,
  and as they are not part of the spec they should not contain any steps
  specified by it. Much functionality is now covered by the layers above
  it and was removed (e.g. handling of accessors, attribute checks).
- PropertyAttributes has been greatly simplified, and is being replaced
  by PropertyDescriptor - a concept similar to the current
  implementation, but more aligned with the actual spec. See the commit
  message of the previous commit where it was introduced for details.
- As a bonus, and since I had to look at the spec a whole lot anyway, I
  introduced more inline comments with the exact steps from the spec -
  this makes it super easy to verify correctness.
- East-const all the things.
As a result of all of this, things are much more correct but a bit
slower now. Retaining speed wasn't a consideration at all, I have done
no profiling of the new code - there might be low hanging fruits, which
we can then harvest separately.
Special thanks to Idan for helping me with this by tracking down bugs,
updating everything outside of LibJS to work with these changes (LibWeb,
Spreadsheet, HackStudio), as well as providing countless patches to fix
regressions I introduced - there still are very few (we got it down to
5), but we also get many new passing test262 tests in return. :^)
Co-authored-by: Idan Horowitz <idan.horowitz@gmail.com>
											 
										 
										
											2021-07-04 18:14:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-02 18:49:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  TRY_OR_DISCARD ( reference . get_value ( global_object ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-09 21:13:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  Identifier : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-22 22:20:17 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    outln ( " Identifier  \" {} \" " ,  m_string ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-09 21:13:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-12 22:45:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  PrivateIdentifier : : execute ( Interpreter & ,  GlobalObject & )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Note: This should be handled by either the member expression this is part of
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //       or the binary expression in the case of `#foo in bar`.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  PrivateIdentifier : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    outln ( " PrivateIdentifier  \" {} \" " ,  m_string ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-26 23:05:37 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  SpreadExpression : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ASTNode : : dump ( indent ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_target - > dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  SpreadExpression : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
									
										
										
										
											2020-04-26 23:05:37 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  m_target - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-26 23:05:37 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-29 16:41:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  ThisExpression : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
									
										
										
										
											2020-04-13 00:42:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-25 11:40:03 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  interpreter . vm ( ) . resolve_this_binding ( global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-13 00:42:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  ThisExpression : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ASTNode : : dump ( indent ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// 13.15.2 Runtime Semantics: Evaluation, https://tc39.es/ecma262/#sec-assignment-operators-runtime-semantics-evaluation
  
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  AssignmentExpression : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
									
										
										
										
											2020-03-09 21:13:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_op  = =  AssignmentOp : : Assignment )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // AssignmentExpression : LeftHandSideExpression = AssignmentExpression
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  m_lhs . visit ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            [ & ] ( NonnullRefPtr < Expression > &  lhs )  - >  JS : : Value  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto  reference  =  lhs - > to_reference ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                Value  rhs_result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( lhs - > is_identifier ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    auto &  identifier_name  =  static_cast < Identifier  const & > ( * lhs ) . string ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    rhs_result  =  TRY_OR_DISCARD ( interpreter . vm ( ) . named_evaluation_if_anonymous_function ( global_object ,  m_rhs ,  identifier_name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    rhs_result  =  m_rhs - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-02 19:20:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                TRY_OR_DISCARD ( reference . put_value ( global_object ,  rhs_result ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  rhs_result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            [ & ] ( NonnullRefPtr < BindingPattern > &  pattern )  - >  JS : : Value  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                Value  rhs_result  =  m_rhs - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                TRY_OR_DISCARD ( interpreter . vm ( ) . destructuring_assignment_evaluation ( pattern ,  rhs_result ,  global_object ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  rhs_result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY ( m_lhs . has < NonnullRefPtr < Expression > > ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  lhs_expression  =  * m_lhs . get < NonnullRefPtr < Expression > > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  reference  =  lhs_expression . to_reference ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-02 18:49:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  lhs_result  =  TRY_OR_DISCARD ( reference . get_value ( global_object ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //  AssignmentExpression : LeftHandSideExpression {&&=, ||=, ??=} AssignmentExpression
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_op  = =  AssignmentOp : : AndAssignment  | |  m_op  = =  AssignmentOp : : OrAssignment  | |  m_op  = =  AssignmentOp : : NullishAssignment )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        switch  ( m_op )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  AssignmentOp : : AndAssignment : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! lhs_result . to_boolean ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  lhs_result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  AssignmentOp : : OrAssignment : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( lhs_result . to_boolean ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  lhs_result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  AssignmentOp : : NullishAssignment : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! lhs_result . is_nullish ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  lhs_result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Value  rhs_result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( lhs_expression . is_identifier ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto &  identifier_name  =  static_cast < Identifier  const & > ( lhs_expression ) . string ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            rhs_result  =  TRY_OR_DISCARD ( interpreter . vm ( ) . named_evaluation_if_anonymous_function ( global_object ,  m_rhs ,  identifier_name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            rhs_result  =  m_rhs - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-02 19:20:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        TRY_OR_DISCARD ( reference . put_value ( global_object ,  rhs_result ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  rhs_result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // AssignmentExpression : LeftHandSideExpression AssignmentOperator AssignmentExpression
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  rhs_result  =  m_rhs - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-09 21:13:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    switch  ( m_op )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 13:54:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  AssignmentOp : : AdditionAssignment : 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-19 00:13:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        rhs_result  =  TRY_OR_DISCARD ( add ( global_object ,  lhs_result ,  rhs_result ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:09:15 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 13:54:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  AssignmentOp : : SubtractionAssignment : 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-19 00:13:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        rhs_result  =  TRY_OR_DISCARD ( sub ( global_object ,  lhs_result ,  rhs_result ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:09:15 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 13:54:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  AssignmentOp : : MultiplicationAssignment : 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-19 00:13:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        rhs_result  =  TRY_OR_DISCARD ( mul ( global_object ,  lhs_result ,  rhs_result ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:09:15 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 13:54:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  AssignmentOp : : DivisionAssignment : 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-19 00:13:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        rhs_result  =  TRY_OR_DISCARD ( div ( global_object ,  lhs_result ,  rhs_result ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:09:15 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-04 23:07:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  AssignmentOp : : ModuloAssignment : 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-19 00:13:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        rhs_result  =  TRY_OR_DISCARD ( mod ( global_object ,  lhs_result ,  rhs_result ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-04 23:07:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-04 23:03:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  AssignmentOp : : ExponentiationAssignment : 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-19 00:13:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        rhs_result  =  TRY_OR_DISCARD ( exp ( global_object ,  lhs_result ,  rhs_result ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-04 23:03:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-04 22:34:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  AssignmentOp : : BitwiseAndAssignment : 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-19 00:13:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        rhs_result  =  TRY_OR_DISCARD ( bitwise_and ( global_object ,  lhs_result ,  rhs_result ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-04 22:34:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  AssignmentOp : : BitwiseOrAssignment : 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-19 00:13:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        rhs_result  =  TRY_OR_DISCARD ( bitwise_or ( global_object ,  lhs_result ,  rhs_result ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-04 22:34:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  AssignmentOp : : BitwiseXorAssignment : 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-19 00:13:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        rhs_result  =  TRY_OR_DISCARD ( bitwise_xor ( global_object ,  lhs_result ,  rhs_result ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-04 22:34:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-23 13:36:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  AssignmentOp : : LeftShiftAssignment : 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-19 00:13:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        rhs_result  =  TRY_OR_DISCARD ( left_shift ( global_object ,  lhs_result ,  rhs_result ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-23 13:36:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-23 13:45:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  AssignmentOp : : RightShiftAssignment : 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-19 00:13:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        rhs_result  =  TRY_OR_DISCARD ( right_shift ( global_object ,  lhs_result ,  rhs_result ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-23 13:45:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-23 15:43:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  AssignmentOp : : UnsignedRightShiftAssignment : 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-19 00:13:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        rhs_result  =  TRY_OR_DISCARD ( unsigned_right_shift ( global_object ,  lhs_result ,  rhs_result ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-23 15:43:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  AssignmentOp : : Assignment : 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-05 16:49:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  AssignmentOp : : AndAssignment : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  AssignmentOp : : OrAssignment : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  AssignmentOp : : NullishAssignment : 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-09 21:13:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-02 19:20:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TRY_OR_DISCARD ( reference . put_value ( global_object ,  rhs_result ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 01:16:17 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  rhs_result ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-09 21:13:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  UpdateExpression : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
									
										
										
										
											2020-03-12 13:45:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  reference  =  m_argument - > to_reference ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-25 16:27:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-28 14:44:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-02 18:49:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  old_value  =  TRY_OR_DISCARD ( reference . get_value ( global_object ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-16 21:42:32 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    old_value  =  TRY_OR_DISCARD ( old_value . to_numeric ( global_object ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 13:45:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-06 01:14:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Value  new_value ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 13:45:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    switch  ( m_op )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  UpdateOp : : Increment : 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-06 01:14:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( old_value . is_number ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            new_value  =  Value ( old_value . as_double ( )  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-27 20:00:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            new_value  =  js_bigint ( interpreter . heap ( ) ,  old_value . as_bigint ( ) . big_integer ( ) . plus ( Crypto : : SignedBigInteger  {  1  } ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 13:45:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  UpdateOp : : Decrement : 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-06 01:14:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( old_value . is_number ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            new_value  =  Value ( old_value . as_double ( )  -  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-27 20:00:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            new_value  =  js_bigint ( interpreter . heap ( ) ,  old_value . as_bigint ( ) . big_integer ( ) . minus ( Crypto : : SignedBigInteger  {  1  } ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 14:24:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-21 23:27:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    default : 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-23 20:42:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 13:45:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-02 19:20:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TRY_OR_DISCARD ( reference . put_value ( global_object ,  new_value ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-21 23:27:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  m_prefixed  ?  new_value  :  old_value ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 13:45:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-09 21:13:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  AssignmentExpression : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  char *  op_string  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    switch  ( m_op )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 13:54:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  AssignmentOp : : Assignment : 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-09 21:13:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        op_string  =  " = " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 13:54:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  AssignmentOp : : AdditionAssignment : 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:09:15 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        op_string  =  " += " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 13:54:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  AssignmentOp : : SubtractionAssignment : 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:09:15 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        op_string  =  " -= " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 13:54:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  AssignmentOp : : MultiplicationAssignment : 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:09:15 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        op_string  =  " *= " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 13:54:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  AssignmentOp : : DivisionAssignment : 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:09:15 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        op_string  =  " /= " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-04 23:07:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  AssignmentOp : : ModuloAssignment : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        op_string  =  " %= " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-04 23:03:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  AssignmentOp : : ExponentiationAssignment : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        op_string  =  " **= " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-04 22:34:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  AssignmentOp : : BitwiseAndAssignment : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        op_string  =  " &= " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  AssignmentOp : : BitwiseOrAssignment : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        op_string  =  " |= " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  AssignmentOp : : BitwiseXorAssignment : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        op_string  =  " ^= " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-23 13:36:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  AssignmentOp : : LeftShiftAssignment : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        op_string  =  " <<= " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-23 13:45:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  AssignmentOp : : RightShiftAssignment : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        op_string  =  " >>= " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-23 15:43:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  AssignmentOp : : UnsignedRightShiftAssignment : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        op_string  =  " >>>= " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-05 16:49:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  AssignmentOp : : AndAssignment : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        op_string  =  " &&= " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  AssignmentOp : : OrAssignment : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        op_string  =  " ||= " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  AssignmentOp : : NullishAssignment : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        op_string  =  " \ ? \ ?= " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-09 21:13:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ASTNode : : dump ( indent ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent  +  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    outln ( " {} " ,  op_string ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 01:16:17 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_lhs . visit ( [ & ] ( auto &  lhs )  {  lhs - > dump ( indent  +  1 ) ;  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-09 21:13:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_rhs - > dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 13:45:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  UpdateExpression : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  char *  op_string  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    switch  ( m_op )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  UpdateOp : : Increment : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        op_string  =  " ++ " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  UpdateOp : : Decrement : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        op_string  =  " -- " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ASTNode : : dump ( indent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-19 00:17:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_prefixed )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        print_indent ( indent  +  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        outln ( " {} " ,  op_string ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-19 00:17:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 13:45:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_argument - > dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 20:44:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! m_prefixed )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        print_indent ( indent  +  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        outln ( " {} " ,  op_string ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 20:44:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 13:45:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  VariableDeclaration : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
									
										
										
										
											2020-03-09 21:13:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-04 21:46:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto &  declarator  :  m_declarations )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( auto *  init  =  declarator . init ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-02 19:20:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            TRY_OR_DISCARD ( declarator . target ( ) . visit ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                [ & ] ( NonnullRefPtr < Identifier >  const &  id )  - >  ThrowCompletionOr < void >  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    auto  reference  =  id - > to_reference ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-02 19:20:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    if  ( auto *  exception  =  interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        return  throw_completion ( exception - > value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    auto  initializer_result  =  TRY_OR_DISCARD ( interpreter . vm ( ) . named_evaluation_if_anonymous_function ( global_object ,  * init ,  id - > string ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    VERIFY ( ! initializer_result . is_empty ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( m_declaration_kind  = =  DeclarationKind : : Var ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-02 19:27:29 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                        return  reference . put_value ( global_object ,  initializer_result ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    else 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-02 19:27:29 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                        return  reference . initialize_referenced_binding ( global_object ,  initializer_result ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                } , 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-02 19:20:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                [ & ] ( NonnullRefPtr < BindingPattern >  const &  pattern )  - >  ThrowCompletionOr < void >  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    auto  initializer_result  =  init - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-02 19:20:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    if  ( auto *  exception  =  interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        return  throw_completion ( exception - > value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    Environment *  environment  =  m_declaration_kind  = =  DeclarationKind : : Var  ?  nullptr  :  interpreter . lexical_environment ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-02 19:20:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    return  interpreter . vm ( ) . binding_initialization ( pattern ,  initializer_result ,  environment ,  global_object ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  if  ( m_declaration_kind  ! =  DeclarationKind : : Var )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            VERIFY ( declarator . target ( ) . has < NonnullRefPtr < Identifier > > ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto &  identifier  =  declarator . target ( ) . get < NonnullRefPtr < Identifier > > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  reference  =  identifier - > to_reference ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-02 19:27:29 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            TRY_OR_DISCARD ( reference . initialize_referenced_binding ( global_object ,  js_undefined ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-04 21:46:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-09 21:13:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-16 09:12:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-09 21:13:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  VariableDeclarator : : execute ( Interpreter &  interpreter ,  GlobalObject & )  const  
						 
					
						
							
								
									
										
										
										
											2020-04-04 21:46:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-18 17:44:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // NOTE: VariableDeclarator execution is handled by VariableDeclaration.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-23 20:42:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-04 21:46:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  VariableDeclaration : : for_each_bound_name ( IteratorOrVoidFunction < FlyString  const & >  callback )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto &  entry  :  declarations ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        entry . target ( ) . template  visit ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            [ & ] ( const  NonnullRefPtr < Identifier > &  id )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                callback ( id - > string ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            [ & ] ( const  NonnullRefPtr < BindingPattern > &  binding )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                binding - > for_each_bound_name ( [ & ] ( const  auto &  name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    callback ( name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-09 21:13:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  VariableDeclaration : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-04-08 11:59:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  char *  declaration_kind_string  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    switch  ( m_declaration_kind )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  DeclarationKind : : Let : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        declaration_kind_string  =  " Let " ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 21:09:20 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-08 11:59:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  DeclarationKind : : Var : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        declaration_kind_string  =  " Var " ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 14:24:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-08 11:59:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  DeclarationKind : : Const : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        declaration_kind_string  =  " Const " ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 21:09:20 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-09 21:13:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ASTNode : : dump ( indent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 21:09:20 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    print_indent ( indent  +  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    outln ( " {} " ,  declaration_kind_string ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-04 21:46:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto &  declarator  :  m_declarations ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        declarator . dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  VariableDeclarator : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ASTNode : : dump ( indent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_target . visit ( [ indent ] ( const  auto &  value )  {  value - > dump ( indent  +  1 ) ;  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-04 21:46:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_init ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_init - > dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-09 21:13:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-23 19:37:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  ObjectProperty : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ASTNode : : dump ( indent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-11 20:30:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_property_type  = =  Type : : Spread )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        print_indent ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        outln ( " ...Spreading " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_key - > dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_key - > dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_value - > dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-23 19:37:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-09 21:28:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  ObjectExpression : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ASTNode : : dump ( indent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-23 19:37:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto &  property  :  m_properties )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        property . dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-21 02:29:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-09 21:28:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  ExpressionStatement : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ASTNode : : dump ( indent ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_expression - > dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  ObjectProperty : : execute ( Interpreter &  interpreter ,  GlobalObject & )  const  
						 
					
						
							
								
									
										
										
										
											2020-04-23 19:37:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-23 19:37:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // NOTE: ObjectProperty execution is handled by ObjectExpression.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-23 20:42:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-23 19:37:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  ObjectExpression : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
									
										
										
										
											2020-03-09 21:28:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-16 20:52:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto *  object  =  Object : : create ( global_object ,  global_object . object_prototype ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-23 19:37:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto &  property  :  m_properties )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-07 21:38:46 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  key  =  property . key ( ) . execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-23 19:37:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-27 21:52:47 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-21 17:28:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( property . type ( )  = =  ObjectProperty : : Type : : Spread )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-05 18:58:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( key . is_object ( )  & &  is < Array > ( key . as_object ( ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-07 21:38:46 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                auto &  array_to_spread  =  static_cast < Array & > ( key . as_object ( ) ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Object index properties have descriptors; Handle sparse indices
This patch adds an IndexedProperties object for storing indexed
properties within an Object. This accomplishes two goals: indexed
properties now have an associated descriptor, and objects now gracefully
handle sparse properties.
The IndexedProperties class is a wrapper around two other classes, one
for simple indexed properties storage, and one for general indexed
property storage. Simple indexed property storage is the common-case,
and is simply a vector of properties which all have attributes of
default_attributes (writable, enumerable, and configurable).
General indexed property storage is for a collection of indexed
properties where EITHER one or more properties have attributes other
than default_attributes OR there is a property with a large index (in
particular, large is '200' or higher).
Indexed properties are now treated relatively the same as storage within
the various Object methods. Additionally, there is a custom iterator
class for IndexedProperties which makes iteration easy. The iterator
skips empty values by default, but can be configured otherwise.
Likewise, it evaluates getters by default, but can be set not to.
											 
										 
										
											2020-05-27 11:35:09 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                for  ( auto &  entry  :  array_to_spread . indexed_properties ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-02 23:52:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    auto  value  =  TRY_OR_DISCARD ( array_to_spread . get ( entry . index ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Rewrite most of Object for spec compliance :^)
This is a huge patch, I know. In hindsight this perhaps could've been
done slightly more incremental, but I started and then fixed everything
until it worked, and here we are. I tried splitting of some completely
unrelated changes into separate commits, however. Anyway.
This is a rewrite of most of Object, and by extension large parts of
Array, Proxy, Reflect, String, TypedArray, and some other things.
What we already had worked fine for about 90% of things, but getting the
last 10% right proved to be increasingly difficult with the current code
that sort of grew organically and is only very loosely based on the
spec - this became especially obvious when we started fixing a large
number of test262 failures.
Key changes include:
- 1:1 matching function names and parameters of all object-related
  functions, to avoid ambiguity. Previously we had things like put(),
  which the spec doesn't have - as a result it wasn't always clear which
  need to be used.
- Better separation between object abstract operations and internal
  methods - the former are always the same, the latter can be overridden
  (and are therefore virtual). The internal methods (i.e. [[Foo]] in the
  spec) are now prefixed with 'internal_' for clarity - again, it was
  previously not always clear which AO a certain method represents,
  get() could've been both Get and [[Get]] (I don't know which one it
  was closer to right now).
  Note that some of the old names have been kept until all code relying
  on them is updated, but they are now simple wrappers around the
  closest matching standard abstract operation.
- Simplifications of the storage layer: functions that write values to
  storage are now prefixed with 'storage_' to make their purpose clear,
  and as they are not part of the spec they should not contain any steps
  specified by it. Much functionality is now covered by the layers above
  it and was removed (e.g. handling of accessors, attribute checks).
- PropertyAttributes has been greatly simplified, and is being replaced
  by PropertyDescriptor - a concept similar to the current
  implementation, but more aligned with the actual spec. See the commit
  message of the previous commit where it was introduced for details.
- As a bonus, and since I had to look at the spec a whole lot anyway, I
  introduced more inline comments with the exact steps from the spec -
  this makes it super easy to verify correctness.
- East-const all the things.
As a result of all of this, things are much more correct but a bit
slower now. Retaining speed wasn't a consideration at all, I have done
no profiling of the new code - there might be low hanging fruits, which
we can then harvest separately.
Special thanks to Idan for helping me with this by tracking down bugs,
updating everything outside of LibJS to work with these changes (LibWeb,
Spreadsheet, HackStudio), as well as providing countless patches to fix
regressions I introduced - there still are very few (we got it down to
5), but we also get many new passing test262 tests in return. :^)
Co-authored-by: Idan Horowitz <idan.horowitz@gmail.com>
											 
										 
										
											2021-07-04 18:14:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    object - > indexed_properties ( ) . put ( entry . index ( ) ,  value ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Object index properties have descriptors; Handle sparse indices
This patch adds an IndexedProperties object for storing indexed
properties within an Object. This accomplishes two goals: indexed
properties now have an associated descriptor, and objects now gracefully
handle sparse properties.
The IndexedProperties class is a wrapper around two other classes, one
for simple indexed properties storage, and one for general indexed
property storage. Simple indexed property storage is the common-case,
and is simply a vector of properties which all have attributes of
default_attributes (writable, enumerable, and configurable).
General indexed property storage is for a collection of indexed
properties where EITHER one or more properties have attributes other
than default_attributes OR there is a property with a large index (in
particular, large is '200' or higher).
Indexed properties are now treated relatively the same as storage within
the various Object methods. Additionally, there is a custom iterator
class for IndexedProperties which makes iteration easy. The iterator
skips empty values by default, but can be configured otherwise.
Likewise, it evaluates getters by default, but can be set not to.
											 
										 
										
											2020-05-27 11:35:09 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-27 21:52:47 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-07 21:38:46 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            }  else  if  ( key . is_object ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto &  obj_to_spread  =  key . as_object ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-27 21:52:47 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-28 19:19:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                for  ( auto &  it  :  obj_to_spread . shape ( ) . property_table_ordered ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-07 10:53:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    if  ( it . value . attributes . is_enumerable ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-02 23:52:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                        object - > define_direct_property ( it . key ,  TRY_OR_DISCARD ( obj_to_spread . get ( it . key ) ) ,  JS : : default_attributes ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-07 10:53:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                        if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-27 21:52:47 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-07 21:38:46 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            }  else  if  ( key . is_string ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto &  str_to_spread  =  key . as_string ( ) . string ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-27 21:52:47 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                for  ( size_t  i  =  0 ;  i  <  str_to_spread . length ( ) ;  i + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-06 02:15:08 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    object - > define_direct_property ( i ,  js_string ( interpreter . heap ( ) ,  str_to_spread . substring ( i ,  1 ) ) ,  JS : : default_attributes ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-07 10:53:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-27 21:52:47 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  value  =  property . value ( ) . execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-27 15:35:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-21 17:28:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( value . is_function ( )  & &  property . is_method ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-24 23:49:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            static_cast < ECMAScriptFunctionObject & > ( value . as_function ( ) ) . set_home_object ( object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-12 17:49:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  name  =  TRY_OR_DISCARD ( get_function_name ( global_object ,  key ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-21 17:28:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( property . type ( )  = =  ObjectProperty : : Type : : Getter )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-04 15:18:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            name  =  String : : formatted ( " get {} " ,  name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-21 17:28:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  if  ( property . type ( )  = =  ObjectProperty : : Type : : Setter )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-04 15:18:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            name  =  String : : formatted ( " set {} " ,  name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-21 17:28:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        update_function_name ( value ,  name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
											
												LibJS: Update Object::define_accessor() to take both getter and setter
This replaces the current 'function plus boolean indicating the type'
API, which makes it easier to set both getter and setter at once.
This was already possible before but required two calls of this
function, which wasn't intuitive:
    define_accessor(name, getter, true, ...);
    define_accessor(name, setter, false, ...);
Which now becomes:
    define_accessor(name, getter, setter, ...);
											 
										 
										
											2021-04-10 18:35:29 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        switch  ( property . type ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  ObjectProperty : : Type : : Getter : 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-23 20:42:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            VERIFY ( value . is_function ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-24 16:01:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            object - > define_direct_accessor ( PropertyKey : : from_value ( global_object ,  key ) ,  & value . as_function ( ) ,  nullptr ,  Attribute : : Configurable  |  Attribute : : Enumerable ) ; 
							 
						 
					
						
							
								
									
										
										
											
												LibJS: Update Object::define_accessor() to take both getter and setter
This replaces the current 'function plus boolean indicating the type'
API, which makes it easier to set both getter and setter at once.
This was already possible before but required two calls of this
function, which wasn't intuitive:
    define_accessor(name, getter, true, ...);
    define_accessor(name, setter, false, ...);
Which now becomes:
    define_accessor(name, getter, setter, ...);
											 
										 
										
											2021-04-10 18:35:29 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  ObjectProperty : : Type : : Setter : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            VERIFY ( value . is_function ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-24 16:01:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            object - > define_direct_accessor ( PropertyKey : : from_value ( global_object ,  key ) ,  nullptr ,  & value . as_function ( ) ,  Attribute : : Configurable  |  Attribute : : Enumerable ) ; 
							 
						 
					
						
							
								
									
										
										
											
												LibJS: Update Object::define_accessor() to take both getter and setter
This replaces the current 'function plus boolean indicating the type'
API, which makes it easier to set both getter and setter at once.
This was already possible before but required two calls of this
function, which wasn't intuitive:
    define_accessor(name, getter, true, ...);
    define_accessor(name, setter, false, ...);
Which now becomes:
    define_accessor(name, getter, setter, ...);
											 
										 
										
											2021-04-10 18:35:29 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  ObjectProperty : : Type : : KeyValue : 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-24 16:01:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            object - > define_direct_property ( PropertyKey : : from_value ( global_object ,  key ) ,  value ,  JS : : default_attributes ) ; 
							 
						 
					
						
							
								
									
										
										
											
												LibJS: Update Object::define_accessor() to take both getter and setter
This replaces the current 'function plus boolean indicating the type'
API, which makes it easier to set both getter and setter at once.
This was already possible before but required two calls of this
function, which wasn't intuitive:
    define_accessor(name, getter, true, ...);
    define_accessor(name, setter, false, ...);
Which now becomes:
    define_accessor(name, getter, setter, ...);
											 
										 
										
											2021-04-10 18:35:29 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  ObjectProperty : : Type : : Spread : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-21 17:28:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
											
												LibJS: Update Object::define_accessor() to take both getter and setter
This replaces the current 'function plus boolean indicating the type'
API, which makes it easier to set both getter and setter at once.
This was already possible before but required two calls of this
function, which wasn't intuitive:
    define_accessor(name, getter, true, ...);
    define_accessor(name, setter, false, ...);
Which now becomes:
    define_accessor(name, getter, setter, ...);
											 
										 
										
											2021-04-10 18:35:29 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-27 15:35:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-21 02:29:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  object ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-09 21:28:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 18:58:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  MemberExpression : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-03-20 20:51:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    print_indent ( indent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-24 13:49:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    outln ( " {}(computed={}) " ,  class_name ( ) ,  is_computed ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 18:58:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_object - > dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_property - > dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-24 16:01:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								PropertyKey  MemberExpression : : computed_property_name ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
									
										
										
										
											2020-03-20 20:51:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-06-24 21:13:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! is_computed ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  verify_cast < Identifier > ( * m_property ) . string ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-07 19:54:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  value  =  m_property - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-15 13:39:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-23 20:42:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    VERIFY ( ! value . is_empty ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-24 16:01:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  PropertyKey : : from_value ( global_object ,  value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-20 20:51:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-19 01:12:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								String  MemberExpression : : to_string_approximation ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    String  object_string  =  " <object> " ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-01 19:34:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( is < Identifier > ( * m_object ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 02:13:06 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        object_string  =  static_cast < Identifier  const & > ( * m_object ) . string ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-19 01:12:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( is_computed ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-04 15:18:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  String : : formatted ( " {}[<computed>] " ,  object_string ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-24 21:13:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  String : : formatted ( " {}.{} " ,  object_string ,  verify_cast < Identifier > ( * m_property ) . string ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-19 01:12:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  MemberExpression : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
									
										
										
										
											2020-03-11 18:58:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-14 22:14:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  reference  =  to_reference ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-27 15:35:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-02 18:49:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  TRY_OR_DISCARD ( reference . get_value ( global_object ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 18:58:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-12 22:45:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  MemberExpression : : ends_in_private_name ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( is_computed ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( is < PrivateIdentifier > ( * m_property ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( is < MemberExpression > ( * m_property ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  static_cast < MemberExpression  const & > ( * m_property ) . ends_in_private_name ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-14 06:56:31 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  OptionalChain : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    outln ( " {} " ,  class_name ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_base - > dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto &  reference  :  m_references )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        reference . visit ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            [ & ] ( Call  const &  call )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                print_indent ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                outln ( " Call({}) " ,  call . mode  = =  Mode : : Optional  ?  " Optional "  :  " Not Optional " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                for  ( auto &  argument  :  call . arguments ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    argument . value - > dump ( indent  +  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            [ & ] ( ComputedReference  const &  ref )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                print_indent ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                outln ( " ComputedReference({}) " ,  ref . mode  = =  Mode : : Optional  ?  " Optional "  :  " Not Optional " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                ref . expression - > dump ( indent  +  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            [ & ] ( MemberReference  const &  ref )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                print_indent ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                outln ( " MemberReference({}) " ,  ref . mode  = =  Mode : : Optional  ?  " Optional "  :  " Not Optional " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                ref . identifier - > dump ( indent  +  2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-18 23:32:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            [ & ] ( PrivateMemberReference  const &  ref )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                print_indent ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                outln ( " PrivateMemberReference({}) " ,  ref . mode  = =  Mode : : Optional  ?  " Optional "  :  " Not Optional " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                ref . private_identifier - > dump ( indent  +  2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-14 06:56:31 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Optional < OptionalChain : : ReferenceAndValue >  OptionalChain : : to_reference_and_value ( JS : : Interpreter &  interpreter ,  JS : : GlobalObject &  global_object )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Note: This is wrapped in an optional to allow base_reference = ...
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Optional < JS : : Reference >  base_reference  =  m_base - > to_reference ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-02 18:49:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  base  =  base_reference - > is_unresolvable ( )  ?  m_base - > execute ( interpreter ,  global_object )  :  TRY_OR_DISCARD ( base_reference - > get_value ( global_object ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-14 06:56:31 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto &  reference  :  m_references )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  is_optional  =  reference . visit ( [ ] ( auto &  ref )  {  return  ref . mode ;  } )  = =  Mode : : Optional ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( is_optional  & &  base . is_nullish ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  ReferenceAndValue  {  { } ,  js_undefined ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  expression  =  reference . visit ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            [ & ] ( Call  const &  call )  - >  NonnullRefPtr < Expression >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  create_ast_node < CallExpression > ( source_range ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    create_ast_node < SyntheticReferenceExpression > ( source_range ( ) ,  * base_reference ,  base ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    call . arguments ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            [ & ] ( ComputedReference  const &  ref )  - >  NonnullRefPtr < Expression >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  create_ast_node < MemberExpression > ( source_range ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    create_ast_node < SyntheticReferenceExpression > ( source_range ( ) ,  * base_reference ,  base ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    ref . expression , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            [ & ] ( MemberReference  const &  ref )  - >  NonnullRefPtr < Expression >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  create_ast_node < MemberExpression > ( source_range ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    create_ast_node < SyntheticReferenceExpression > ( source_range ( ) ,  * base_reference ,  base ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    ref . identifier , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    false ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-18 23:32:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            [ & ] ( PrivateMemberReference  const &  ref )  - >  NonnullRefPtr < Expression >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  create_ast_node < MemberExpression > ( source_range ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    create_ast_node < SyntheticReferenceExpression > ( source_range ( ) ,  * base_reference ,  base ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    ref . private_identifier , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    false ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-14 06:56:31 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( is < CallExpression > ( * expression ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            base_reference  =  JS : : Reference  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            base  =  expression - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            base_reference  =  expression - > to_reference ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-02 18:49:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            base  =  TRY_OR_DISCARD ( base_reference - > get_value ( global_object ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-14 06:56:31 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  ReferenceAndValue  {  base_reference . release_value ( ) ,  base  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Value  OptionalChain : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( auto  result  =  to_reference_and_value ( interpreter ,  global_object ) ;  result . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  result . release_value ( ) . value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								JS : : Reference  OptionalChain : : to_reference ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( auto  result  =  to_reference_and_value ( interpreter ,  global_object ) ;  result . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  result . release_value ( ) . reference ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-02 21:27:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  MetaProperty : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    String  name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_type  = =  MetaProperty : : Type : : NewTarget ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        name  =  " new.target " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else  if  ( m_type  = =  MetaProperty : : Type : : ImportMeta ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        name  =  " import.meta " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-23 20:42:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-02 21:27:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    print_indent ( indent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    outln ( " {} {} " ,  class_name ( ) ,  name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-02 21:27:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 23:45:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  MetaProperty : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
									
										
										
										
											2020-11-02 21:27:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-02 21:27:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_type  = =  MetaProperty : : Type : : NewTarget ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  interpreter . vm ( ) . get_new_target ( ) . value_or ( js_undefined ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 23:45:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_type  = =  MetaProperty : : Type : : ImportMeta )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        interpreter . vm ( ) . throw_exception < InternalError > ( global_object ,  ErrorType : : NotImplemented ,  " 'import.meta' in modules " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-02-23 20:42:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-02 21:27:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 23:45:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  ImportCall : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ASTNode : : dump ( indent ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    outln ( " (Specifier) " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_specifier - > dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_options )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        outln ( " (Options) " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_options - > dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Value  ImportCall : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    interpreter . vm ( ) . throw_exception < InternalError > ( global_object ,  ErrorType : : NotImplemented ,  " 'import(...)' in modules " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  StringLiteral : : execute ( Interpreter &  interpreter ,  GlobalObject & )  const  
						 
					
						
							
								
									
										
										
										
											2020-03-12 12:19:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-27 20:03:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  js_string ( interpreter . heap ( ) ,  m_value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 12:19:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  NumericLiteral : : execute ( Interpreter &  interpreter ,  GlobalObject & )  const  
						 
					
						
							
								
									
										
										
										
											2020-03-12 12:19:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 12:19:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  Value ( m_value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  BigIntLiteral : : execute ( Interpreter &  interpreter ,  GlobalObject & )  const  
						 
					
						
							
								
									
										
										
										
											2020-06-06 01:14:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-14 02:19:23 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Crypto : : SignedBigInteger  integer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_value [ 0 ]  = =  ' 0 '  & &  m_value . length ( )  > =  3 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( m_value [ 1 ]  = =  ' x '  | |  m_value [ 1 ]  = =  ' X ' )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-29 17:51:52 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  js_bigint ( interpreter . heap ( ) ,  Crypto : : SignedBigInteger : : from_base ( 16 ,  m_value . substring ( 2 ,  m_value . length ( )  -  3 ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-14 02:19:23 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  if  ( m_value [ 1 ]  = =  ' o '  | |  m_value [ 1 ]  = =  ' O ' )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-29 17:51:52 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  js_bigint ( interpreter . heap ( ) ,  Crypto : : SignedBigInteger : : from_base ( 8 ,  m_value . substring ( 2 ,  m_value . length ( )  -  3 ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-14 02:19:23 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  if  ( m_value [ 1 ]  = =  ' b '  | |  m_value [ 1 ]  = =  ' B ' )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-29 17:51:52 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  js_bigint ( interpreter . heap ( ) ,  Crypto : : SignedBigInteger : : from_base ( 2 ,  m_value . substring ( 2 ,  m_value . length ( )  -  3 ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-14 02:19:23 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-29 17:51:52 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  js_bigint ( interpreter . heap ( ) ,  Crypto : : SignedBigInteger : : from_base ( 10 ,  m_value . substring ( 0 ,  m_value . length ( )  -  1 ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-06 01:14:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  BooleanLiteral : : execute ( Interpreter &  interpreter ,  GlobalObject & )  const  
						 
					
						
							
								
									
										
										
										
											2020-03-12 12:19:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 12:19:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  Value ( m_value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  NullLiteral : : execute ( Interpreter &  interpreter ,  GlobalObject & )  const  
						 
					
						
							
								
									
										
										
										
											2020-03-15 23:32:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-15 23:32:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  js_null ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-03 16:05:49 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  RegExpLiteral : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-10 11:56:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    outln ( " {} (/{}/{}) " ,  class_name ( ) ,  pattern ( ) ,  flags ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-03 16:05:49 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  RegExpLiteral : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
									
										
										
										
											2020-06-03 16:05:49 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-29 10:34:37 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Regex < ECMA262 >  regex ( parsed_regex ( ) ,  parsed_pattern ( ) ,  parsed_flags ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  RegExpObject : : create ( global_object ,  move ( regex ) ,  pattern ( ) ,  flags ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-03 16:05:49 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-20 20:29:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  ArrayExpression : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ASTNode : : dump ( indent ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto &  element  :  m_elements )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-15 20:09:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( element )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            element - > dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            print_indent ( indent  +  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            outln ( " <empty> " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-15 20:09:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-20 20:29:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  ArrayExpression : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
									
										
										
										
											2020-03-20 20:29:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-22 01:34:06 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto *  array  =  MUST ( Array : : create ( global_object ,  0 ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-06 03:29:52 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    array - > indexed_properties ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    size_t  index  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-20 20:29:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto &  element  :  m_elements )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-15 20:09:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  value  =  Value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( element )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            value  =  element - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-15 20:09:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-26 23:05:37 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-01 19:34:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( is < SpreadExpression > ( * element ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-20 12:10:23 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                TRY_OR_DISCARD ( get_iterator_values ( global_object ,  value ,  [ & ] ( Value  iterator_value )  - >  Optional < Completion >  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-06 03:29:52 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    array - > indexed_properties ( ) . put ( index + + ,  iterator_value ,  default_attributes ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-13 08:27:20 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-20 12:10:23 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                } ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-13 08:27:20 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-26 23:05:37 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-15 20:09:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-06 03:29:52 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        array - > indexed_properties ( ) . put ( index + + ,  value ,  default_attributes ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-20 20:29:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  array ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Add template literals
Adds fully functioning template literals. Because template literals
contain expressions, most of the work has to be done in the Lexer rather
than the Parser. And because of the complexity of template literals
(expressions, nesting, escapes, etc), the Lexer needs to have some
template-related state.
When entering a new template literal, a TemplateLiteralStart token is
emitted. When inside a literal, all text will be parsed up until a '${'
or '`' (or EOF, but that's a syntax error) is seen, and then a
TemplateLiteralExprStart token is emitted. At this point, the Lexer
proceeds as normal, however it keeps track of the number of opening
and closing curly braces it has seen in order to determine the close
of the expression. Once it finds a matching curly brace for the '${',
a TemplateLiteralExprEnd token is emitted and the state is updated
accordingly.
When the Lexer is inside of a template literal, but not an expression,
and sees a '`', this must be the closing grave: a TemplateLiteralEnd
token is emitted.
The state required to correctly parse template strings consists of a
vector (for nesting) of two pieces of information: whether or not we
are in a template expression (as opposed to a template string); and
the count of the number of unmatched open curly braces we have seen
(only applicable if the Lexer is currently in a template expression).
TODO: Add support for template literal newlines in the JS REPL (this will
cause a syntax error currently):
    > `foo
    > bar`
    'foo
    bar'
											 
										 
										
											2020-05-03 15:41:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  TemplateLiteral : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ASTNode : : dump ( indent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 10:17:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto &  expression  :  m_expressions ) 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Add template literals
Adds fully functioning template literals. Because template literals
contain expressions, most of the work has to be done in the Lexer rather
than the Parser. And because of the complexity of template literals
(expressions, nesting, escapes, etc), the Lexer needs to have some
template-related state.
When entering a new template literal, a TemplateLiteralStart token is
emitted. When inside a literal, all text will be parsed up until a '${'
or '`' (or EOF, but that's a syntax error) is seen, and then a
TemplateLiteralExprStart token is emitted. At this point, the Lexer
proceeds as normal, however it keeps track of the number of opening
and closing curly braces it has seen in order to determine the close
of the expression. Once it finds a matching curly brace for the '${',
a TemplateLiteralExprEnd token is emitted and the state is updated
accordingly.
When the Lexer is inside of a template literal, but not an expression,
and sees a '`', this must be the closing grave: a TemplateLiteralEnd
token is emitted.
The state required to correctly parse template strings consists of a
vector (for nesting) of two pieces of information: whether or not we
are in a template expression (as opposed to a template string); and
the count of the number of unmatched open curly braces we have seen
(only applicable if the Lexer is currently in a template expression).
TODO: Add support for template literal newlines in the JS REPL (this will
cause a syntax error currently):
    > `foo
    > bar`
    'foo
    bar'
											 
										 
										
											2020-05-03 15:41:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        expression . dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  TemplateLiteral : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Add template literals
Adds fully functioning template literals. Because template literals
contain expressions, most of the work has to be done in the Lexer rather
than the Parser. And because of the complexity of template literals
(expressions, nesting, escapes, etc), the Lexer needs to have some
template-related state.
When entering a new template literal, a TemplateLiteralStart token is
emitted. When inside a literal, all text will be parsed up until a '${'
or '`' (or EOF, but that's a syntax error) is seen, and then a
TemplateLiteralExprStart token is emitted. At this point, the Lexer
proceeds as normal, however it keeps track of the number of opening
and closing curly braces it has seen in order to determine the close
of the expression. Once it finds a matching curly brace for the '${',
a TemplateLiteralExprEnd token is emitted and the state is updated
accordingly.
When the Lexer is inside of a template literal, but not an expression,
and sees a '`', this must be the closing grave: a TemplateLiteralEnd
token is emitted.
The state required to correctly parse template strings consists of a
vector (for nesting) of two pieces of information: whether or not we
are in a template expression (as opposed to a template string); and
the count of the number of unmatched open curly braces we have seen
(only applicable if the Lexer is currently in a template expression).
TODO: Add support for template literal newlines in the JS REPL (this will
cause a syntax error currently):
    > `foo
    > bar`
    'foo
    bar'
											 
										 
										
											2020-05-03 15:41:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Add template literals
Adds fully functioning template literals. Because template literals
contain expressions, most of the work has to be done in the Lexer rather
than the Parser. And because of the complexity of template literals
(expressions, nesting, escapes, etc), the Lexer needs to have some
template-related state.
When entering a new template literal, a TemplateLiteralStart token is
emitted. When inside a literal, all text will be parsed up until a '${'
or '`' (or EOF, but that's a syntax error) is seen, and then a
TemplateLiteralExprStart token is emitted. At this point, the Lexer
proceeds as normal, however it keeps track of the number of opening
and closing curly braces it has seen in order to determine the close
of the expression. Once it finds a matching curly brace for the '${',
a TemplateLiteralExprEnd token is emitted and the state is updated
accordingly.
When the Lexer is inside of a template literal, but not an expression,
and sees a '`', this must be the closing grave: a TemplateLiteralEnd
token is emitted.
The state required to correctly parse template strings consists of a
vector (for nesting) of two pieces of information: whether or not we
are in a template expression (as opposed to a template string); and
the count of the number of unmatched open curly braces we have seen
(only applicable if the Lexer is currently in a template expression).
TODO: Add support for template literal newlines in the JS REPL (this will
cause a syntax error currently):
    > `foo
    > bar`
    'foo
    bar'
											 
										 
										
											2020-05-03 15:41:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    StringBuilder  string_builder ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 10:17:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto &  expression  :  m_expressions )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  expr  =  expression . execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Add template literals
Adds fully functioning template literals. Because template literals
contain expressions, most of the work has to be done in the Lexer rather
than the Parser. And because of the complexity of template literals
(expressions, nesting, escapes, etc), the Lexer needs to have some
template-related state.
When entering a new template literal, a TemplateLiteralStart token is
emitted. When inside a literal, all text will be parsed up until a '${'
or '`' (or EOF, but that's a syntax error) is seen, and then a
TemplateLiteralExprStart token is emitted. At this point, the Lexer
proceeds as normal, however it keeps track of the number of opening
and closing curly braces it has seen in order to determine the close
of the expression. Once it finds a matching curly brace for the '${',
a TemplateLiteralExprEnd token is emitted and the state is updated
accordingly.
When the Lexer is inside of a template literal, but not an expression,
and sees a '`', this must be the closing grave: a TemplateLiteralEnd
token is emitted.
The state required to correctly parse template strings consists of a
vector (for nesting) of two pieces of information: whether or not we
are in a template expression (as opposed to a template string); and
the count of the number of unmatched open curly braces we have seen
(only applicable if the Lexer is currently in a template expression).
TODO: Add support for template literal newlines in the JS REPL (this will
cause a syntax error currently):
    > `foo
    > bar`
    'foo
    bar'
											 
										 
										
											2020-05-03 15:41:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-12 17:49:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  string  =  TRY_OR_DISCARD ( expr . to_string ( global_object ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-15 13:39:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        string_builder . append ( string ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Add template literals
Adds fully functioning template literals. Because template literals
contain expressions, most of the work has to be done in the Lexer rather
than the Parser. And because of the complexity of template literals
(expressions, nesting, escapes, etc), the Lexer needs to have some
template-related state.
When entering a new template literal, a TemplateLiteralStart token is
emitted. When inside a literal, all text will be parsed up until a '${'
or '`' (or EOF, but that's a syntax error) is seen, and then a
TemplateLiteralExprStart token is emitted. At this point, the Lexer
proceeds as normal, however it keeps track of the number of opening
and closing curly braces it has seen in order to determine the close
of the expression. Once it finds a matching curly brace for the '${',
a TemplateLiteralExprEnd token is emitted and the state is updated
accordingly.
When the Lexer is inside of a template literal, but not an expression,
and sees a '`', this must be the closing grave: a TemplateLiteralEnd
token is emitted.
The state required to correctly parse template strings consists of a
vector (for nesting) of two pieces of information: whether or not we
are in a template expression (as opposed to a template string); and
the count of the number of unmatched open curly braces we have seen
(only applicable if the Lexer is currently in a template expression).
TODO: Add support for template literal newlines in the JS REPL (this will
cause a syntax error currently):
    > `foo
    > bar`
    'foo
    bar'
											 
										 
										
											2020-05-03 15:41:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-27 20:03:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  js_string ( interpreter . heap ( ) ,  string_builder . build ( ) ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Add template literals
Adds fully functioning template literals. Because template literals
contain expressions, most of the work has to be done in the Lexer rather
than the Parser. And because of the complexity of template literals
(expressions, nesting, escapes, etc), the Lexer needs to have some
template-related state.
When entering a new template literal, a TemplateLiteralStart token is
emitted. When inside a literal, all text will be parsed up until a '${'
or '`' (or EOF, but that's a syntax error) is seen, and then a
TemplateLiteralExprStart token is emitted. At this point, the Lexer
proceeds as normal, however it keeps track of the number of opening
and closing curly braces it has seen in order to determine the close
of the expression. Once it finds a matching curly brace for the '${',
a TemplateLiteralExprEnd token is emitted and the state is updated
accordingly.
When the Lexer is inside of a template literal, but not an expression,
and sees a '`', this must be the closing grave: a TemplateLiteralEnd
token is emitted.
The state required to correctly parse template strings consists of a
vector (for nesting) of two pieces of information: whether or not we
are in a template expression (as opposed to a template string); and
the count of the number of unmatched open curly braces we have seen
(only applicable if the Lexer is currently in a template expression).
TODO: Add support for template literal newlines in the JS REPL (this will
cause a syntax error currently):
    > `foo
    > bar`
    'foo
    bar'
											 
										 
										
											2020-05-03 15:41:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 10:17:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  TaggedTemplateLiteral : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ASTNode : : dump ( indent ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent  +  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    outln ( " (Tag) " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 10:17:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_tag - > dump ( indent  +  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent  +  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    outln ( " (Template Literal) " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 10:17:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_template_literal - > dump ( indent  +  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  TaggedTemplateLiteral : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
									
										
										
										
											2020-05-06 10:17:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-13 23:49:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto &  vm  =  interpreter . vm ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  tag  =  m_tag - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-13 23:49:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( vm . exception ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 10:17:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! tag . is_function ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-13 23:49:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        vm . throw_exception < TypeError > ( global_object ,  ErrorType : : NotAFunction ,  tag . to_string_without_side_effects ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 10:17:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  tag_function  =  tag . as_function ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  expressions  =  m_template_literal - > expressions ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-22 01:34:06 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto *  strings  =  MUST ( Array : : create ( global_object ,  0 ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-13 23:49:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    MarkedValueList  arguments ( vm . heap ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 10:17:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    arguments . append ( strings ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( size_t  i  =  0 ;  i  <  expressions . size ( ) ;  + + i )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  value  =  expressions [ i ] . execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-13 23:49:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( vm . exception ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 10:17:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // tag`${foo}`             -> "", foo, ""                -> tag(["", ""], foo)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // tag`foo${bar}baz${qux}` -> "foo", bar, "baz", qux, "" -> tag(["foo", "baz", ""], bar, qux)
 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Object index properties have descriptors; Handle sparse indices
This patch adds an IndexedProperties object for storing indexed
properties within an Object. This accomplishes two goals: indexed
properties now have an associated descriptor, and objects now gracefully
handle sparse properties.
The IndexedProperties class is a wrapper around two other classes, one
for simple indexed properties storage, and one for general indexed
property storage. Simple indexed property storage is the common-case,
and is simply a vector of properties which all have attributes of
default_attributes (writable, enumerable, and configurable).
General indexed property storage is for a collection of indexed
properties where EITHER one or more properties have attributes other
than default_attributes OR there is a property with a large index (in
particular, large is '200' or higher).
Indexed properties are now treated relatively the same as storage within
the various Object methods. Additionally, there is a custom iterator
class for IndexedProperties which makes iteration easy. The iterator
skips empty values by default, but can be configured otherwise.
Likewise, it evaluates getters by default, but can be set not to.
											 
										 
										
											2020-05-27 11:35:09 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( i  %  2  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            strings - > indexed_properties ( ) . append ( value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 10:17:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            arguments . append ( value ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Object index properties have descriptors; Handle sparse indices
This patch adds an IndexedProperties object for storing indexed
properties within an Object. This accomplishes two goals: indexed
properties now have an associated descriptor, and objects now gracefully
handle sparse properties.
The IndexedProperties class is a wrapper around two other classes, one
for simple indexed properties storage, and one for general indexed
property storage. Simple indexed property storage is the common-case,
and is simply a vector of properties which all have attributes of
default_attributes (writable, enumerable, and configurable).
General indexed property storage is for a collection of indexed
properties where EITHER one or more properties have attributes other
than default_attributes OR there is a property with a large index (in
particular, large is '200' or higher).
Indexed properties are now treated relatively the same as storage within
the various Object methods. Additionally, there is a custom iterator
class for IndexedProperties which makes iteration easy. The iterator
skips empty values by default, but can be configured otherwise.
Likewise, it evaluates getters by default, but can be set not to.
											 
										 
										
											2020-05-27 11:35:09 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 10:17:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 16:34:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-22 01:34:06 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto *  raw_strings  =  MUST ( Array : : create ( global_object ,  0 ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 16:34:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto &  raw_string  :  m_template_literal - > raw_strings ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  value  =  raw_string . execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-13 23:49:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( vm . exception ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 16:34:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Object index properties have descriptors; Handle sparse indices
This patch adds an IndexedProperties object for storing indexed
properties within an Object. This accomplishes two goals: indexed
properties now have an associated descriptor, and objects now gracefully
handle sparse properties.
The IndexedProperties class is a wrapper around two other classes, one
for simple indexed properties storage, and one for general indexed
property storage. Simple indexed property storage is the common-case,
and is simply a vector of properties which all have attributes of
default_attributes (writable, enumerable, and configurable).
General indexed property storage is for a collection of indexed
properties where EITHER one or more properties have attributes other
than default_attributes OR there is a property with a large index (in
particular, large is '200' or higher).
Indexed properties are now treated relatively the same as storage within
the various Object methods. Additionally, there is a custom iterator
class for IndexedProperties which makes iteration easy. The iterator
skips empty values by default, but can be configured otherwise.
Likewise, it evaluates getters by default, but can be set not to.
											 
										 
										
											2020-05-27 11:35:09 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        raw_strings - > indexed_properties ( ) . append ( value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 16:34:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-06 02:15:08 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    strings - > define_direct_property ( vm . names . raw ,  raw_strings ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-23 20:56:28 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  TRY_OR_DISCARD ( vm . call ( tag_function ,  js_undefined ( ) ,  move ( arguments ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 10:17:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-24 14:03:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  TryStatement : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ASTNode : : dump ( indent ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    outln ( " (Block) " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-24 14:03:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    block ( ) . dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( handler ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        print_indent ( indent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        outln ( " (Handler) " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-24 14:03:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        handler ( ) - > dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( finalizer ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        print_indent ( indent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        outln ( " (Finalizer) " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-24 14:03:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        finalizer ( ) - > dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  CatchClause : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:15:38 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_parameter . visit ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        [ & ] ( FlyString  const &  parameter )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( parameter . is_null ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                outln ( " CatchClause " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                outln ( " CatchClause ({}) " ,  parameter ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        [ & ] ( NonnullRefPtr < BindingPattern >  const &  pattern )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            outln ( " CatchClause " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            print_indent ( indent ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            outln ( " (Parameter) " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            pattern - > dump ( indent  +  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-24 14:03:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    body ( ) . dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-24 22:03:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  ThrowStatement : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ASTNode : : dump ( indent ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    argument ( ) . dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 23:01:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  TryStatement : : add_label ( FlyString  string )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_block - > add_label ( move ( string ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  TryStatement : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
									
										
										
										
											2020-03-24 14:03:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // FIXME: Use Completions here to be closer to the spec.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  result  =  m_block - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( interpreter . vm ( ) . unwind_until ( )  = =  ScopeType : : Try ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        interpreter . vm ( ) . stop_unwind ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-24 14:37:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( auto *  exception  =  interpreter . exception ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // 14.15.2 Runtime Semantics: CatchClauseEvaluation, https://tc39.es/ecma262/#sec-runtime-semantics-catchclauseevaluation
 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-24 14:37:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( m_handler )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-21 15:28:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            interpreter . vm ( ) . clear_exception ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-08 18:12:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto *  catch_scope  =  new_declarative_environment ( * interpreter . lexical_environment ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:15:38 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            m_handler - > parameter ( ) . visit ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                [ & ] ( FlyString  const &  parameter )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-09 18:53:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    MUST ( catch_scope - > create_mutable_binding ( global_object ,  parameter ,  false ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:15:38 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                [ & ] ( NonnullRefPtr < BindingPattern >  const &  pattern )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    pattern - > for_each_bound_name ( [ & ] ( auto &  name )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-09 18:53:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                        MUST ( catch_scope - > create_mutable_binding ( global_object ,  name ,  false ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:15:38 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-01 12:24:46 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            TemporaryChange < Environment * >  scope_change ( interpreter . vm ( ) . running_execution_context ( ) . lexical_environment ,  catch_scope ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:15:38 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            m_handler - > parameter ( ) . visit ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                [ & ] ( FlyString  const &  parameter )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-09 19:16:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    ( void ) catch_scope - > initialize_binding ( global_object ,  parameter ,  exception - > value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                [ & ] ( NonnullRefPtr < BindingPattern >  const &  pattern )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    ( void ) interpreter . vm ( ) . binding_initialization ( pattern ,  exception - > value ( ) ,  catch_scope ,  global_object ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                result  =  m_handler - > body ( ) . execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-24 14:37:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-11 23:30:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_finalizer )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Keep, if any, and then clear the current exception so we can
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // execute() the finalizer without an exception in our way.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto *  previous_exception  =  interpreter . exception ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-21 15:28:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        interpreter . vm ( ) . clear_exception ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-13 00:57:17 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Remember what scope type we were unwinding to, and temporarily
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // clear it as well (e.g. return from handler).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  unwind_until  =  interpreter . vm ( ) . unwind_until ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-27 15:18:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        interpreter . vm ( ) . stop_unwind ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-13 00:57:17 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  finalizer_result  =  m_finalizer - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( interpreter . vm ( ) . should_unwind ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // This was NOT a 'normal' completion (e.g. return from finalizer).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            result  =  finalizer_result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Continue unwinding to whatever we found ourselves unwinding
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // to when the finalizer was entered (e.g. return from handler,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // which is unaffected by normal completion from finalizer).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            interpreter . vm ( ) . unwind ( unwind_until ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // If we previously had an exception and the finalizer didn't
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // throw a new one, restore the old one.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( previous_exception  & &  ! interpreter . exception ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-13 01:02:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                interpreter . vm ( ) . set_exception ( * previous_exception ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-13 00:57:17 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-11 23:30:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-24 14:37:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-13 00:58:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  result . value_or ( js_undefined ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-24 14:03:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  CatchClause : : execute ( Interpreter &  interpreter ,  GlobalObject & )  const  
						 
					
						
							
								
									
										
										
										
											2020-03-24 14:03:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-24 14:37:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // NOTE: CatchClause execution is handled by TryStatement.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-23 20:42:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-24 14:03:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  ThrowStatement : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
									
										
										
										
											2020-03-24 22:03:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  value  =  m_argument - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-27 15:18:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( interpreter . vm ( ) . exception ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-27 15:35:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-27 15:18:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    interpreter . vm ( ) . throw_exception ( global_object ,  value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-25 12:52:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-24 22:03:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 15:51:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// 14.12.2 Runtime Semantics: CaseBlockEvaluation, https://tc39.es/ecma262/#sec-runtime-semantics-caseblockevaluation
  
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  SwitchStatement : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
									
										
										
										
											2020-03-29 13:09:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-09-26 16:28:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // FIXME: This needs a massive refactoring, ideally once we start using continue, break, and return completions.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Instead of having an optional test expression, SwitchCase should be split into CaseClause and DefaultClause.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // https://tc39.es/ecma262/#sec-switch-statement
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  discriminant_result  =  m_discriminant - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-29 14:34:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-09 00:42:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Optimization: Avoid creating a lexical environment if there are no lexical declarations.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Optional < TemporaryChange < Environment * > >  lexical_environment_changer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( has_lexical_declarations ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto *  old_environment  =  interpreter . lexical_environment ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto *  block_environment  =  new_declarative_environment ( * old_environment ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        block_declaration_instantiation ( global_object ,  block_environment ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        lexical_environment_changer . emplace ( interpreter . vm ( ) . running_execution_context ( ) . lexical_environment ,  block_environment ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 15:51:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Optional < size_t >  first_passing_case ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( size_t  i  =  0 ;  i  <  m_cases . size ( ) ;  + + i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  switch_case  =  m_cases [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( switch_case . test ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  test_result  =  switch_case . test ( ) - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( is_strictly_equal ( discriminant_result ,  test_result ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                first_passing_case  =  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // FIXME: we could optimize and store the location of the default case in a member variable.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! first_passing_case . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( size_t  i  =  0 ;  i  <  m_cases . size ( ) ;  + + i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto &  switch_case  =  m_cases [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! switch_case . test ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                first_passing_case  =  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-06 20:58:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  last_value  =  js_undefined ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-29 14:34:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 15:51:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! first_passing_case . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  last_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY ( first_passing_case . value ( )  <  m_cases . size ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( size_t  i  =  first_passing_case . value ( ) ;  i  <  m_cases . size ( ) ;  + + i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  switch_case  =  m_cases [ i ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        for  ( auto &  statement  :  switch_case . children ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-06 20:58:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto  value  =  statement . execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! value . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                last_value  =  value ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-29 14:34:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 15:51:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-27 15:18:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( interpreter . vm ( ) . should_unwind ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-26 18:16:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  ( interpreter . vm ( ) . should_unwind_until ( ScopeType : : Continuable ,  m_labels ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-18 18:01:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    // No stop_unwind(), the outer loop will handle that - we just need to break out of the switch/case.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-06 20:58:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    return  last_value ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-26 18:16:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                }  else  if  ( interpreter . vm ( ) . should_unwind_until ( ScopeType : : Breakable ,  m_labels ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-27 15:18:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    interpreter . vm ( ) . stop_unwind ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-06 20:58:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    return  last_value ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-18 17:44:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    return  last_value ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 00:09:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-29 14:34:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-06 20:58:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  last_value ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-29 13:09:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  SwitchCase : : execute ( Interpreter &  interpreter ,  GlobalObject & )  const  
						 
					
						
							
								
									
										
										
										
											2020-03-29 13:09:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-18 17:44:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // NOTE: SwitchCase execution is handled by SwitchStatement.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-23 20:42:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-29 13:09:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  BreakStatement : : execute ( Interpreter &  interpreter ,  GlobalObject & )  const  
						 
					
						
							
								
									
										
										
										
											2020-03-29 13:09:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-27 15:18:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    interpreter . vm ( ) . unwind ( ScopeType : : Breakable ,  m_target_label ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-16 09:12:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-29 13:09:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  ContinueStatement : : execute ( Interpreter &  interpreter ,  GlobalObject & )  const  
						 
					
						
							
								
									
										
										
										
											2020-04-05 00:22:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-27 15:18:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    interpreter . vm ( ) . unwind ( ScopeType : : Continuable ,  m_target_label ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-16 09:12:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 00:22:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-29 13:09:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  SwitchStatement : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ASTNode : : dump ( indent ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_discriminant - > dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto &  switch_case  :  m_cases )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        switch_case . dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  SwitchCase : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-05-04 19:01:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    print_indent ( indent  +  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-29 13:09:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_test )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        outln ( " (Test) " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-04 19:01:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_test - > dump ( indent  +  2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-29 13:09:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        outln ( " (Default) " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-29 13:09:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-04 19:01:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    print_indent ( indent  +  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    outln ( " (Consequent) " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ScopeNode : : dump ( indent  +  2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-29 13:09:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2020-04-01 18:31:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  ConditionalExpression : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
									
										
										
										
											2020-04-03 12:14:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  test_result  =  m_test - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-03 12:14:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Value  result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( test_result . to_boolean ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        result  =  m_consequent - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-03 12:14:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        result  =  m_alternate - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-03 12:14:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  ConditionalExpression : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ASTNode : : dump ( indent ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Add template literals
Adds fully functioning template literals. Because template literals
contain expressions, most of the work has to be done in the Lexer rather
than the Parser. And because of the complexity of template literals
(expressions, nesting, escapes, etc), the Lexer needs to have some
template-related state.
When entering a new template literal, a TemplateLiteralStart token is
emitted. When inside a literal, all text will be parsed up until a '${'
or '`' (or EOF, but that's a syntax error) is seen, and then a
TemplateLiteralExprStart token is emitted. At this point, the Lexer
proceeds as normal, however it keeps track of the number of opening
and closing curly braces it has seen in order to determine the close
of the expression. Once it finds a matching curly brace for the '${',
a TemplateLiteralExprEnd token is emitted and the state is updated
accordingly.
When the Lexer is inside of a template literal, but not an expression,
and sees a '`', this must be the closing grave: a TemplateLiteralEnd
token is emitted.
The state required to correctly parse template strings consists of a
vector (for nesting) of two pieces of information: whether or not we
are in a template expression (as opposed to a template string); and
the count of the number of unmatched open curly braces we have seen
(only applicable if the Lexer is currently in a template expression).
TODO: Add support for template literal newlines in the JS REPL (this will
cause a syntax error currently):
    > `foo
    > bar`
    'foo
    bar'
											 
										 
										
											2020-05-03 15:41:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    print_indent ( indent  +  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    outln ( " (Test) " ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Add template literals
Adds fully functioning template literals. Because template literals
contain expressions, most of the work has to be done in the Lexer rather
than the Parser. And because of the complexity of template literals
(expressions, nesting, escapes, etc), the Lexer needs to have some
template-related state.
When entering a new template literal, a TemplateLiteralStart token is
emitted. When inside a literal, all text will be parsed up until a '${'
or '`' (or EOF, but that's a syntax error) is seen, and then a
TemplateLiteralExprStart token is emitted. At this point, the Lexer
proceeds as normal, however it keeps track of the number of opening
and closing curly braces it has seen in order to determine the close
of the expression. Once it finds a matching curly brace for the '${',
a TemplateLiteralExprEnd token is emitted and the state is updated
accordingly.
When the Lexer is inside of a template literal, but not an expression,
and sees a '`', this must be the closing grave: a TemplateLiteralEnd
token is emitted.
The state required to correctly parse template strings consists of a
vector (for nesting) of two pieces of information: whether or not we
are in a template expression (as opposed to a template string); and
the count of the number of unmatched open curly braces we have seen
(only applicable if the Lexer is currently in a template expression).
TODO: Add support for template literal newlines in the JS REPL (this will
cause a syntax error currently):
    > `foo
    > bar`
    'foo
    bar'
											 
										 
										
											2020-05-03 15:41:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_test - > dump ( indent  +  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent  +  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    outln ( " (Consequent) " ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Add template literals
Adds fully functioning template literals. Because template literals
contain expressions, most of the work has to be done in the Lexer rather
than the Parser. And because of the complexity of template literals
(expressions, nesting, escapes, etc), the Lexer needs to have some
template-related state.
When entering a new template literal, a TemplateLiteralStart token is
emitted. When inside a literal, all text will be parsed up until a '${'
or '`' (or EOF, but that's a syntax error) is seen, and then a
TemplateLiteralExprStart token is emitted. At this point, the Lexer
proceeds as normal, however it keeps track of the number of opening
and closing curly braces it has seen in order to determine the close
of the expression. Once it finds a matching curly brace for the '${',
a TemplateLiteralExprEnd token is emitted and the state is updated
accordingly.
When the Lexer is inside of a template literal, but not an expression,
and sees a '`', this must be the closing grave: a TemplateLiteralEnd
token is emitted.
The state required to correctly parse template strings consists of a
vector (for nesting) of two pieces of information: whether or not we
are in a template expression (as opposed to a template string); and
the count of the number of unmatched open curly braces we have seen
(only applicable if the Lexer is currently in a template expression).
TODO: Add support for template literal newlines in the JS REPL (this will
cause a syntax error currently):
    > `foo
    > bar`
    'foo
    bar'
											 
										 
										
											2020-05-03 15:41:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_consequent - > dump ( indent  +  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent  +  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    outln ( " (Alternate) " ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Add template literals
Adds fully functioning template literals. Because template literals
contain expressions, most of the work has to be done in the Lexer rather
than the Parser. And because of the complexity of template literals
(expressions, nesting, escapes, etc), the Lexer needs to have some
template-related state.
When entering a new template literal, a TemplateLiteralStart token is
emitted. When inside a literal, all text will be parsed up until a '${'
or '`' (or EOF, but that's a syntax error) is seen, and then a
TemplateLiteralExprStart token is emitted. At this point, the Lexer
proceeds as normal, however it keeps track of the number of opening
and closing curly braces it has seen in order to determine the close
of the expression. Once it finds a matching curly brace for the '${',
a TemplateLiteralExprEnd token is emitted and the state is updated
accordingly.
When the Lexer is inside of a template literal, but not an expression,
and sees a '`', this must be the closing grave: a TemplateLiteralEnd
token is emitted.
The state required to correctly parse template strings consists of a
vector (for nesting) of two pieces of information: whether or not we
are in a template expression (as opposed to a template string); and
the count of the number of unmatched open curly braces we have seen
(only applicable if the Lexer is currently in a template expression).
TODO: Add support for template literal newlines in the JS REPL (this will
cause a syntax error currently):
    > `foo
    > bar`
    'foo
    bar'
											 
										 
										
											2020-05-03 15:41:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_alternate - > dump ( indent  +  2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-03 12:14:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-07 15:11:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  SequenceExpression : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ASTNode : : dump ( indent ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto &  expression  :  m_expressions ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        expression . dump ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  SequenceExpression : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
									
										
										
										
											2020-04-07 15:11:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-21 17:38:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-07 15:11:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Value  last_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto &  expression  :  m_expressions )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 20:57:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        last_value  =  expression . execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-07 15:11:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  last_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  DebuggerStatement : : execute ( Interpreter &  interpreter ,  GlobalObject & )  const  
						 
					
						
							
								
									
										
										
										
											2020-04-30 17:26:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-03-16 10:51:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-03 22:46:12 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Sorry, no JavaScript debugger available (yet)!
 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-16 09:12:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-30 17:26:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  ScopeNode : : for_each_lexically_scoped_declaration ( IteratorOrVoidFunction < Declaration  const & > & &  callback )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto &  declaration  :  m_lexical_declarations )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( callback ( declaration )  = =  IterationDecision : : Break ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  ScopeNode : : for_each_lexically_declared_name ( IteratorOrVoidFunction < FlyString  const & > & &  callback )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  running  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto &  declaration  :  m_lexical_declarations )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        declaration . for_each_bound_name ( [ & ] ( auto  const &  name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( callback ( name )  = =  IterationDecision : : Break )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                running  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  IterationDecision : : Break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  IterationDecision : : Continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! running ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  ScopeNode : : for_each_var_declared_name ( IteratorOrVoidFunction < FlyString  const & > & &  callback )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  running  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto &  declaration  :  m_var_declarations )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        declaration . for_each_bound_name ( [ & ] ( auto  const &  name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( callback ( name )  = =  IterationDecision : : Break )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                running  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  IterationDecision : : Break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  IterationDecision : : Continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! running ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  ScopeNode : : for_each_var_function_declaration_in_reverse_order ( IteratorOrVoidFunction < FunctionDeclaration  const & > & &  callback )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( ssize_t  i  =  m_var_declarations . size ( )  -  1 ;  i  > =  0 ;  i - - )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  declaration  =  m_var_declarations [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( is < FunctionDeclaration > ( declaration ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( callback ( static_cast < FunctionDeclaration  const & > ( declaration ) )  = =  IterationDecision : : Break ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  ScopeNode : : for_each_var_scoped_variable_declaration ( IteratorOrVoidFunction < VariableDeclaration  const & > & &  callback )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto &  declaration  :  m_var_declarations )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! is < FunctionDeclaration > ( declaration ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            VERIFY ( is < VariableDeclaration > ( declaration ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( callback ( static_cast < VariableDeclaration  const & > ( declaration ) )  = =  IterationDecision : : Break ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  ScopeNode : : for_each_function_hoistable_with_annexB_extension ( IteratorOrVoidFunction < FunctionDeclaration & > & &  callback )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto &  function  :  m_functions_hoistable_with_annexB_extension )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // We need const_cast here since it might have to set a property on function declaration.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( callback ( const_cast < FunctionDeclaration & > ( function ) )  = =  IterationDecision : : Break ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  ScopeNode : : add_lexical_declaration ( NonnullRefPtr < Declaration >  declaration )  
						 
					
						
							
								
									
										
										
										
											2020-04-13 16:42:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_lexical_declarations . append ( move ( declaration ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-13 16:42:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  ScopeNode : : add_var_scoped_declaration ( NonnullRefPtr < Declaration >  declaration )  
						 
					
						
							
								
									
										
										
										
											2020-06-04 14:48:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_var_declarations . append ( move ( declaration ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-04 14:48:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  ScopeNode : : add_hoisted_function ( NonnullRefPtr < FunctionDeclaration >  declaration )  
						 
					
						
							
								
									
										
										
										
											2021-07-04 03:15:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_functions_hoistable_with_annexB_extension . append ( move ( declaration ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-04 03:15:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2021-08-14 17:42:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-22 00:23:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Value  ImportStatement : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
									
										
										
										
											2021-08-14 17:42:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    dbgln ( " Modules are not fully supported yet! " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-22 00:23:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    interpreter . vm ( ) . throw_exception < InternalError > ( global_object ,  ErrorType : : NotImplemented ,  " 'import' in modules " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-14 17:42:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Value  ExportStatement : : execute ( Interpreter &  interpreter ,  GlobalObject &  global_object )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    InterpreterNodeScope  node_scope  {  interpreter ,  * this  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_statement ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  m_statement - > execute ( interpreter ,  global_object ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-20 15:29:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  dump_assert_clauses ( ModuleRequest  const &  request )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! request . assertions . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        out ( " [  " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( auto &  assertion  :  request . assertions ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            out ( " {}: {},  " ,  assertion . key ,  assertion . value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        out ( "  ] " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-14 17:42:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  ExportStatement : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ASTNode : : dump ( indent ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    outln ( " (ExportEntries) " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  string_or_null  =  [ ] ( String  const &  string )  - >  String  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( string . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  " null " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  String : : formatted ( " \" {} \" " ,  string ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto &  entry  :  m_entries )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        print_indent ( indent  +  2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-20 15:29:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        out ( " ModuleRequest: {} " ,  entry . module_request . module_specifier ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        dump_assert_clauses ( entry . module_request ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        outln ( " , ImportName: {}, LocalName: {}, ExportName: {} " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            entry . kind  = =  ExportEntry : : Kind : : ModuleRequest  ?  string_or_null ( entry . local_or_import_name )  :  " null " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            entry . kind  ! =  ExportEntry : : Kind : : ModuleRequest  ?  string_or_null ( entry . local_or_import_name )  :  " null " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            string_or_null ( entry . export_name ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-14 17:42:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  ImportStatement : : dump ( int  indent )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ASTNode : : dump ( indent ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_indent ( indent  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_entries . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // direct from "module" import
 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-20 15:29:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        outln ( " Entire module '{}' " ,  m_module_request . module_specifier ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        dump_assert_clauses ( m_module_request ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-14 17:42:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-20 15:29:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        outln ( " (ExportEntries) from {} " ,  m_module_request . module_specifier ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        dump_assert_clauses ( m_module_request ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-14 17:42:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( auto &  entry  :  m_entries )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            print_indent ( indent  +  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            outln ( " ImportName: {}, LocalName: {} " ,  entry . import_name ,  entry . local_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								bool  ExportStatement : : has_export ( StringView  export_name )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  any_of ( m_entries . begin ( ) ,  m_entries . end ( ) ,  [ & ] ( auto &  entry )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  entry . export_name  = =  export_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								bool  ImportStatement : : has_bound_name ( StringView  name )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  any_of ( m_entries . begin ( ) ,  m_entries . end ( ) ,  [ & ] ( auto &  entry )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  entry . local_name  = =  name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// 14.2.3 BlockDeclarationInstantiation ( code, env ), https://tc39.es/ecma262/#sec-blockdeclarationinstantiation
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  ScopeNode : : block_declaration_instantiation ( GlobalObject &  global_object ,  Environment *  environment )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // See also B.3.2.6 Changes to BlockDeclarationInstantiation, https://tc39.es/ecma262/#sec-web-compat-blockdeclarationinstantiation
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY ( environment ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-11 20:29:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto *  private_environment  =  global_object . vm ( ) . running_execution_context ( ) . private_environment ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for_each_lexically_scoped_declaration ( [ & ] ( Declaration  const &  declaration )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  is_constant_declaration  =  declaration . is_constant_declaration ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        declaration . for_each_bound_name ( [ & ] ( auto  const &  name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( is_constant_declaration )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-09 19:00:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                MUST ( environment - > create_immutable_binding ( global_object ,  name ,  true ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-09 17:07:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  ( ! MUST ( environment - > has_binding ( name ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-09 18:53:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    MUST ( environment - > create_mutable_binding ( global_object ,  name ,  false ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( is < FunctionDeclaration > ( declaration ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto &  function_declaration  =  static_cast < FunctionDeclaration  const & > ( declaration ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-11 20:29:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto *  function  =  ECMAScriptFunctionObject : : create ( global_object ,  function_declaration . name ( ) ,  function_declaration . body ( ) ,  function_declaration . parameters ( ) ,  function_declaration . function_length ( ) ,  environment ,  private_environment ,  function_declaration . kind ( ) ,  function_declaration . is_strict_mode ( ) ,  function_declaration . might_need_arguments_object ( ) ,  function_declaration . contains_direct_call_to_eval ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            VERIFY ( is < DeclarativeEnvironment > ( * environment ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            static_cast < DeclarativeEnvironment & > ( * environment ) . initialize_or_set_mutable_binding ( { } ,  global_object ,  function_declaration . name ( ) ,  function ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// 16.1.7 GlobalDeclarationInstantiation ( script, env ), https://tc39.es/ecma262/#sec-globaldeclarationinstantiation
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								ThrowCompletionOr < void >  Program : : global_declaration_instantiation ( Interpreter &  interpreter ,  GlobalObject &  global_object ,  GlobalEnvironment &  global_environment )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for_each_lexically_declared_name ( [ & ] ( FlyString  const &  name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( global_environment . has_var_declaration ( name )  | |  global_environment . has_lexical_declaration ( name ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 00:25:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            interpreter . vm ( ) . throw_exception < SyntaxError > ( global_object ,  ErrorType : : TopLevelVariableAlreadyDeclared ,  name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  IterationDecision : : Break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  restricted_global  =  global_environment . has_restricted_global_property ( name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  IterationDecision : : Break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( restricted_global ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 00:25:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            interpreter . vm ( ) . throw_exception < SyntaxError > ( global_object ,  ErrorType : : RestrictedGlobalProperty ,  name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  IterationDecision : : Continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( auto *  exception  =  interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  throw_completion ( exception - > value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for_each_var_declared_name ( [ & ] ( auto  const &  name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( global_environment . has_lexical_declaration ( name ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 00:25:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            interpreter . vm ( ) . throw_exception < SyntaxError > ( global_object ,  ErrorType : : TopLevelVariableAlreadyDeclared ,  name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  IterationDecision : : Break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  IterationDecision : : Continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( auto *  exception  =  interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  throw_completion ( exception - > value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    HashTable < FlyString >  declared_function_names ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Vector < FunctionDeclaration  const & >  functions_to_initialize ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for_each_var_function_declaration_in_reverse_order ( [ & ] ( FunctionDeclaration  const &  function )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( declared_function_names . set ( function . name ( ) )  ! =  AK : : HashSetResult : : InsertedNewEntry ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  IterationDecision : : Continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  function_definable  =  global_environment . can_declare_global_function ( function . name ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  IterationDecision : : Break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! function_definable )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 00:25:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            interpreter . vm ( ) . throw_exception < TypeError > ( global_object ,  ErrorType : : CannotDeclareGlobalFunction ,  function . name ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  IterationDecision : : Break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        functions_to_initialize . append ( function ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  IterationDecision : : Continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( auto *  exception  =  interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  throw_completion ( exception - > value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    HashTable < FlyString >  declared_var_names ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for_each_var_scoped_variable_declaration ( [ & ] ( Declaration  const &  declaration )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        declaration . for_each_bound_name ( [ & ] ( auto  const &  name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( declared_function_names . contains ( name ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  IterationDecision : : Continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  var_definable  =  global_environment . can_declare_global_var ( name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  IterationDecision : : Break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! var_definable )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 00:25:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                interpreter . vm ( ) . throw_exception < TypeError > ( global_object ,  ErrorType : : CannotDeclareGlobalVariable ,  name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  IterationDecision : : Break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            declared_var_names . set ( name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  IterationDecision : : Continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  IterationDecision : : Break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  IterationDecision : : Continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( auto *  exception  =  interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  throw_completion ( exception - > value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! m_is_strict_mode )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for_each_function_hoistable_with_annexB_extension ( [ & ] ( FunctionDeclaration &  function_declaration )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto &  function_name  =  function_declaration . name ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( global_environment . has_lexical_declaration ( function_name ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  IterationDecision : : Continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  function_definable  =  global_environment . can_declare_global_function ( function_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  IterationDecision : : Break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! function_definable )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 00:25:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                interpreter . vm ( ) . throw_exception < TypeError > ( global_object ,  ErrorType : : CannotDeclareGlobalFunction ,  function_name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  IterationDecision : : Break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! declared_function_names . contains ( function_name )  & &  ! declared_var_names . contains ( function_name ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                global_environment . create_global_var_binding ( function_name ,  false ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    return  IterationDecision : : Break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                declared_function_names . set ( function_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            function_declaration . set_should_do_additional_annexB_steps ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  IterationDecision : : Continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( auto *  exception  =  interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  throw_completion ( exception - > value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // We should not use declared function names below here anymore since these functions are not in there in the spec.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        declared_function_names . clear ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-11 20:29:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    PrivateEnvironment *  private_environment  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for_each_lexically_scoped_declaration ( [ & ] ( Declaration  const &  declaration )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        declaration . for_each_bound_name ( [ & ] ( auto  const &  name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( declaration . is_constant_declaration ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-09 19:00:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                ( void ) global_environment . create_immutable_binding ( global_object ,  name ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            else 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-09 18:53:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                ( void ) global_environment . create_mutable_binding ( global_object ,  name ,  false ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  IterationDecision : : Break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  IterationDecision : : Continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  IterationDecision : : Break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  IterationDecision : : Continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto &  declaration  :  functions_to_initialize )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-11 20:29:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto *  function  =  ECMAScriptFunctionObject : : create ( global_object ,  declaration . name ( ) ,  declaration . body ( ) ,  declaration . parameters ( ) ,  declaration . function_length ( ) ,  & global_environment ,  private_environment ,  declaration . kind ( ) ,  declaration . is_strict_mode ( ) ,  declaration . might_need_arguments_object ( ) ,  declaration . contains_direct_call_to_eval ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        global_environment . create_global_function_binding ( declaration . name ( ) ,  function ,  false ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( auto *  exception  =  interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  throw_completion ( exception - > value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto &  var_name  :  declared_var_names )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        global_environment . create_global_var_binding ( var_name ,  false ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( auto *  exception  =  interpreter . exception ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  throw_completion ( exception - > value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-07 19:42:11 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}