2021-06-04 11:31:13 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
									
										
										
										
											2023-02-19 22:07:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2021 - 2023 ,  Andreas  Kling  < kling @ serenityos . org > 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 21:13:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2021 ,  Linus  Groh  < linusg @ serenityos . org > 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 18:18:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2021 ,  Gunnar  Beutner  < gbeutner @ serenityos . org > 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 00:36:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2021 ,  Marcin  Gasperowicz  < xnooga @ gmail . com > 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-04 11:31:13 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  SPDX - License - Identifier :  BSD - 2 - Clause 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-09 15:23:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <AK/Find.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-06-04 11:31:13 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# include  <LibJS/AST.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibJS/Bytecode/Generator.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibJS/Bytecode/Instruction.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibJS/Bytecode/Op.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibJS/Bytecode/Register.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-06-10 22:12:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibJS/Bytecode/StringTable.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-07-01 12:24:46 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/Environment.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-12-09 18:48:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/ErrorTypes.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-06-04 11:31:13 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								namespace  JS  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  ASTNode : : generate_bytecode ( Bytecode : : Generator & )  const  
						 
					
						
							
								
									
										
										
										
											2021-06-04 11:31:13 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  Bytecode : : CodeGenerationError  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        this , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        " Missing generate_bytecode() " sv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-04 11:31:13 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  ScopeNode : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
									
										
										
										
											2021-06-04 11:31:13 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-04-03 02:13:51 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Note: SwitchStatement has its own codegen, but still calls into this function to handle the scoping of the switch body.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  is_switch_statement  =  is < SwitchStatement > ( * this ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-16 16:34:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    bool  did_create_lexical_environment  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-03 02:13:51 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( is < BlockStatement > ( * this )  | |  is_switch_statement )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:48:45 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( has_lexical_declarations ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-16 16:34:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            generator . block_declaration_instantiation ( * this ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            did_create_lexical_environment  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:48:45 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-03 02:13:51 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( is_switch_statement ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:48:45 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else  if  ( is < Program > ( * this ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-15 12:36:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // GlobalDeclarationInstantiation is handled by the C++ AO.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:48:45 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-15 09:14:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // FunctionDeclarationInstantiation is handled by the C++ AO.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:48:45 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 19:57:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto &  child  :  children ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-06 14:17:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        TRY ( child - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 19:57:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( generator . is_current_block_terminated ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-16 16:34:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( did_create_lexical_environment ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:48:45 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . end_variable_scope ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-04 11:31:13 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  EmptyStatement : : generate_bytecode ( Bytecode : : Generator & )  const  
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:47:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:47:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  ExpressionStatement : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
									
										
										
										
											2021-06-04 11:31:13 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  m_expression - > generate_bytecode ( generator ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-04 11:31:13 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  BinaryExpression : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
									
										
										
										
											2021-06-04 11:31:13 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TRY ( m_lhs - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:58:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  lhs_reg  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Store > ( lhs_reg ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-04 11:31:13 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TRY ( m_rhs - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-04 11:31:13 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    switch  ( m_op )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  BinaryOp : : Addition : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:58:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Add > ( lhs_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-04 11:31:13 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    case  BinaryOp : : Subtraction : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:58:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Sub > ( lhs_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 19:17:20 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : Multiplication : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:58:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Mul > ( lhs_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 19:17:20 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : Division : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:58:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Div > ( lhs_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 19:37:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : Modulo : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:58:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Mod > ( lhs_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 19:37:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : Exponentiation : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:58:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Exp > ( lhs_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 19:57:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : GreaterThan : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:58:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : GreaterThan > ( lhs_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 19:57:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : GreaterThanEquals : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:58:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : GreaterThanEquals > ( lhs_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-04 12:03:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : LessThan : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:58:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : LessThan > ( lhs_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 19:57:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : LessThanEquals : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:58:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : LessThanEquals > ( lhs_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-24 00:06:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : LooselyInequals : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : LooselyInequals > ( lhs_reg ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:58:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-24 00:06:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : LooselyEquals : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : LooselyEquals > ( lhs_reg ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:58:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-24 00:06:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : StrictlyInequals : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : StrictlyInequals > ( lhs_reg ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:58:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-24 00:06:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : StrictlyEquals : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : StrictlyEquals > ( lhs_reg ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:58:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 19:16:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : BitwiseAnd : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:58:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : BitwiseAnd > ( lhs_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 19:16:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : BitwiseOr : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:58:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : BitwiseOr > ( lhs_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 19:16:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : BitwiseXor : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:58:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : BitwiseXor > ( lhs_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:14:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : LeftShift : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:58:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : LeftShift > ( lhs_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:14:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : RightShift : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:58:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : RightShift > ( lhs_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:14:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : UnsignedRightShift : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:58:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : UnsignedRightShift > ( lhs_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 21:13:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : In : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:58:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : In > ( lhs_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 21:18:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  BinaryOp : : InstanceOf : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:58:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : InstanceOf > ( lhs_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-04 11:31:13 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    default : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 21:18:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-04 11:31:13 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-04 11:31:13 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  LogicalExpression : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
									
										
										
										
											2021-06-08 02:18:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TRY ( m_lhs - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-08 02:18:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // lhs
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // jump op (true) end (false) rhs
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // rhs
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // jump always (true) end
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // end
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  rhs_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  end_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-08 02:18:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    switch  ( m_op )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  LogicalOp : : And : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : JumpConditional > ( ) . set_targets ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Bytecode : : Label  {  rhs_block  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Bytecode : : Label  {  end_block  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-08 02:18:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  LogicalOp : : Or : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : JumpConditional > ( ) . set_targets ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Bytecode : : Label  {  end_block  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Bytecode : : Label  {  rhs_block  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-08 02:18:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  LogicalOp : : NullishCoalescing : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : JumpNullish > ( ) . set_targets ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Bytecode : : Label  {  rhs_block  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Bytecode : : Label  {  end_block  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-08 02:18:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . switch_to_basic_block ( rhs_block ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TRY ( m_rhs - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Jump > ( ) . set_targets ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Bytecode : : Label  {  end_block  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        { } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . switch_to_basic_block ( end_block ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-08 02:18:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  UnaryExpression : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
									
										
										
										
											2021-06-07 19:53:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-03-27 19:50:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_op  = =  UnaryOp : : Delete ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  generator . emit_delete_reference ( m_lhs ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 23:12:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Typeof needs some special handling for when the LHS is an Identifier. Namely, it shouldn't throw on unresolvable references, but instead return "undefined".
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_op  ! =  UnaryOp : : Typeof ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        TRY ( m_lhs - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 19:53:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    switch  ( m_op )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  UnaryOp : : BitwiseNot : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:58:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : BitwiseNot > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 19:53:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  UnaryOp : : Not : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:58:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Not > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 19:53:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  UnaryOp : : Plus : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:58:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : UnaryPlus > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 19:53:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  UnaryOp : : Minus : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:58:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : UnaryMinus > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 19:53:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  UnaryOp : : Typeof : 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 23:12:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( is < Identifier > ( * m_lhs ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto &  identifier  =  static_cast < Identifier  const & > ( * m_lhs ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : TypeofVariable > ( generator . intern_identifier ( identifier . string ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        TRY ( m_lhs - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:58:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Typeof > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 19:53:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  UnaryOp : : Void : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:58:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : LoadImmediate > ( js_undefined ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-27 19:50:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  UnaryOp : : Delete :  // Delete is implemented above.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 19:53:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    default : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-27 19:50:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 19:53:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 19:53:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  NumericLiteral : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
									
										
										
										
											2021-06-04 11:31:13 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:58:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : LoadImmediate > ( m_value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-04 11:31:13 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  BooleanLiteral : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:22:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:58:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : LoadImmediate > ( Value ( m_value ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:22:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  NullLiteral : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:22:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:58:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : LoadImmediate > ( js_null ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:22:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  BigIntLiteral : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
									
										
										
										
											2021-06-08 07:59:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-10-19 19:17:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 1. Return the NumericValue of NumericLiteral as defined in 12.8.3.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  integer  =  [ & ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( m_value [ 0 ]  = =  ' 0 '  & &  m_value . length ( )  > =  3 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( m_value [ 1 ]  = =  ' x '  | |  m_value [ 1 ]  = =  ' X ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  Crypto : : SignedBigInteger : : from_base ( 16 ,  m_value . substring ( 2 ,  m_value . length ( )  -  3 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( m_value [ 1 ]  = =  ' o '  | |  m_value [ 1 ]  = =  ' O ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  Crypto : : SignedBigInteger : : from_base ( 8 ,  m_value . substring ( 2 ,  m_value . length ( )  -  3 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( m_value [ 1 ]  = =  ' b '  | |  m_value [ 1 ]  = =  ' B ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  Crypto : : SignedBigInteger : : from_base ( 2 ,  m_value . substring ( 2 ,  m_value . length ( )  -  3 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  Crypto : : SignedBigInteger : : from_base ( 10 ,  m_value . substring ( 0 ,  m_value . length ( )  -  1 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : NewBigInt > ( integer ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-08 07:59:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  StringLiteral : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
									
										
										
										
											2021-06-04 11:31:13 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-06-09 10:02:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : NewString > ( generator . intern_string ( m_value ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-04 11:31:13 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  RegExpLiteral : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
									
										
										
										
											2021-06-19 17:17:40 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  source_index  =  generator . intern_string ( m_pattern ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  flags_index  =  generator . intern_string ( m_flags ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : NewRegExp > ( source_index ,  flags_index ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 17:17:40 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  Identifier : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
									
										
										
										
											2021-06-04 11:31:13 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-10-24 15:34:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : GetVariable > ( generator . intern_identifier ( m_string ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-04 11:31:13 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-05 19:02:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  Bytecode : : CodeGenerationErrorOr < void >  arguments_to_array_for_call ( Bytecode : : Generator &  generator ,  ReadonlySpan < CallExpression : : Argument >  arguments )  
						 
					
						
							
								
									
										
										
										
											2022-09-09 16:05:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( arguments . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : NewArray > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  first_spread  =  find_if ( arguments . begin ( ) ,  arguments . end ( ) ,  [ ] ( auto  el )  {  return  el . is_spread ;  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Bytecode : : Register  args_start_reg  {  0  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto  it  =  arguments . begin ( ) ;  it  ! =  first_spread ;  + + it )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  reg  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( args_start_reg . index ( )  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            args_start_reg  =  reg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    u32  i  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto  it  =  arguments . begin ( ) ;  it  ! =  first_spread ;  + + it ,  + + i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( it - > is_spread  = =  false ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Bytecode : : Register  reg  {  args_start_reg . index ( )  +  i  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        TRY ( it - > value - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Store > ( reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( first_spread . index ( )  ! =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit_with_extra_register_slots < Bytecode : : Op : : NewArray > ( 2u ,  AK : : Array  {  args_start_reg ,  Bytecode : : Register  {  args_start_reg . index ( )  +  static_cast < u32 > ( first_spread . index ( )  -  1 )  }  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : NewArray > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( first_spread  ! =  arguments . end ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  array_reg  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Store > ( array_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( auto  it  =  first_spread ;  it  ! =  arguments . end ( ) ;  + + it )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            TRY ( it - > value - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : Append > ( array_reg ,  it - > is_spread ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Load > ( array_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-30 18:03:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  SuperCall : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_is_synthetic  = =  IsPartOfSyntheticConstructor : : Yes )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // NOTE: This is the case where we have a fake constructor(...args) { super(...args); } which
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //       shouldn't call @@iterator of %Array.prototype%.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( m_arguments . size ( )  = =  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( m_arguments [ 0 ] . is_spread ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  const &  argument  =  m_arguments [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // This generates a single argument, which will be implicitly passed in accumulator
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        MUST ( argument . value - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-09 16:05:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        TRY ( arguments_to_array_for_call ( generator ,  m_arguments ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-30 18:03:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-07 23:39:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : SuperCall > ( m_is_synthetic  = =  IsPartOfSyntheticConstructor : : Yes ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-30 18:03:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-17 19:24:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  Bytecode : : CodeGenerationErrorOr < void >  generate_binding_pattern_bytecode ( Bytecode : : Generator &  generator ,  BindingPattern  const &  pattern ,  Bytecode : : Op : : SetVariable : : InitializationMode ,  Bytecode : : Register  const &  value_reg ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  AssignmentExpression : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
									
										
										
										
											2021-06-04 11:31:13 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-10-25 15:29:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_op  = =  AssignmentOp : : Assignment )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-17 19:23:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // AssignmentExpression : LeftHandSideExpression = AssignmentExpression
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  m_lhs . visit ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // 1. If LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral, then
 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-19 22:07:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            [ & ] ( NonnullRefPtr < Expression  const >  const &  lhs )  - >  Bytecode : : CodeGenerationErrorOr < void >  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-17 19:23:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                // a. Let lref be the result of evaluating LeftHandSideExpression.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // b. ReturnIfAbrupt(lref).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                Optional < Bytecode : : Register >  base_object_register ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                Optional < Bytecode : : Register >  computed_property_register ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( is < MemberExpression > ( * lhs ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    auto &  expression  =  static_cast < MemberExpression  const & > ( * lhs ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    TRY ( expression . object ( ) . generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    base_object_register  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    generator . emit < Bytecode : : Op : : Store > ( * base_object_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( expression . is_computed ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        TRY ( expression . property ( ) . generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        computed_property_register  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        generator . emit < Bytecode : : Op : : Store > ( * computed_property_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        // To be continued later with PutByValue.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    }  else  if  ( expression . property ( ) . is_identifier ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        // Do nothing, this will be handled by PutById later.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-23 08:16:17 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    }  else  if  ( expression . property ( ) . is_private_identifier ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        // Do nothing, this will be handled by PutPrivateById later.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-17 19:23:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        return  Bytecode : : CodeGenerationError  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            & expression , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            " Unimplemented non-computed member expression " sv 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  else  if  ( is < Identifier > ( * lhs ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    // NOTE: For Identifiers, we cannot perform GetVariable and then write into the reference it retrieves, only SetVariable can do this.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    // FIXME: However, this breaks spec as we are doing variable lookup after evaluating the RHS. This is observable in an object environment, where we visibly perform HasOwnProperty and Get(@@unscopables) on the binded object.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    TRY ( lhs - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // FIXME: c. If IsAnonymousFunctionDefinition(AssignmentExpression) and IsIdentifierRef of LeftHandSideExpression are both true, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                //           i. Let rval be ? NamedEvaluation of AssignmentExpression with argument lref.[[ReferencedName]].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // d. Else,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // i. Let rref be the result of evaluating AssignmentExpression.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // ii. Let rval be ? GetValue(rref).
 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-23 14:27:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  ( lhs - > is_identifier ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    TRY ( generator . emit_named_evaluation_if_anonymous_function ( * m_rhs ,  static_cast < Identifier  const & > ( * lhs ) . string ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    TRY ( m_rhs - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-17 19:23:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // e. Perform ? PutValue(lref, rval).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( is < Identifier > ( * lhs ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    auto &  identifier  =  static_cast < Identifier  const & > ( * lhs ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    generator . emit < Bytecode : : Op : : SetVariable > ( generator . intern_identifier ( identifier . string ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  else  if  ( is < MemberExpression > ( * lhs ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    auto &  expression  =  static_cast < MemberExpression  const & > ( * lhs ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( expression . is_computed ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        generator . emit < Bytecode : : Op : : PutByValue > ( * base_object_register ,  * computed_property_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    }  else  if  ( expression . property ( ) . is_identifier ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        auto  identifier_table_ref  =  generator . intern_identifier ( verify_cast < Identifier > ( expression . property ( ) ) . string ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        generator . emit < Bytecode : : Op : : PutById > ( * base_object_register ,  identifier_table_ref ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-23 08:16:17 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    }  else  if  ( expression . property ( ) . is_private_identifier ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        auto  identifier_table_ref  =  generator . intern_identifier ( verify_cast < PrivateIdentifier > ( expression . property ( ) ) . string ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        generator . emit < Bytecode : : Op : : PutPrivateById > ( * base_object_register ,  identifier_table_ref ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-17 19:23:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        return  Bytecode : : CodeGenerationError  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            & expression , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            " Unimplemented non-computed member expression " sv 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    return  Bytecode : : CodeGenerationError  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        lhs , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        " Unimplemented/invalid node used a reference " sv 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // f. Return rval.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // NOTE: This is already in the accumulator.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // 2. Let assignmentPattern be the AssignmentPattern that is covered by LeftHandSideExpression.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-19 22:07:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            [ & ] ( NonnullRefPtr < BindingPattern  const >  const &  pattern )  - >  Bytecode : : CodeGenerationErrorOr < void >  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-17 19:24:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                // 3. Let rref be the result of evaluating AssignmentExpression.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // 4. Let rval be ? GetValue(rref).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                TRY ( m_rhs - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto  value_register  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                generator . emit < Bytecode : : Op : : Store > ( value_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // 5. Perform ? DestructuringAssignmentEvaluation of assignmentPattern with argument rval.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                TRY ( generate_binding_pattern_bytecode ( generator ,  pattern ,  Bytecode : : Op : : SetVariable : : InitializationMode : : Set ,  value_register ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // 6. Return rval.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                generator . emit < Bytecode : : Op : : Load > ( value_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-17 19:23:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-25 15:29:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:12:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-19 22:07:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    VERIFY ( m_lhs . has < NonnullRefPtr < Expression  const > > ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  lhs  =  m_lhs . get < NonnullRefPtr < Expression  const > > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-17 19:23:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TRY ( generator . emit_load_from_reference ( lhs ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:12:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-25 15:29:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Bytecode : : BasicBlock *  rhs_block_ptr  {  nullptr  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Bytecode : : BasicBlock *  end_block_ptr  {  nullptr  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:12:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-25 15:29:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Logical assignments short circuit.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_op  = =  AssignmentOp : : AndAssignment )  {  // &&=
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        rhs_block_ptr  =  & generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        end_block_ptr  =  & generator . make_block ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 21:14:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-25 15:29:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : JumpConditional > ( ) . set_targets ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Bytecode : : Label  {  * rhs_block_ptr  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Bytecode : : Label  {  * end_block_ptr  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  if  ( m_op  = =  AssignmentOp : : OrAssignment )  {  // ||=
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        rhs_block_ptr  =  & generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        end_block_ptr  =  & generator . make_block ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 21:14:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-25 15:29:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : JumpConditional > ( ) . set_targets ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Bytecode : : Label  {  * end_block_ptr  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Bytecode : : Label  {  * rhs_block_ptr  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  if  ( m_op  = =  AssignmentOp : : NullishAssignment )  {  // ??=
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        rhs_block_ptr  =  & generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        end_block_ptr  =  & generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : JumpNullish > ( ) . set_targets ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Bytecode : : Label  {  * rhs_block_ptr  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Bytecode : : Label  {  * end_block_ptr  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-04 11:31:13 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-25 15:29:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( rhs_block_ptr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . switch_to_basic_block ( * rhs_block_ptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // lhs_reg is a part of the rhs_block because the store isn't necessary
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // if the logical assignment condition fails.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  lhs_reg  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Store > ( lhs_reg ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TRY ( m_rhs - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-25 15:29:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    switch  ( m_op )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  AssignmentOp : : AdditionAssignment : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Add > ( lhs_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  AssignmentOp : : SubtractionAssignment : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Sub > ( lhs_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  AssignmentOp : : MultiplicationAssignment : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Mul > ( lhs_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  AssignmentOp : : DivisionAssignment : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Div > ( lhs_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  AssignmentOp : : ModuloAssignment : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Mod > ( lhs_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  AssignmentOp : : ExponentiationAssignment : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Exp > ( lhs_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  AssignmentOp : : BitwiseAndAssignment : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : BitwiseAnd > ( lhs_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  AssignmentOp : : BitwiseOrAssignment : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : BitwiseOr > ( lhs_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  AssignmentOp : : BitwiseXorAssignment : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : BitwiseXor > ( lhs_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  AssignmentOp : : LeftShiftAssignment : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : LeftShift > ( lhs_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  AssignmentOp : : RightShiftAssignment : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : RightShift > ( lhs_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  AssignmentOp : : UnsignedRightShiftAssignment : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : UnsignedRightShift > ( lhs_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  AssignmentOp : : AndAssignment : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  AssignmentOp : : OrAssignment : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  AssignmentOp : : NullishAssignment : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ;  // These are handled above.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    default : 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  Bytecode : : CodeGenerationError  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            this , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            " Unimplemented operation " sv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-04 20:47:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TRY ( generator . emit_store_to_reference ( lhs ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-25 15:29:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( end_block_ptr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Jump > ( ) . set_targets ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Bytecode : : Label  {  * end_block_ptr  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            { } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . switch_to_basic_block ( * end_block_ptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-04 11:31:13 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 23:09:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// 14.13.3 Runtime Semantics: Evaluation, https://tc39.es/ecma262/#sec-labelled-statements-runtime-semantics-evaluation
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  LabelledStatement : LabelIdentifier : LabelledItem
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  LabelledStatement : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Return ? LabelledEvaluation of this LabelledStatement with argument « ».
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  generate_labelled_evaluation ( generator ,  { } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// 14.13.4 Runtime Semantics: LabelledEvaluation, https://tc39.es/ecma262/#sec-runtime-semantics-labelledevaluation
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// LabelledStatement : LabelIdentifier : LabelledItem
  
						 
					
						
							
								
									
										
										
										
											2023-01-08 19:23:00 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  LabelledStatement : : generate_labelled_evaluation ( Bytecode : : Generator &  generator ,  Vector < DeprecatedFlyString >  const &  label_set )  const  
						 
					
						
							
								
									
										
										
										
											2022-06-11 23:09:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Convert the m_labelled_item NNRP to a reference early so we don't have to do it every single time we want to use it.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  const &  labelled_item  =  * m_labelled_item ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 1. Let label be the StringValue of LabelIdentifier.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // NOTE: Not necessary, this is m_label.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 2. Let newLabelSet be the list-concatenation of labelSet and « label ».
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // FIXME: Avoid copy here.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  new_label_set  =  label_set ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    new_label_set . append ( m_label ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 3. Let stmtResult be LabelledEvaluation of LabelledItem with argument newLabelSet.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // NOTE: stmtResult will be in the accumulator after running the generated bytecode.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( is < IterationStatement > ( labelled_item ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  const &  iteration_statement  =  static_cast < IterationStatement  const & > ( labelled_item ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        TRY ( iteration_statement . generate_labelled_evaluation ( generator ,  new_label_set ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  if  ( is < SwitchStatement > ( labelled_item ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  const &  switch_statement  =  static_cast < SwitchStatement  const & > ( labelled_item ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        TRY ( switch_statement . generate_labelled_evaluation ( generator ,  new_label_set ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  if  ( is < LabelledStatement > ( labelled_item ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  const &  labelled_statement  =  static_cast < LabelledStatement  const & > ( labelled_item ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        TRY ( labelled_statement . generate_labelled_evaluation ( generator ,  new_label_set ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  labelled_break_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // NOTE: We do not need a continuable scope as `continue;` is not allowed outside of iteration statements, throwing a SyntaxError in the parser.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . begin_breakable_scope ( Bytecode : : Label  {  labelled_break_block  } ,  new_label_set ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        TRY ( labelled_item . generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . end_breakable_scope ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! generator . is_current_block_terminated ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : Jump > ( ) . set_targets ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                Bytecode : : Label  {  labelled_break_block  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                { } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . switch_to_basic_block ( labelled_break_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 4. If stmtResult.[[Type]] is break and SameValue(stmtResult.[[Target]], label) is true, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //    a. Set stmtResult to NormalCompletion(stmtResult.[[Value]]).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // NOTE: These steps are performed by making labelled break jump straight to the appropriate break block, which preserves the statement result's value in the accumulator.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 5. Return Completion(stmtResult).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // NOTE: This is in the accumulator.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-08 19:23:00 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  IterationStatement : : generate_labelled_evaluation ( Bytecode : : Generator & ,  Vector < DeprecatedFlyString >  const & )  const  
						 
					
						
							
								
									
										
										
										
											2022-06-11 23:09:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  Bytecode : : CodeGenerationError  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        this , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        " Missing generate_labelled_evaluation() " sv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  WhileStatement : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
									
										
										
										
											2022-06-11 23:09:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  generate_labelled_evaluation ( generator ,  { } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-08 19:23:00 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  WhileStatement : : generate_labelled_evaluation ( Bytecode : : Generator &  generator ,  Vector < DeprecatedFlyString >  const &  label_set )  const  
						 
					
						
							
								
									
										
										
										
											2021-06-04 12:07:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // test
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // jump if_false (true) end (false) body
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // body
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // jump always (true) test
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // end
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  test_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  body_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  end_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Init result register
 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-08 22:17:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : LoadImmediate > ( js_undefined ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  result_reg  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Store > ( result_reg ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // jump to the test block
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Jump > ( ) . set_targets ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Bytecode : : Label  {  test_block  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        { } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . switch_to_basic_block ( test_block ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TRY ( m_test - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : JumpConditional > ( ) . set_targets ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Bytecode : : Label  {  body_block  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Bytecode : : Label  {  end_block  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . switch_to_basic_block ( body_block ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 23:09:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . begin_continuable_scope ( Bytecode : : Label  {  test_block  } ,  label_set ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . begin_breakable_scope ( Bytecode : : Label  {  end_block  } ,  label_set ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TRY ( m_body - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-14 02:13:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . end_breakable_scope ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . end_continuable_scope ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 19:57:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! generator . is_current_block_terminated ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Jump > ( ) . set_targets ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Bytecode : : Label  {  test_block  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            { } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-30 14:29:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . switch_to_basic_block ( end_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Load > ( result_reg ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-04 12:07:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  DoWhileStatement : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
									
										
										
										
											2022-06-11 23:09:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  generate_labelled_evaluation ( generator ,  { } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-08 19:23:00 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  DoWhileStatement : : generate_labelled_evaluation ( Bytecode : : Generator &  generator ,  Vector < DeprecatedFlyString >  const &  label_set )  const  
						 
					
						
							
								
									
										
										
										
											2021-06-04 12:20:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // jump always (true) body
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // test
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // jump if_false (true) end (false) body
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // body
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // jump always (true) test
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // end
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  test_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  body_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  end_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Init result register
 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-08 22:17:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : LoadImmediate > ( js_undefined ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  result_reg  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Store > ( result_reg ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // jump to the body block
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Jump > ( ) . set_targets ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Bytecode : : Label  {  body_block  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        { } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . switch_to_basic_block ( test_block ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TRY ( m_test - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : JumpConditional > ( ) . set_targets ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Bytecode : : Label  {  body_block  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Bytecode : : Label  {  end_block  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . switch_to_basic_block ( body_block ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 23:09:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . begin_continuable_scope ( Bytecode : : Label  {  test_block  } ,  label_set ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . begin_breakable_scope ( Bytecode : : Label  {  end_block  } ,  label_set ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TRY ( m_body - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-14 02:13:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . end_breakable_scope ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . end_continuable_scope ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 19:57:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! generator . is_current_block_terminated ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Jump > ( ) . set_targets ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Bytecode : : Label  {  test_block  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            { } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-30 14:29:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . switch_to_basic_block ( end_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Load > ( result_reg ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-04 12:20:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  ForStatement : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
									
										
										
										
											2022-06-11 23:09:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  generate_labelled_evaluation ( generator ,  { } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-08 19:23:00 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  ForStatement : : generate_labelled_evaluation ( Bytecode : : Generator &  generator ,  Vector < DeprecatedFlyString >  const &  label_set )  const  
						 
					
						
							
								
									
										
										
										
											2021-06-08 10:54:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // init
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // jump always (true) test
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // test
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // jump if_true (true) body (false) end
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // body
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // jump always (true) update
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // update
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // jump always (true) test
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // end
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // If 'test' is missing, fuse the 'test' and 'body' basic blocks
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // If 'update' is missing, fuse the 'body' and 'update' basic blocks
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Bytecode : : BasicBlock *  test_block_ptr  {  nullptr  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Bytecode : : BasicBlock *  body_block_ptr  {  nullptr  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Bytecode : : BasicBlock *  update_block_ptr  {  nullptr  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  end_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-08 10:54:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-14 02:39:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    bool  has_lexical_environment  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_init )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( m_init - > is_variable_declaration ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto &  variable_declaration  =  verify_cast < VariableDeclaration > ( * m_init ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( variable_declaration . is_lexical_declaration ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                has_lexical_environment  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // FIXME: Is Block correct?
 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-16 16:34:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                generator . begin_variable_scope ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-14 02:39:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                bool  is_const  =  variable_declaration . is_constant_declaration ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-27 22:13:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                // NOTE: Nothing in the callback throws an exception.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                MUST ( variable_declaration . for_each_bound_name ( [ & ] ( auto  const &  name )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-14 02:39:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    auto  index  =  generator . intern_identifier ( name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    generator . emit < Bytecode : : Op : : CreateVariable > ( index ,  Bytecode : : Op : : EnvironmentMode : : Lexical ,  is_const ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-27 22:13:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                } ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-14 02:39:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        TRY ( m_init - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-14 02:39:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:58:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    body_block_ptr  =  & generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_test ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        test_block_ptr  =  & generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        test_block_ptr  =  body_block_ptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_update ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        update_block_ptr  =  & generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        update_block_ptr  =  body_block_ptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-08 22:17:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : LoadImmediate > ( js_undefined ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  result_reg  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Store > ( result_reg ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Jump > ( ) . set_targets ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Bytecode : : Label  {  * test_block_ptr  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        { } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-08 10:54:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_test )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . switch_to_basic_block ( * test_block_ptr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        TRY ( m_test - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : JumpConditional > ( ) . set_targets ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Bytecode : : Label  {  * body_block_ptr  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Bytecode : : Label  {  end_block  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-08 10:54:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:58:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-15 19:13:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_update )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . switch_to_basic_block ( * update_block_ptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        TRY ( m_update - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Jump > ( ) . set_targets ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Bytecode : : Label  {  * test_block_ptr  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            { } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . switch_to_basic_block ( * body_block_ptr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-15 19:13:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . begin_continuable_scope ( Bytecode : : Label  {  m_update  ?  * update_block_ptr  :  * test_block_ptr  } ,  label_set ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-17 19:22:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . begin_breakable_scope ( Bytecode : : Label  {  end_block  } ,  label_set ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TRY ( m_body - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-17 19:22:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . end_breakable_scope ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-08 10:54:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . end_continuable_scope ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 19:57:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! generator . is_current_block_terminated ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( m_update )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : Jump > ( ) . set_targets ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                Bytecode : : Label  {  * update_block_ptr  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                { } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-15 19:13:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : Jump > ( ) . set_targets ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                Bytecode : : Label  {  * test_block_ptr  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                { } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 19:57:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-30 15:55:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . switch_to_basic_block ( end_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Load > ( result_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-15 01:44:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( has_lexical_environment ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . end_variable_scope ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-08 10:54:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  ObjectExpression : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
									
										
										
										
											2021-06-04 20:30:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:58:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : NewObject > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 19:40:48 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_properties . is_empty ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-04 20:30:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 19:40:48 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  object_reg  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Store > ( object_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-16 10:25:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . push_home_object ( object_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 19:40:48 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto &  property  :  m_properties )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 00:59:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        Bytecode : : Op : : PropertyKind  property_kind ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-06 14:17:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        switch  ( property - > type ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 00:59:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        case  ObjectProperty : : Type : : KeyValue : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            property_kind  =  Bytecode : : Op : : PropertyKind : : KeyValue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  ObjectProperty : : Type : : Getter : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            property_kind  =  Bytecode : : Op : : PropertyKind : : Getter ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  ObjectProperty : : Type : : Setter : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            property_kind  =  Bytecode : : Op : : PropertyKind : : Setter ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  ObjectProperty : : Type : : Spread : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            property_kind  =  Bytecode : : Op : : PropertyKind : : Spread ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  ObjectProperty : : Type : : ProtoSetter : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            property_kind  =  Bytecode : : Op : : PropertyKind : : ProtoSetter ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 19:40:48 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-03-06 14:17:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( is < StringLiteral > ( property - > key ( ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto &  string_literal  =  static_cast < StringLiteral  const & > ( property - > key ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-24 15:34:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            Bytecode : : IdentifierTableIndex  key_name  =  generator . intern_identifier ( string_literal . value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 19:40:48 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 00:59:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( property_kind  ! =  Bytecode : : Op : : PropertyKind : : Spread ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-06 14:17:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                TRY ( property - > value ( ) . generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 00:59:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : PutById > ( object_reg ,  key_name ,  property_kind ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 19:40:48 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-06 14:17:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            TRY ( property - > key ( ) . generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 19:40:48 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto  property_reg  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : Store > ( property_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 00:59:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( property_kind  ! =  Bytecode : : Op : : PropertyKind : : Spread ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-06 14:17:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                TRY ( property - > value ( ) . generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 00:59:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : PutByValue > ( object_reg ,  property_reg ,  property_kind ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 19:40:48 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Load > ( object_reg ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-16 10:25:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . pop_home_object ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-04 20:30:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  ArrayExpression : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
									
										
										
										
											2021-06-08 23:06:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-09-09 15:23:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_elements . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : NewArray > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-14 14:48:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-08 23:06:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-09 15:23:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  first_spread  =  find_if ( m_elements . begin ( ) ,  m_elements . end ( ) ,  [ ] ( auto  el )  {  return  el  & &  is < SpreadExpression > ( * el ) ;  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Bytecode : : Register  args_start_reg  {  0  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto  it  =  m_elements . begin ( ) ;  it  ! =  first_spread ;  + + it )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  reg  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( args_start_reg . index ( )  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            args_start_reg  =  reg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    u32  i  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto  it  =  m_elements . begin ( ) ;  it  ! =  first_spread ;  + + it ,  + + i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Bytecode : : Register  reg  {  args_start_reg . index ( )  +  i  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! * it ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 04:43:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : LoadImmediate > ( Value  { } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-09 15:23:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            TRY ( ( * it ) - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-08 23:06:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-09 15:23:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Store > ( reg ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-08 23:06:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-09 15:23:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( first_spread . index ( )  ! =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit_with_extra_register_slots < Bytecode : : Op : : NewArray > ( 2u ,  AK : : Array  {  args_start_reg ,  Bytecode : : Register  {  args_start_reg . index ( )  +  static_cast < u32 > ( first_spread . index ( )  -  1 )  }  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-14 14:48:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : NewArray > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-09 15:23:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( first_spread  ! =  m_elements . end ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  array_reg  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Store > ( array_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( auto  it  =  first_spread ;  it  ! =  m_elements . end ( ) ;  + + it )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! * it )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                generator . emit < Bytecode : : Op : : LoadImmediate > ( Value  { } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                generator . emit < Bytecode : : Op : : Append > ( array_reg ,  false ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                TRY ( ( * it ) - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                generator . emit < Bytecode : : Op : : Append > ( array_reg ,  * it  & &  is < SpreadExpression > ( * * it ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Load > ( array_reg ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-14 14:48:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-09 15:23:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-08 23:06:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  MemberExpression : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
									
										
										
										
											2021-06-04 21:03:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  generator . emit_load_from_reference ( * this ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-04 21:03:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:48:45 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  FunctionDeclaration : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
									
										
										
										
											2021-06-05 15:15:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:48:45 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_is_hoisted )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  index  =  generator . intern_identifier ( name ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : GetVariable > ( index ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 12:43:45 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : SetVariable > ( index ,  Bytecode : : Op : : SetVariable : : InitializationMode : : Set ,  Bytecode : : Op : : EnvironmentMode : : Var ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:48:45 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-05 15:15:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-23 14:27:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  FunctionExpression : : generate_bytecode_with_lhs_name ( Bytecode : : Generator &  generator ,  Optional < DeprecatedFlyString  const & >  lhs_name )  const  
						 
					
						
							
								
									
										
										
										
											2021-06-11 10:46:46 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-06-11 23:24:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    bool  has_name  =  ! name ( ) . is_empty ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Optional < Bytecode : : IdentifierTableIndex >  name_identifier ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( has_name )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-16 16:34:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . begin_variable_scope ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 23:24:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        name_identifier  =  generator . intern_identifier ( name ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : CreateVariable > ( * name_identifier ,  Bytecode : : Op : : EnvironmentMode : : Lexical ,  true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-23 14:27:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . emit_new_function ( * this ,  lhs_name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 23:24:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( has_name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : SetVariable > ( * name_identifier ,  Bytecode : : Op : : SetVariable : : InitializationMode : : Initialize ,  Bytecode : : Op : : EnvironmentMode : : Lexical ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . end_variable_scope ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 10:46:46 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-23 14:27:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  FunctionExpression : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  generate_bytecode_with_lhs_name ( generator ,  { } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  Bytecode : : CodeGenerationErrorOr < void >  generate_object_binding_pattern_bytecode ( Bytecode : : Generator &  generator ,  BindingPattern  const &  pattern ,  Bytecode : : Op : : SetVariable : : InitializationMode  initialization_mode ,  Bytecode : : Register  const &  value_reg )  
						 
					
						
							
								
									
										
										
										
											2021-06-13 12:24:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-06-13 15:30:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Vector < Bytecode : : Register >  excluded_property_names ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  has_rest  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( pattern . entries . size ( )  >  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        has_rest  =  pattern . entries [ pattern . entries . size ( )  -  1 ] . is_rest ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 12:24:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto &  [ name ,  alias ,  initializer ,  is_rest ]  :  pattern . entries )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 15:30:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( is_rest )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-19 22:07:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            VERIFY ( name . has < NonnullRefPtr < Identifier  const > > ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 15:30:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            VERIFY ( alias . has < Empty > ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            VERIFY ( ! initializer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-19 22:07:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto  identifier  =  name . get < NonnullRefPtr < Identifier  const > > ( ) - > string ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-24 15:34:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto  interned_identifier  =  generator . intern_identifier ( identifier ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 15:30:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            generator . emit_with_extra_register_slots < Bytecode : : Op : : CopyObjectExcludingProperties > ( excluded_property_names . size ( ) ,  value_reg ,  excluded_property_names ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : SetVariable > ( interned_identifier ,  initialization_mode ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 15:30:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 15:30:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 12:24:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 13:40:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        Bytecode : : StringTableIndex  name_index ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 12:24:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-19 22:07:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( name . has < NonnullRefPtr < Identifier  const > > ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  identifier  =  name . get < NonnullRefPtr < Identifier  const > > ( ) - > string ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 13:40:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            name_index  =  generator . intern_string ( identifier ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 15:30:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( has_rest )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto  excluded_name_reg  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                excluded_property_names . append ( excluded_name_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                generator . emit < Bytecode : : Op : : NewString > ( name_index ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                generator . emit < Bytecode : : Op : : Store > ( excluded_name_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 13:40:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : Load > ( value_reg ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-24 15:34:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : GetById > ( generator . intern_identifier ( identifier ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 13:40:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-19 22:07:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto  expression  =  name . get < NonnullRefPtr < Expression  const > > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            TRY ( expression - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 15:30:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( has_rest )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto  excluded_name_reg  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                excluded_property_names . append ( excluded_name_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                generator . emit < Bytecode : : Op : : Store > ( excluded_name_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 13:40:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : GetByValue > ( value_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 12:24:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 13:40:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( initializer )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto &  if_undefined_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto &  if_not_undefined_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 12:24:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 13:40:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : JumpUndefined > ( ) . set_targets ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                Bytecode : : Label  {  if_undefined_block  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                Bytecode : : Label  {  if_not_undefined_block  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 12:24:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 13:40:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            generator . switch_to_basic_block ( if_undefined_block ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-23 14:27:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( auto  const *  lhs  =  name . get_pointer < NonnullRefPtr < Identifier  const > > ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                TRY ( generator . emit_named_evaluation_if_anonymous_function ( * initializer ,  ( * lhs ) - > string ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                TRY ( initializer - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 13:40:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : Jump > ( ) . set_targets ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                Bytecode : : Label  {  if_not_undefined_block  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                { } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 12:24:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 13:40:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            generator . switch_to_basic_block ( if_not_undefined_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 12:24:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-19 22:07:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( alias . has < NonnullRefPtr < BindingPattern  const > > ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto &  binding_pattern  =  * alias . get < NonnullRefPtr < BindingPattern  const > > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 13:40:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto  nested_value_reg  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : Store > ( nested_value_reg ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            TRY ( generate_binding_pattern_bytecode ( generator ,  binding_pattern ,  initialization_mode ,  nested_value_reg ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 13:40:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  if  ( alias . has < Empty > ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-19 22:07:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( name . has < NonnullRefPtr < Expression  const > > ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 13:40:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                // This needs some sort of SetVariableByValue opcode, as it's a runtime binding
 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  Bytecode : : CodeGenerationError  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-19 22:07:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    name . get < NonnullRefPtr < Expression  const > > ( ) . ptr ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    " Unimplemented name/alias pair: Empty/Expression " sv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 12:24:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 13:40:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-19 22:07:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto &  identifier  =  name . get < NonnullRefPtr < Identifier  const > > ( ) - > string ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : SetVariable > ( generator . intern_identifier ( identifier ) ,  initialization_mode ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 12:24:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-19 22:07:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto &  identifier  =  alias . get < NonnullRefPtr < Identifier  const > > ( ) - > string ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : SetVariable > ( generator . intern_identifier ( identifier ) ,  initialization_mode ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 13:40:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 13:40:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  Bytecode : : CodeGenerationErrorOr < void >  generate_array_binding_pattern_bytecode ( Bytecode : : Generator &  generator ,  BindingPattern  const &  pattern ,  Bytecode : : Op : : SetVariable : : InitializationMode  initialization_mode ,  Bytecode : : Register  const &  value_reg )  
						 
					
						
							
								
									
										
										
										
											2021-06-13 13:40:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    /*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Consider  the  following  destructuring  assignment : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *      let  [ a ,  b ,  c ,  d ,  e ]  =  o ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  It  would  be  fairly  trivial  to  just  loop  through  this  iterator ,  getting  the  value 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  at  each  step  and  assigning  them  to  the  binding  sequentially .  However ,  this  is  not 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  correct :  once  an  iterator  is  exhausted ,  it  must  not  be  called  again .  This  complicates 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  the  bytecode .  In  order  to  accomplish  this ,  we  do  the  following : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  -  Reserve  a  special  boolean  register  which  holds  ' true '  if  the  iterator  is  exhausted , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *    and  false  otherwise 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  -  When  we  are  retrieving  the  value  which  should  be  bound ,  we  first  check  this  register . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *    If  it  is  ' true ' ,  we  load  undefined  into  the  accumulator .  Otherwise ,  we  grab  the  next 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *    value  from  the  iterator  and  store  it  into  the  accumulator . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Note  that  the  is_exhausted  register  does  not  need  to  be  loaded  with  false  because  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  first  IteratorNext  bytecode  is  _not_  proceeded  by  an  exhausted  check ,  as  it  is 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  unnecessary . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  is_iterator_exhausted_register  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  iterator_reg  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Load > ( value_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : GetIterator > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Store > ( iterator_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    bool  first  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  temp_iterator_result_reg  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 14:06:26 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  assign_accumulator_to_alias  =  [ & ] ( auto &  alias )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  alias . visit ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            [ & ] ( Empty )  - >  Bytecode : : CodeGenerationErrorOr < void >  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 14:06:26 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                // This element is an elision
 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 14:06:26 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } , 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-19 22:07:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            [ & ] ( NonnullRefPtr < Identifier  const >  const &  identifier )  - >  Bytecode : : CodeGenerationErrorOr < void >  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-24 15:34:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                auto  interned_index  =  generator . intern_identifier ( identifier - > string ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                generator . emit < Bytecode : : Op : : SetVariable > ( interned_index ,  initialization_mode ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 14:06:26 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } , 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-19 22:07:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            [ & ] ( NonnullRefPtr < BindingPattern  const >  const &  pattern )  - >  Bytecode : : CodeGenerationErrorOr < void >  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 14:06:26 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                // Store the accumulator value in a permanent register
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto  target_reg  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                generator . emit < Bytecode : : Op : : Store > ( target_reg ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  generate_binding_pattern_bytecode ( generator ,  pattern ,  initialization_mode ,  target_reg ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 01:11:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } , 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-19 22:07:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            [ & ] ( NonnullRefPtr < MemberExpression  const >  const &  expr )  - >  Bytecode : : CodeGenerationErrorOr < void >  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 03:09:08 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  generator . emit_store_to_reference ( * expr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 14:06:26 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 13:40:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto &  [ name ,  alias ,  initializer ,  is_rest ]  :  pattern . entries )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( name . has < Empty > ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 14:06:26 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( is_rest )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-17 19:25:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            VERIFY ( ! initializer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 14:06:26 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( first )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // The iterator has not been called, and is thus known to be not exhausted
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                generator . emit < Bytecode : : Op : : Load > ( iterator_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                generator . emit < Bytecode : : Op : : IteratorToArray > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto &  if_exhausted_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto &  if_not_exhausted_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto &  continuation_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                generator . emit < Bytecode : : Op : : Load > ( is_iterator_exhausted_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                generator . emit < Bytecode : : Op : : JumpConditional > ( ) . set_targets ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    Bytecode : : Label  {  if_exhausted_block  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    Bytecode : : Label  {  if_not_exhausted_block  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                generator . switch_to_basic_block ( if_exhausted_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                generator . emit < Bytecode : : Op : : NewArray > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                generator . emit < Bytecode : : Op : : Jump > ( ) . set_targets ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    Bytecode : : Label  {  continuation_block  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    { } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                generator . switch_to_basic_block ( if_not_exhausted_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                generator . emit < Bytecode : : Op : : Load > ( iterator_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                generator . emit < Bytecode : : Op : : IteratorToArray > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                generator . emit < Bytecode : : Op : : Jump > ( ) . set_targets ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    Bytecode : : Label  {  continuation_block  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    { } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                generator . switch_to_basic_block ( continuation_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  assign_accumulator_to_alias ( alias ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 14:06:26 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 13:40:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // In the first iteration of the loop, a few things are true which can save
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // us some bytecode:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //  - the iterator result is still in the accumulator, so we can avoid a load
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //  - the iterator is not yet exhausted, which can save us a jump and some
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //    creation
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  iterator_is_exhausted_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! first )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto &  iterator_is_not_exhausted_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : Load > ( is_iterator_exhausted_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : JumpConditional > ( ) . set_targets ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                Bytecode : : Label  {  iterator_is_exhausted_block  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                Bytecode : : Label  {  iterator_is_not_exhausted_block  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            generator . switch_to_basic_block ( iterator_is_not_exhausted_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : Load > ( iterator_reg ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 12:24:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 13:40:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : IteratorNext > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Store > ( temp_iterator_result_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : IteratorResultDone > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Store > ( is_iterator_exhausted_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // We still have to check for exhaustion here. If the iterator is exhausted,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // we need to bail before trying to get the value
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  no_bail_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : JumpConditional > ( ) . set_targets ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Bytecode : : Label  {  iterator_is_exhausted_block  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Bytecode : : Label  {  no_bail_block  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . switch_to_basic_block ( no_bail_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Get the next value in the iterator
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Load > ( temp_iterator_result_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : IteratorResultValue > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  create_binding_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Jump > ( ) . set_targets ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Bytecode : : Label  {  create_binding_block  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            { } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // The iterator is exhausted, so we just load undefined and continue binding
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . switch_to_basic_block ( iterator_is_exhausted_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : LoadImmediate > ( js_undefined ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Jump > ( ) . set_targets ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Bytecode : : Label  {  create_binding_block  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            { } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Create the actual binding. The value which this entry must bind is now in the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // accumulator. We can proceed, processing the alias as a nested  destructuring
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // pattern if necessary.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . switch_to_basic_block ( create_binding_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-17 19:25:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( initializer )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto &  value_is_undefined_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto &  value_is_not_undefined_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : JumpUndefined > ( ) . set_targets ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                Bytecode : : Label  {  value_is_undefined_block  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                Bytecode : : Label  {  value_is_not_undefined_block  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            generator . switch_to_basic_block ( value_is_undefined_block ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-23 14:27:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( auto  const *  lhs  =  name . get_pointer < NonnullRefPtr < Identifier  const > > ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                TRY ( generator . emit_named_evaluation_if_anonymous_function ( * initializer ,  ( * lhs ) - > string ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                TRY ( initializer - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-17 19:25:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : Jump > ( Bytecode : : Label  {  value_is_not_undefined_block  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            generator . switch_to_basic_block ( value_is_not_undefined_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        TRY ( assign_accumulator_to_alias ( alias ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 13:40:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        first  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 13:40:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  Bytecode : : CodeGenerationErrorOr < void >  generate_binding_pattern_bytecode ( Bytecode : : Generator &  generator ,  BindingPattern  const &  pattern ,  Bytecode : : Op : : SetVariable : : InitializationMode  initialization_mode ,  Bytecode : : Register  const &  value_reg )  
						 
					
						
							
								
									
										
										
										
											2021-06-13 13:40:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( pattern . kind  = =  BindingPattern : : Kind : : Object ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  generate_object_binding_pattern_bytecode ( generator ,  pattern ,  initialization_mode ,  value_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  generate_array_binding_pattern_bytecode ( generator ,  pattern ,  initialization_mode ,  value_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2021-06-13 12:24:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 20:18:19 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  Bytecode : : CodeGenerationErrorOr < void >  assign_accumulator_to_variable_declarator ( Bytecode : : Generator &  generator ,  VariableDeclarator  const &  declarator ,  VariableDeclaration  const &  declaration )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  initialization_mode  =  declaration . is_lexical_declaration ( )  ?  Bytecode : : Op : : SetVariable : : InitializationMode : : Initialize  :  Bytecode : : Op : : SetVariable : : InitializationMode : : Set ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  declarator . target ( ) . visit ( 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-19 22:07:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        [ & ] ( NonnullRefPtr < Identifier  const >  const &  id )  - >  Bytecode : : CodeGenerationErrorOr < void >  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-13 13:37:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : SetVariable > ( generator . intern_identifier ( id - > string ( ) ) ,  initialization_mode ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 20:18:19 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } , 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-19 22:07:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        [ & ] ( NonnullRefPtr < BindingPattern  const >  const &  pattern )  - >  Bytecode : : CodeGenerationErrorOr < void >  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 20:18:19 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto  value_register  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : Store > ( value_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  generate_binding_pattern_bytecode ( generator ,  pattern ,  initialization_mode ,  value_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  VariableDeclaration : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
									
										
										
										
											2021-06-10 00:29:17 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-06-10 22:12:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto &  declarator  :  m_declarations )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-17 15:16:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( declarator - > init ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-23 14:27:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( auto  const *  lhs  =  declarator - > target ( ) . get_pointer < NonnullRefPtr < Identifier  const > > ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                TRY ( generator . emit_named_evaluation_if_anonymous_function ( * declarator - > init ( ) ,  ( * lhs ) - > string ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                TRY ( declarator - > init ( ) - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-17 15:16:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            TRY ( assign_accumulator_to_variable_declarator ( generator ,  declarator ,  * this ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  if  ( m_declaration_kind  ! =  DeclarationKind : : Var )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 22:12:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : LoadImmediate > ( js_undefined ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-17 15:16:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            TRY ( assign_accumulator_to_variable_declarator ( generator ,  declarator ,  * this ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 22:12:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 00:29:17 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-17 14:50:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  Bytecode : : CodeGenerationErrorOr < void >  get_base_and_value_from_member_expression ( Bytecode : : Generator &  generator ,  MemberExpression  const &  member_expression ,  Bytecode : : Register  this_reg )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // https://tc39.es/ecma262/#sec-super-keyword-runtime-semantics-evaluation
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( is < SuperExpression > ( member_expression . object ( ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 1. Let env be GetThisEnvironment().
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 2. Let actualThis be ? env.GetThisBinding().
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : ResolveThisBinding > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Store > ( this_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Optional < Bytecode : : Register >  computed_property_value_register ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( member_expression . is_computed ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // SuperProperty : super [ Expression ]
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // 3. Let propertyNameReference be ? Evaluation of Expression.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // 4. Let propertyNameValue be ? GetValue(propertyNameReference).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            TRY ( member_expression . property ( ) . generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            computed_property_value_register  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : Store > ( * computed_property_value_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 5/7. Return ? MakeSuperPropertyReference(actualThis, propertyKey, strict).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // https://tc39.es/ecma262/#sec-makesuperpropertyreference
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 1. Let env be GetThisEnvironment().
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 2. Assert: env.HasSuperBinding() is true.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 3. Let baseValue be ? env.GetSuperBase().
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : ResolveSuperBase > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 4. Return the Reference Record { [[Base]]: baseValue, [[ReferencedName]]: propertyKey, [[Strict]]: strict, [[ThisValue]]: actualThis }.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( computed_property_value_register . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // 5. Let propertyKey be ? ToPropertyKey(propertyNameValue).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // FIXME: This does ToPropertyKey out of order, which is observable by Symbol.toPrimitive!
 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-17 18:42:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto  super_base_register  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : Store > ( super_base_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : Load > ( * computed_property_value_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : GetByValue > ( super_base_register ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-17 14:50:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // 3. Let propertyKey be StringValue of IdentifierName.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  identifier_table_ref  =  generator . intern_identifier ( verify_cast < Identifier > ( member_expression . property ( ) ) . string ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : GetById > ( identifier_table_ref ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        TRY ( member_expression . object ( ) . generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Store > ( this_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( member_expression . is_computed ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            TRY ( member_expression . property ( ) . generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : GetByValue > ( this_reg ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-23 17:09:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  if  ( is < PrivateIdentifier > ( member_expression . property ( ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : GetPrivateById > ( generator . intern_identifier ( verify_cast < PrivateIdentifier > ( member_expression . property ( ) ) . string ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-17 14:50:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-23 17:09:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : GetById > ( generator . intern_identifier ( verify_cast < Identifier > ( member_expression . property ( ) ) . string ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-17 14:50:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  Bytecode : : CodeGenerationErrorOr < void >  generate_optional_chain ( Bytecode : : Generator &  generator ,  OptionalChain  const &  optional_chain ,  Bytecode : : Register  current_value_register ,  Bytecode : : Register  current_base_register ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  CallExpression : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
									
										
										
										
											2021-06-05 15:15:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:58:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  callee_reg  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-05 15:15:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  this_reg  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:58:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : LoadImmediate > ( js_undefined ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Store > ( this_reg ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-05 15:15:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 01:36:10 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( is < NewExpression > ( this ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        TRY ( m_callee - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 01:36:10 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Store > ( callee_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  if  ( is < MemberExpression > ( * m_callee ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-01 20:58:27 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto &  member_expression  =  static_cast < MemberExpression  const & > ( * m_callee ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-17 14:50:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        TRY ( get_base_and_value_from_member_expression ( generator ,  member_expression ,  this_reg ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Store > ( callee_reg ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-17 14:50:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else  if  ( is < OptionalChain > ( * m_callee ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  optional_chain  =  static_cast < OptionalChain  const & > ( * m_callee ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        TRY ( generate_optional_chain ( generator ,  optional_chain ,  callee_reg ,  this_reg ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 01:36:10 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // FIXME: this = global object in sloppy mode.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        TRY ( m_callee - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 01:36:10 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Store > ( callee_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-26 19:51:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TRY ( arguments_to_array_for_call ( generator ,  arguments ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 23:01:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Bytecode : : Op : : Call : : CallType  call_type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( is < NewExpression > ( * this ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        call_type  =  Bytecode : : Op : : Call : : CallType : : Construct ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-15 13:16:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else  if  ( m_callee - > is_identifier ( )  & &  static_cast < Identifier  const & > ( * m_callee ) . string ( )  = =  " eval " sv )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        call_type  =  Bytecode : : Op : : Call : : CallType : : DirectEval ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 23:01:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        call_type  =  Bytecode : : Op : : Call : : CallType : : Call ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-01 01:36:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Optional < Bytecode : : StringTableIndex >  expression_string_index ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( auto  expression_string  =  this - > expression_string ( ) ;  expression_string . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        expression_string_index  =  generator . intern_string ( expression_string . release_value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Call > ( call_type ,  callee_reg ,  this_reg ,  expression_string_index ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-05 15:15:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  ReturnStatement : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
									
										
										
										
											2021-06-05 15:53:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-06-08 16:29:21 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_argument ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        TRY ( m_argument - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 23:13:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : LoadImmediate > ( js_undefined ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 01:38:30 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 11:51:02 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( generator . is_in_generator_or_async_function ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . perform_needed_unwinds < Bytecode : : Op : : Yield > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 01:38:30 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Yield > ( nullptr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 11:51:02 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . perform_needed_unwinds < Bytecode : : Op : : Return > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 01:38:30 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Return > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 11:51:02 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 01:38:30 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  YieldExpression : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
									
										
										
										
											2021-06-11 01:38:30 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY ( generator . is_in_generator_function ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-25 23:14:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  received_completion_register  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  received_completion_type_register  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  received_completion_value_register  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  type_identifier  =  generator . intern_identifier ( " type " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  value_identifier  =  generator . intern_identifier ( " value " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  get_received_completion_type_and_value  =  [ & ] ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // The accumulator is set to an object, for example: { "type": 1 (normal), value: 1337 }
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Store > ( received_completion_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : GetById > ( type_identifier ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Store > ( received_completion_type_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Load > ( received_completion_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : GetById > ( value_identifier ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Store > ( received_completion_value_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_is_yield_from )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-09 18:48:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // 15.5.5 Runtime Semantics: Evaluation, https://tc39.es/ecma262/#sec-generator-function-definitions-runtime-semantics-evaluation
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // FIXME: 1. Let generatorKind be GetGeneratorKind().
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 2. Let exprRef be ? Evaluation of AssignmentExpression.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 3. Let value be ? GetValue(exprRef).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( m_argument ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        TRY ( m_argument - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 4. Let iteratorRecord be ? GetIterator(value, generatorKind).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // FIXME: Consider generatorKind.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  iterator_record_register  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : GetIterator > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Store > ( iterator_record_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 5. Let iterator be iteratorRecord.[[Iterator]].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  iterator_register  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  iterator_identifier  =  generator . intern_identifier ( " iterator " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : GetById > ( iterator_identifier ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Store > ( iterator_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Cache iteratorRecord.[[NextMethod]] for use in step 7.a.i.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  next_method_register  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  next_method_identifier  =  generator . intern_identifier ( " next " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Load > ( iterator_record_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : GetById > ( next_method_identifier ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Store > ( next_method_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 6. Let received be NormalCompletion(undefined).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // See get_received_completion_type_and_value above.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : LoadImmediate > ( Value ( to_underlying ( Completion : : Type : : Normal ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Store > ( received_completion_type_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : LoadImmediate > ( js_undefined ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Store > ( received_completion_value_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 7. Repeat,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  loop_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  continuation_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  loop_end_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Jump > ( Bytecode : : Label  {  loop_block  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . switch_to_basic_block ( loop_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // a. If received.[[Type]] is normal, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  type_is_normal_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  is_type_throw_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : LoadImmediate > ( Value ( to_underlying ( Completion : : Type : : Normal ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : StrictlyEquals > ( received_completion_type_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : JumpConditional > ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Bytecode : : Label  {  type_is_normal_block  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Bytecode : : Label  {  is_type_throw_block  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . switch_to_basic_block ( type_is_normal_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // i. Let innerResult be ? Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]], « received.[[Value]] »).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit_with_extra_register_slots < Bytecode : : Op : : NewArray > ( 2 ,  AK : : Array  {  received_completion_value_register ,  received_completion_value_register  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Call > ( Bytecode : : Op : : Call : : CallType : : Call ,  next_method_register ,  iterator_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // FIXME: ii. If generatorKind is async, set innerResult to ? Await(innerResult).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // iii. If innerResult is not an Object, throw a TypeError exception.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : ThrowIfNotObject > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  inner_result_register  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Store > ( inner_result_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // iv. Let done be ? IteratorComplete(innerResult).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : IteratorResultDone > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // v. If done is true, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  type_is_normal_done_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  type_is_normal_not_done_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : JumpConditional > ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Bytecode : : Label  {  type_is_normal_done_block  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Bytecode : : Label  {  type_is_normal_not_done_block  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . switch_to_basic_block ( type_is_normal_done_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 1. Return ? IteratorValue(innerResult).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Load > ( inner_result_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : IteratorResultValue > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Jump > ( Bytecode : : Label  {  loop_end_block  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . switch_to_basic_block ( type_is_normal_not_done_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // FIXME: vi. If generatorKind is async, set received to Completion(AsyncGeneratorYield(? IteratorValue(innerResult))).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // vii. Else, set received to Completion(GeneratorYield(innerResult)).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // FIXME: Else,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Load > ( inner_result_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // FIXME: Yield currently only accepts a Value, not an object conforming to the IteratorResult interface, so we have to do an observable lookup of `value` here.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : IteratorResultValue > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Yield > ( Bytecode : : Label  {  continuation_block  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // b. Else if received.[[Type]] is throw, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . switch_to_basic_block ( is_type_throw_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  type_is_throw_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  type_is_return_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : LoadImmediate > ( Value ( to_underlying ( Completion : : Type : : Throw ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : StrictlyEquals > ( received_completion_type_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : JumpConditional > ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Bytecode : : Label  {  type_is_throw_block  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Bytecode : : Label  {  type_is_return_block  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . switch_to_basic_block ( type_is_throw_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // i. Let throw be ? GetMethod(iterator, "throw").
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  throw_method_register  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  throw_identifier  =  generator . intern_identifier ( " throw " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Load > ( iterator_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : GetMethod > ( throw_identifier ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Store > ( throw_method_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // ii. If throw is not undefined, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  throw_method_is_defined_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  throw_method_is_undefined_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : LoadImmediate > ( js_undefined ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : StrictlyInequals > ( throw_method_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : JumpConditional > ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Bytecode : : Label  {  throw_method_is_defined_block  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Bytecode : : Label  {  throw_method_is_undefined_block  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . switch_to_basic_block ( throw_method_is_defined_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 1. Let innerResult be ? Call(throw, iterator, « received.[[Value]] »).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit_with_extra_register_slots < Bytecode : : Op : : NewArray > ( 2 ,  AK : : Array  {  received_completion_value_register ,  received_completion_value_register  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Call > ( Bytecode : : Op : : Call : : CallType : : Call ,  throw_method_register ,  iterator_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // FIXME: 2. If generatorKind is async, set innerResult to ? Await(innerResult).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 3. NOTE: Exceptions from the inner iterator throw method are propagated. Normal completions from an inner throw method are processed similarly to an inner next.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 4. If innerResult is not an Object, throw a TypeError exception.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : ThrowIfNotObject > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Store > ( inner_result_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 5. Let done be ? IteratorComplete(innerResult).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : IteratorResultDone > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 6. If done is true, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  type_is_throw_done_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  type_is_throw_not_done_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : JumpConditional > ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Bytecode : : Label  {  type_is_throw_done_block  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Bytecode : : Label  {  type_is_throw_not_done_block  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . switch_to_basic_block ( type_is_throw_done_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // a. Return ? IteratorValue(innerResult).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Load > ( inner_result_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : IteratorResultValue > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Jump > ( Bytecode : : Label  {  loop_end_block  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . switch_to_basic_block ( type_is_throw_not_done_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // FIXME: 7. If generatorKind is async, set received to Completion(AsyncGeneratorYield(? IteratorValue(innerResult))).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 8. Else, set received to Completion(GeneratorYield(innerResult)).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // FIXME: Else,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Load > ( inner_result_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // FIXME: Yield currently only accepts a Value, not an object conforming to the IteratorResult interface, so we have to do an observable lookup of `value` here.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : IteratorResultValue > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Yield > ( Bytecode : : Label  {  continuation_block  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . switch_to_basic_block ( throw_method_is_undefined_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 1. NOTE: If iterator does not have a throw method, this throw is going to terminate the yield* loop. But first we need to give iterator a chance to clean up.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 2. Let closeCompletion be Completion Record { [[Type]]: normal, [[Value]]: empty, [[Target]]: empty }.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // FIXME: 3. If generatorKind is async, perform ? AsyncIteratorClose(iteratorRecord, closeCompletion).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 4. Else, perform ? IteratorClose(iteratorRecord, closeCompletion).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // FIXME: Else,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Load > ( iterator_record_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : IteratorClose > ( Completion : : Type : : Normal ,  Optional < Value >  { } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 5. NOTE: The next step throws a TypeError to indicate that there was a yield* protocol violation: iterator does not have a throw method.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 6. Throw a TypeError exception.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : NewTypeError > ( generator . intern_string ( ErrorType : : YieldFromIteratorMissingThrowMethod . message ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . perform_needed_unwinds < Bytecode : : Op : : Throw > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Throw > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // c. Else,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // i. Assert: received.[[Type]] is return.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . switch_to_basic_block ( type_is_return_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // ii. Let return be ? GetMethod(iterator, "return").
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  return_method_register  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  return_identifier  =  generator . intern_identifier ( " return " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Load > ( iterator_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : GetMethod > ( return_identifier ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Store > ( return_method_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // iii. If return is undefined, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  return_is_undefined_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  return_is_defined_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : LoadImmediate > ( js_undefined ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : StrictlyEquals > ( return_method_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : JumpConditional > ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Bytecode : : Label  {  return_is_undefined_block  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Bytecode : : Label  {  return_is_defined_block  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . switch_to_basic_block ( return_is_undefined_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // FIXME: 1. If generatorKind is async, set received.[[Value]] to ? Await(received.[[Value]]).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 2. Return ? received.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // NOTE: This will always be a return completion.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Load > ( received_completion_value_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . perform_needed_unwinds < Bytecode : : Op : : Yield > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Yield > ( nullptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . switch_to_basic_block ( return_is_defined_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // iv. Let innerReturnResult be ? Call(return, iterator, « received.[[Value]] »).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit_with_extra_register_slots < Bytecode : : Op : : NewArray > ( 2 ,  AK : : Array  {  received_completion_value_register ,  received_completion_value_register  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Call > ( Bytecode : : Op : : Call : : CallType : : Call ,  return_method_register ,  iterator_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // FIXME: v. If generatorKind is async, set innerReturnResult to ? Await(innerReturnResult).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // vi. If innerReturnResult is not an Object, throw a TypeError exception.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : ThrowIfNotObject > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  inner_return_result_register  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Store > ( inner_return_result_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // vii. Let done be ? IteratorComplete(innerReturnResult).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : IteratorResultDone > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // viii. If done is true, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  type_is_return_done_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  type_is_return_not_done_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : JumpConditional > ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Bytecode : : Label  {  type_is_return_done_block  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Bytecode : : Label  {  type_is_return_not_done_block  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . switch_to_basic_block ( type_is_return_done_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 1. Let value be ? IteratorValue(innerReturnResult).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Load > ( inner_result_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : IteratorResultValue > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 2. Return Completion Record { [[Type]]: return, [[Value]]: value, [[Target]]: empty }.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . perform_needed_unwinds < Bytecode : : Op : : Yield > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Yield > ( nullptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . switch_to_basic_block ( type_is_return_not_done_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // FIXME: ix. If generatorKind is async, set received to Completion(AsyncGeneratorYield(? IteratorValue(innerReturnResult))).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // x. Else, set received to Completion(GeneratorYield(innerReturnResult)).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // FIXME: Else,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Load > ( inner_return_result_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // FIXME: Yield currently only accepts a Value, not an object conforming to the IteratorResult interface, so we have to do an observable lookup of `value` here.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : IteratorResultValue > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Yield > ( Bytecode : : Label  {  continuation_block  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . switch_to_basic_block ( continuation_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        get_received_completion_type_and_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Jump > ( Bytecode : : Label  {  loop_block  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . switch_to_basic_block ( loop_end_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-14 15:46:41 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 01:38:30 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_argument ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        TRY ( m_argument - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-25 23:14:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : LoadImmediate > ( js_undefined ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 01:38:30 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  continuation_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Yield > ( Bytecode : : Label  {  continuation_block  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . switch_to_basic_block ( continuation_block ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-25 23:14:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    get_received_completion_type_and_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  normal_completion_continuation_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  throw_completion_continuation_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : LoadImmediate > ( Value ( to_underlying ( Completion : : Type : : Normal ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : StrictlyEquals > ( received_completion_type_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : JumpConditional > ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Bytecode : : Label  {  normal_completion_continuation_block  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Bytecode : : Label  {  throw_completion_continuation_block  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  throw_value_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  return_value_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . switch_to_basic_block ( throw_completion_continuation_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : LoadImmediate > ( Value ( to_underlying ( Completion : : Type : : Throw ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : StrictlyEquals > ( received_completion_type_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // If type is not equal to "throw" or "normal", assume it's "return".
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : JumpConditional > ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Bytecode : : Label  {  throw_value_block  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Bytecode : : Label  {  return_value_block  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . switch_to_basic_block ( throw_value_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Load > ( received_completion_value_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . perform_needed_unwinds < Bytecode : : Op : : Throw > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Throw > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . switch_to_basic_block ( return_value_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Load > ( received_completion_value_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . perform_needed_unwinds < Bytecode : : Op : : Yield > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Yield > ( nullptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . switch_to_basic_block ( normal_completion_continuation_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Load > ( received_completion_value_register ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-05 15:53:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  IfStatement : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
									
										
										
										
											2021-06-06 13:26:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // test
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // jump if_true (true) true (false) false
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // true
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // jump always (true) end
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // false
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // jump always (true) end
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // end
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  true_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  false_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TRY ( m_predicate - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : JumpConditional > ( ) . set_targets ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Bytecode : : Label  {  true_block  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Bytecode : : Label  {  false_block  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Bytecode : : Op : : Jump *  true_block_jump  {  nullptr  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-06 13:26:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . switch_to_basic_block ( true_block ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-20 12:38:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : LoadImmediate > ( js_undefined ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TRY ( m_consequent - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! generator . is_current_block_terminated ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        true_block_jump  =  & generator . emit < Bytecode : : Op : : Jump > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . switch_to_basic_block ( false_block ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-20 12:38:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto &  end_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-20 12:38:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : LoadImmediate > ( js_undefined ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_alternate ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        TRY ( m_alternate - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-20 12:38:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! generator . is_current_block_terminated ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Jump > ( ) . set_targets ( Bytecode : : Label  {  end_block  } ,  { } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-20 12:38:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( true_block_jump ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        true_block_jump - > set_targets ( Bytecode : : Label  {  end_block  } ,  { } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-20 12:38:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . switch_to_basic_block ( end_block ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-06 13:26:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  ContinueStatement : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
									
										
										
										
											2021-06-06 13:33:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-11-13 20:56:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // FIXME: Handle finally blocks in a graceful manner
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //        We need to execute the finally block, but tell it to resume
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //        execution at the designated block
 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 23:09:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_target_label . is_null ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-25 16:35:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . generate_continue ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 23:09:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-25 16:35:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . generate_continue ( m_target_label ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-06 13:33:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  DebuggerStatement : : generate_bytecode ( Bytecode : : Generator & )  const  
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:05:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:05:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  ConditionalExpression : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
									
										
										
										
											2021-06-08 04:54:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // test
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // jump if_true (true) true (false) false
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // true
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // jump always (true) end
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // false
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // jump always (true) end
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // end
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  true_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  false_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  end_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TRY ( m_test - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : JumpConditional > ( ) . set_targets ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Bytecode : : Label  {  true_block  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Bytecode : : Label  {  false_block  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-08 04:54:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . switch_to_basic_block ( true_block ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TRY ( m_consequent - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Jump > ( ) . set_targets ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Bytecode : : Label  {  end_block  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        { } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-08 04:54:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . switch_to_basic_block ( false_block ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TRY ( m_alternate - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Jump > ( ) . set_targets ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Bytecode : : Label  {  end_block  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        { } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-08 04:54:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 06:49:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . switch_to_basic_block ( end_block ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-08 04:54:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  SequenceExpression : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
									
										
										
										
											2021-06-08 10:13:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto &  expression  :  m_expressions ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-06 14:17:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        TRY ( expression - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-08 10:13:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  TemplateLiteral : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
									
										
										
										
											2021-06-08 19:14:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:58:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  string_reg  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-08 19:14:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:58:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( size_t  i  =  0 ;  i  <  m_expressions . size ( ) ;  i + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-06 14:17:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        TRY ( m_expressions [ i ] - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 20:58:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( i  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : Store > ( string_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : ConcatString > ( string_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-08 19:14:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 21:11:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Load > ( string_reg ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-08 19:14:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2021-06-09 11:40:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  TaggedTemplateLiteral : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
									
										
										
										
											2021-06-09 21:02:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TRY ( m_tag - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 22:07:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  tag_reg  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Store > ( tag_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-07 23:39:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // FIXME: We only need to record the first and last register,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //        due to packing everything in an array, same goes for argument_regs
 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 21:02:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Vector < Bytecode : : Register >  string_regs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  expressions  =  m_template_literal - > expressions ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-14 14:48:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( size_t  i  =  0 ;  i  <  expressions . size ( ) ;  + + i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( i  %  2  ! =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        string_regs . append ( generator . allocate_register ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    size_t  reg_index  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 21:02:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( size_t  i  =  0 ;  i  <  expressions . size ( ) ;  + + i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( i  %  2  ! =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-03-06 14:17:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        TRY ( expressions [ i ] - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-14 14:48:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  string_reg  =  string_regs [ reg_index + + ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 21:02:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Store > ( string_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-14 14:48:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( string_regs . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : NewArray > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit_with_extra_register_slots < Bytecode : : Op : : NewArray > ( 2u ,  AK : : Array  {  string_regs . first ( ) ,  string_regs . last ( )  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 21:02:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  strings_reg  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Store > ( strings_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Vector < Bytecode : : Register >  argument_regs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    argument_regs . append ( strings_reg ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-07 23:39:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( size_t  i  =  1 ;  i  <  expressions . size ( ) ;  i  + =  2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        argument_regs . append ( generator . allocate_register ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 21:02:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-07 23:39:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( size_t  i  =  1 ;  i  <  expressions . size ( ) ;  i  + =  2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  string_reg  =  argument_regs [ 1  +  i  /  2 ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-06 14:17:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        TRY ( expressions [ i ] - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 21:02:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Store > ( string_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Vector < Bytecode : : Register >  raw_string_regs ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-14 14:48:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( [[maybe_unused]]  auto &  raw_string  :  m_template_literal - > raw_strings ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        string_regs . append ( generator . allocate_register ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    reg_index  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 21:02:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto &  raw_string  :  m_template_literal - > raw_strings ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-06 14:17:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        TRY ( raw_string - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-14 14:48:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  raw_string_reg  =  string_regs [ reg_index + + ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 21:02:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Store > ( raw_string_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        raw_string_regs . append ( raw_string_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-14 14:48:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( raw_string_regs . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : NewArray > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit_with_extra_register_slots < Bytecode : : Op : : NewArray > ( 2u ,  AK : : Array  {  raw_string_regs . first ( ) ,  raw_string_regs . last ( )  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 21:02:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  raw_strings_reg  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Store > ( raw_strings_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-15 16:36:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : PutById > ( strings_reg ,  generator . intern_identifier ( " raw " ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 21:02:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : LoadImmediate > ( js_undefined ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  this_reg  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Store > ( this_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-07 23:39:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! argument_regs . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit_with_extra_register_slots < Bytecode : : Op : : NewArray > ( 2 ,  AK : : Array  {  argument_regs . first ( ) ,  argument_regs . last ( )  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : NewArray > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Call > ( Bytecode : : Op : : Call : : CallType : : Call ,  tag_reg ,  this_reg ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 21:02:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  UpdateExpression : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
									
										
										
										
											2021-06-09 11:40:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TRY ( generator . emit_load_from_reference ( * m_argument ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 11:40:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-25 15:17:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Optional < Bytecode : : Register >  previous_value_for_postfix_reg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! m_prefixed )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        previous_value_for_postfix_reg  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-16 10:51:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : ToNumeric > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-25 15:17:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Store > ( * previous_value_for_postfix_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 11:40:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-25 15:17:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_op  = =  UpdateOp : : Increment ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Increment > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Decrement > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 11:40:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TRY ( generator . emit_store_to_reference ( * m_argument ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 11:40:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-25 15:17:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! m_prefixed ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Load > ( * previous_value_for_postfix_reg ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 11:40:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  ThrowStatement : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
									
										
										
										
											2021-06-09 18:18:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TRY ( m_argument - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-14 02:26:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . perform_needed_unwinds < Bytecode : : Op : : Throw > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 18:18:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Throw > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 18:18:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  BreakStatement : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
									
										
										
										
											2021-06-10 20:28:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-11-13 20:56:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // FIXME: Handle finally blocks in a graceful manner
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //        We need to execute the finally block, but tell it to resume
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //        execution at the designated block
 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 23:09:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_target_label . is_null ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-25 16:15:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . generate_break ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 23:09:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-25 16:15:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . generate_break ( m_target_label ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 20:28:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  TryStatement : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
									
										
										
										
											2021-06-10 15:04:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  saved_block  =  generator . current_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Optional < Bytecode : : Label >  handler_target ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Optional < Bytecode : : Label >  finalizer_target ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Bytecode : : BasicBlock *  next_block  {  nullptr  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_finalizer )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-25 16:15:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // FIXME: See notes in Op.h->ScheduleJump
 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 15:04:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto &  finalizer_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . switch_to_basic_block ( finalizer_block ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-13 15:58:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : LeaveUnwindContext > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        TRY ( m_finalizer - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 15:04:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ! generator . is_current_block_terminated ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            next_block  =  & generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  next_target  =  Bytecode : : Label  {  * next_block  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : ContinuePendingUnwind > ( next_target ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        finalizer_target  =  Bytecode : : Label  {  finalizer_block  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-13 20:56:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_finalizer ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . start_boundary ( Bytecode : : Generator : : BlockBoundaryType : : ReturnToFinally ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 15:04:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_handler )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  handler_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . switch_to_basic_block ( handler_block ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-13 20:56:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! m_finalizer ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : LeaveUnwindContext > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-16 16:34:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . begin_variable_scope ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        TRY ( m_handler - > parameter ( ) . visit ( 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-08 19:23:00 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            [ & ] ( DeprecatedFlyString  const &  parameter )  - >  Bytecode : : CodeGenerationErrorOr < void >  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-24 22:46:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  ( ! parameter . is_empty ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-14 02:38:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    auto  parameter_identifier  =  generator . intern_identifier ( parameter ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    generator . emit < Bytecode : : Op : : CreateVariable > ( parameter_identifier ,  Bytecode : : Op : : EnvironmentMode : : Lexical ,  false ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    generator . emit < Bytecode : : Op : : SetVariable > ( parameter_identifier ,  Bytecode : : Op : : SetVariable : : InitializationMode : : Initialize ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:15:38 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:15:38 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } , 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-19 22:07:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            [ & ] ( NonnullRefPtr < BindingPattern  const >  const & )  - >  Bytecode : : CodeGenerationErrorOr < void >  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-06 07:07:15 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                // FIXME: Implement this path when the above DeclarativeEnvironment issue is dealt with.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  Bytecode : : CodeGenerationError  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    this , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    " Unimplemented catch argument: BindingPattern " sv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:15:38 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        TRY ( m_handler - > body ( ) . generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 15:04:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        handler_target  =  Bytecode : : Label  {  handler_block  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-14 02:38:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . end_variable_scope ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 15:04:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ! generator . is_current_block_terminated ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( m_finalizer )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                generator . emit < Bytecode : : Op : : Jump > ( finalizer_target ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                VERIFY ( ! next_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                next_block  =  & generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto  next_target  =  Bytecode : : Label  {  * next_block  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                generator . emit < Bytecode : : Op : : Jump > ( next_target ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-13 20:56:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_finalizer ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . end_boundary ( Bytecode : : Generator : : BlockBoundaryType : : ReturnToFinally ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 15:04:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 20:39:40 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto &  target_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 15:04:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . switch_to_basic_block ( saved_block ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 20:39:40 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : EnterUnwindContext > ( Bytecode : : Label  {  target_block  } ,  handler_target ,  finalizer_target ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 11:51:02 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . start_boundary ( Bytecode : : Generator : : BlockBoundaryType : : Unwind ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-13 20:56:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_finalizer ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . start_boundary ( Bytecode : : Generator : : BlockBoundaryType : : ReturnToFinally ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 20:39:40 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . switch_to_basic_block ( target_block ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TRY ( m_block - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-10 22:22:26 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! generator . is_current_block_terminated ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( m_finalizer )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : Jump > ( finalizer_target ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-13 18:50:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( ! next_block ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                next_block  =  & generator . make_block ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-13 18:38:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : LeaveUnwindContext > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-13 18:50:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : Jump > ( Bytecode : : Label  {  * next_block  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-10 22:22:26 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-13 20:56:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_finalizer ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . end_boundary ( Bytecode : : Generator : : BlockBoundaryType : : ReturnToFinally ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 11:51:02 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . end_boundary ( Bytecode : : Generator : : BlockBoundaryType : : Unwind ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 15:04:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . switch_to_basic_block ( next_block  ?  * next_block  :  saved_block ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 15:04:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  SwitchStatement : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
									
										
										
										
											2022-06-11 23:09:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  generate_labelled_evaluation ( generator ,  { } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-08 19:23:00 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  SwitchStatement : : generate_labelled_evaluation ( Bytecode : : Generator &  generator ,  Vector < DeprecatedFlyString >  const &  label_set )  const  
						 
					
						
							
								
									
										
										
										
											2021-06-11 00:36:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  discriminant_reg  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TRY ( m_discriminant - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 00:36:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Store > ( discriminant_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Vector < Bytecode : : BasicBlock & >  case_blocks ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Bytecode : : BasicBlock *  default_block  {  nullptr  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Bytecode : : BasicBlock *  next_test_block  =  & generator . make_block ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-03 02:13:51 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  has_lexical_block  =  has_lexical_declarations ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Note: This call ends up calling begin_variable_scope() if has_lexical_block is true, so we need to clean up after it at the end.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    TRY ( ScopeNode : : generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 00:36:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Jump > ( ) . set_targets ( Bytecode : : Label  {  * next_test_block  } ,  { } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-03 02:13:51 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 00:36:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto &  switch_case  :  m_cases )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  case_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-06 14:17:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( switch_case - > test ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 00:36:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            generator . switch_to_basic_block ( * next_test_block ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-06 14:17:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            TRY ( switch_case - > test ( ) - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-24 00:06:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : StrictlyEquals > ( discriminant_reg ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 00:36:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            next_test_block  =  & generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : JumpConditional > ( ) . set_targets ( Bytecode : : Label  {  case_block  } ,  Bytecode : : Label  {  * next_test_block  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            default_block  =  & case_block ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case_blocks . append ( case_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . switch_to_basic_block ( * next_test_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  end_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( default_block  ! =  nullptr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Jump > ( ) . set_targets ( Bytecode : : Label  {  * default_block  } ,  { } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : LoadImmediate > ( js_undefined ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Jump > ( ) . set_targets ( Bytecode : : Label  {  end_block  } ,  { } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  current_block  =  case_blocks . begin ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 23:09:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . begin_breakable_scope ( Bytecode : : Label  {  end_block  } ,  label_set ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 00:36:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto &  switch_case  :  m_cases )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . switch_to_basic_block ( * current_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : LoadImmediate > ( js_undefined ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-06 14:17:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        for  ( auto &  statement  :  switch_case - > children ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            TRY ( statement - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-15 01:43:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( generator . is_current_block_terminated ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 00:36:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! generator . is_current_block_terminated ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  next_block  =  current_block ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            next_block + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( next_block . is_end ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                generator . emit < Bytecode : : Op : : Jump > ( ) . set_targets ( Bytecode : : Label  {  end_block  } ,  { } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                generator . emit < Bytecode : : Op : : Jump > ( ) . set_targets ( Bytecode : : Label  {  * next_block  } ,  { } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        current_block + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . end_breakable_scope ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-03 02:13:51 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( has_lexical_block ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . end_variable_scope ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 00:36:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . switch_to_basic_block ( end_block ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 00:36:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:55:40 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  ClassDeclaration : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
									
										
										
										
											2021-06-30 15:42:13 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:55:40 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TRY ( m_class_expression - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : SetVariable > ( generator . intern_identifier ( m_class_expression . ptr ( ) - > name ( ) ) ,  Bytecode : : Op : : SetVariable : : InitializationMode : : Initialize ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-23 14:27:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  ClassExpression : : generate_bytecode_with_lhs_name ( Bytecode : : Generator &  generator ,  Optional < DeprecatedFlyString  const & >  lhs_name )  const  
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:55:40 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2023-06-23 14:27:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : NewClass > ( * this ,  lhs_name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:55:40 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-30 15:42:13 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-23 14:27:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  ClassExpression : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  generate_bytecode_with_lhs_name ( generator ,  { } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-02 23:39:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  SpreadExpression : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // NOTE: All users of this should handle the behaviour of this on their own,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //       assuming it returns an Array-like object
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  m_target - > generate_bytecode ( generator ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  ThisExpression : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
									
										
										
										
											2021-10-24 14:43:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : ResolveThisBinding > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-24 14:43:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  AwaitExpression : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
									
										
										
										
											2021-11-11 00:46:07 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY ( generator . is_in_async_function ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-25 17:15:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Transform `await expr` to `yield expr`, see AsyncFunctionDriverWrapper
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // For that we just need to copy most of the code from YieldExpression
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  received_completion_register  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  received_completion_type_register  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  received_completion_value_register  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  type_identifier  =  generator . intern_identifier ( " type " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  value_identifier  =  generator . intern_identifier ( " value " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TRY ( m_argument - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-11 00:46:07 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  continuation_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Yield > ( Bytecode : : Label  {  continuation_block  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . switch_to_basic_block ( continuation_block ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-25 17:15:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // The accumulator is set to an object, for example: { "type": 1 (normal), value: 1337 }
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Store > ( received_completion_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : GetById > ( type_identifier ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Store > ( received_completion_type_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Load > ( received_completion_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : GetById > ( value_identifier ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Store > ( received_completion_value_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  normal_completion_continuation_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  throw_value_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : LoadImmediate > ( Value ( to_underlying ( Completion : : Type : : Normal ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : StrictlyEquals > ( received_completion_type_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : JumpConditional > ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Bytecode : : Label  {  normal_completion_continuation_block  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Bytecode : : Label  {  throw_value_block  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Simplification: The only abrupt completion we receive from AsyncFunctionDriverWrapper is Type::Throw
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //                 So we do not need to account for the Type::Return path
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . switch_to_basic_block ( throw_value_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Load > ( received_completion_value_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . perform_needed_unwinds < Bytecode : : Op : : Throw > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Throw > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . switch_to_basic_block ( normal_completion_continuation_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Load > ( received_completion_value_register ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-12 19:54:08 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-11 00:46:07 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 16:01:18 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  WithStatement : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    TRY ( m_object - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : EnterObjectEnvironment > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-14 02:35:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // EnterObjectEnvironment sets the running execution context's lexical_environment to a new Object Environment.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . start_boundary ( Bytecode : : Generator : : BlockBoundaryType : : LeaveLexicalEnvironment ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 16:01:18 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TRY ( m_body - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-14 02:35:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . end_boundary ( Bytecode : : Generator : : BlockBoundaryType : : LeaveLexicalEnvironment ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! generator . is_current_block_terminated ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-16 16:43:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : LeaveLexicalEnvironment > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-14 02:35:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 16:01:18 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 20:18:19 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								enum  class  LHSKind  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Assignment , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VarBinding , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    LexicalBinding , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								enum  class  IterationKind  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Enumerate , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Iterate , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    AsyncIterate , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// 14.7.5.6 ForIn/OfHeadEvaluation ( uninitializedBoundNames, expr, iterationKind ), https://tc39.es/ecma262/#sec-runtime-semantics-forinofheadevaluation
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								struct  ForInOfHeadEvaluationResult  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    bool  is_destructuring  {  false  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    LHSKind  lhs_kind  {  LHSKind : : Assignment  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
									
										
										
										
											2023-02-19 22:07:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  Bytecode : : CodeGenerationErrorOr < ForInOfHeadEvaluationResult >  for_in_of_head_evaluation ( Bytecode : : Generator &  generator ,  IterationKind  iteration_kind ,  Variant < NonnullRefPtr < ASTNode  const > ,  NonnullRefPtr < BindingPattern  const > >  const &  lhs ,  NonnullRefPtr < ASTNode  const >  const &  rhs )  
						 
					
						
							
								
									
										
										
										
											2022-03-18 20:18:19 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ForInOfHeadEvaluationResult  result  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-19 17:42:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    bool  entered_lexical_scope  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-19 22:07:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( auto *  ast_ptr  =  lhs . get_pointer < NonnullRefPtr < ASTNode  const > > ( ) ;  ast_ptr  & &  is < VariableDeclaration > ( * * ast_ptr ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 20:18:19 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // 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
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  variable_declaration  =  static_cast < VariableDeclaration  const & > ( * * ast_ptr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-06 14:17:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        result . is_destructuring  =  variable_declaration . declarations ( ) . first ( ) - > target ( ) . has < NonnullRefPtr < BindingPattern  const > > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 20:18:19 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        result . lhs_kind  =  variable_declaration . is_lexical_declaration ( )  ?  LHSKind : : LexicalBinding  :  LHSKind : : VarBinding ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 1. Let oldEnv be the running execution context's LexicalEnvironment.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // NOTE: 'uninitializedBoundNames' refers to the lexical bindings (i.e. Const/Let) present in the second and last form.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 2. If uninitializedBoundNames is not an empty List, then
 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-19 17:42:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 20:18:19 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( variable_declaration . declaration_kind ( )  ! =  DeclarationKind : : Var )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            entered_lexical_scope  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // a. Assert: uninitializedBoundNames has no duplicate entries.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // b. Let newEnv be NewDeclarativeEnvironment(oldEnv).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            generator . begin_variable_scope ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // c. For each String name of uninitializedBoundNames, do
 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-27 22:13:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // NOTE: Nothing in the callback throws an exception.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            MUST ( variable_declaration . for_each_bound_name ( [ & ] ( auto  const &  name )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 20:18:19 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                // i. Perform ! newEnv.CreateMutableBinding(name, false).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto  identifier  =  generator . intern_identifier ( name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                generator . emit < Bytecode : : Op : : CreateVariable > ( identifier ,  Bytecode : : Op : : EnvironmentMode : : Lexical ,  false ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-27 22:13:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 20:18:19 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // d. Set the running execution context's LexicalEnvironment to newEnv.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-16 16:43:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // NOTE: Done by CreateLexicalEnvironment.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 20:18:19 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Runtime Semantics: ForInOfLoopEvaluation, for any of:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //  ForInOfStatement : for ( LeftHandSideExpression in Expression ) Statement
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //  ForInOfStatement : for ( LeftHandSideExpression of AssignmentExpression ) Statement
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        result . lhs_kind  =  LHSKind : : Assignment ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-19 17:42:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 20:18:19 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-19 17:42:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 3. Let exprRef be the result of evaluating expr.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    TRY ( rhs - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 4. Set the running execution context's LexicalEnvironment to oldEnv.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( entered_lexical_scope ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . end_variable_scope ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 20:18:19 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-19 17:42:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 5. Let exprValue be ? GetValue(exprRef).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // NOTE: No need to store this anywhere.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 20:18:19 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-19 17:42:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 6. If iterationKind is enumerate, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( iteration_kind  = =  IterationKind : : Enumerate )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // a. If exprValue is undefined or null, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  nullish_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  continuation_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  jump  =  generator . emit < Bytecode : : Op : : JumpNullish > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        jump . set_targets ( Bytecode : : Label  {  nullish_block  } ,  Bytecode : : Label  {  continuation_block  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // i. Return Completion Record { [[Type]]: break, [[Value]]: empty, [[Target]]: empty }.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . switch_to_basic_block ( nullish_block ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-25 16:42:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . generate_break ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-19 17:42:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . switch_to_basic_block ( continuation_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // b. Let obj be ! ToObject(exprValue).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // NOTE: GetObjectPropertyIterator does this.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // c. Let iterator be EnumerateObjectProperties(obj).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // d. Let nextMethod be ! GetV(iterator, "next").
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // e. Return the Iterator Record { [[Iterator]]: iterator, [[NextMethod]]: nextMethod, [[Done]]: false }.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : GetObjectPropertyIterator > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 7. Else,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 20:18:19 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // a. Assert: iterationKind is iterate or async-iterate.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // b. If iterationKind is async-iterate, let iteratorHint be async.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( iteration_kind  = =  IterationKind : : AsyncIterate )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  Bytecode : : CodeGenerationError  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                rhs . ptr ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                " Unimplemented iteration mode: AsyncIterate " sv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // c. Else, let iteratorHint be sync.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // d. Return ? GetIterator(exprValue, iteratorHint).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : GetIterator > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// 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
  
						 
					
						
							
								
									
										
										
										
											2023-02-19 22:07:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  Bytecode : : CodeGenerationErrorOr < void >  for_in_of_body_evaluation ( Bytecode : : Generator &  generator ,  ASTNode  const &  node ,  Variant < NonnullRefPtr < ASTNode  const > ,  NonnullRefPtr < BindingPattern  const > >  const &  lhs ,  ASTNode  const &  body ,  ForInOfHeadEvaluationResult  const &  head_result ,  Vector < DeprecatedFlyString >  const &  label_set ,  Bytecode : : BasicBlock &  loop_end ,  Bytecode : : BasicBlock &  loop_update )  
						 
					
						
							
								
									
										
										
										
											2022-03-18 20:18:19 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  iterator_register  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Store > ( iterator_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // FIXME: Implement this
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //        1. If iteratorKind is not present, set iteratorKind to sync.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 2. Let oldEnv be the running execution context's LexicalEnvironment.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    bool  has_lexical_binding  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 3. Let V be undefined.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // NOTE: We don't need 'V' as the resulting value will naturally flow through via the accumulator register.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 4. Let destructuring be IsDestructuring of lhs.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  destructuring  =  head_result . is_destructuring ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 5. If destructuring is true and if lhsKind is assignment, then
 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-09 18:47:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( destructuring  & &  head_result . lhs_kind  = =  LHSKind : : Assignment )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 20:18:19 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // a. Assert: lhs is a LeftHandSideExpression.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // b. Let assignmentPattern be the AssignmentPattern that is covered by lhs.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // FIXME: Implement this.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  Bytecode : : CodeGenerationError  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            & node , 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-09 18:47:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            " Unimplemented: assignment destructuring in for/of " sv , 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 20:18:19 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 6. Repeat,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Jump > ( Bytecode : : Label  {  loop_update  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . switch_to_basic_block ( loop_update ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 23:09:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . begin_continuable_scope ( Bytecode : : Label  {  loop_update  } ,  label_set ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 20:18:19 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // a. Let nextResult be ? Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]]).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Load > ( iterator_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : IteratorNext > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // FIXME: Implement this:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //        b. If iteratorKind is async, set nextResult to ? Await(nextResult).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // c. If Type(nextResult) is not Object, throw a TypeError exception.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // NOTE: IteratorComplete already does this.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // d. Let done be ? IteratorComplete(nextResult).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  iterator_result_register  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Store > ( iterator_result_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : IteratorResultDone > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // e. If done is true, return V.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  loop_continue  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : JumpConditional > ( ) . set_targets ( Bytecode : : Label  {  loop_end  } ,  Bytecode : : Label  {  loop_continue  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . switch_to_basic_block ( loop_continue ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // f. Let nextValue be ? IteratorValue(nextResult).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Load > ( iterator_result_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : IteratorResultValue > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // g. If lhsKind is either assignment or varBinding, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( head_result . lhs_kind  ! =  LHSKind : : LexicalBinding )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // i. If destructuring is false, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! destructuring )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // 1. Let lhsRef be the result of evaluating lhs. (It may be evaluated repeatedly.)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // NOTE: We're skipping all the completion stuff that the spec does, as the unwinding mechanism will take case of doing that.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( head_result . lhs_kind  = =  LHSKind : : VarBinding )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-19 22:07:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                auto &  declaration  =  static_cast < VariableDeclaration  const & > ( * lhs . get < NonnullRefPtr < ASTNode  const > > ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 20:18:19 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                VERIFY ( declaration . declarations ( ) . size ( )  = =  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                TRY ( assign_accumulator_to_variable_declarator ( generator ,  declaration . declarations ( ) . first ( ) ,  declaration ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-19 22:07:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  ( auto  ptr  =  lhs . get_pointer < NonnullRefPtr < ASTNode  const > > ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 03:09:36 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    TRY ( generator . emit_store_to_reference ( * * ptr ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-19 22:07:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    auto &  binding_pattern  =  lhs . get < NonnullRefPtr < BindingPattern  const > > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-09 18:47:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    auto  value_register  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    generator . emit < Bytecode : : Op : : Store > ( value_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    TRY ( generate_binding_pattern_bytecode ( generator ,  * binding_pattern ,  Bytecode : : Op : : SetVariable : : InitializationMode : : Set ,  value_register ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 03:09:36 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 20:18:19 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // h. Else,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // i. Assert: lhsKind is lexicalBinding.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // ii. Assert: lhs is a ForDeclaration.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // iii. Let iterationEnv be NewDeclarativeEnvironment(oldEnv).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // iv. Perform ForDeclarationBindingInstantiation of lhs with argument iterationEnv.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // v. Set the running execution context's LexicalEnvironment to iterationEnv.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-16 16:34:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generator . begin_variable_scope ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 20:18:19 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        has_lexical_binding  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 14.7.5.4 Runtime Semantics: ForDeclarationBindingInstantiation, https://tc39.es/ecma262/#sec-runtime-semantics-fordeclarationbindinginstantiation
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 1. Assert: environment is a declarative Environment Record.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // NOTE: We just made it.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-19 22:07:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto &  variable_declaration  =  static_cast < VariableDeclaration  const & > ( * lhs . get < NonnullRefPtr < ASTNode  const > > ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 20:18:19 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // 2. For each element name of the BoundNames of ForBinding, do
 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-27 22:13:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // NOTE: Nothing in the callback throws an exception.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        MUST ( variable_declaration . for_each_bound_name ( [ & ] ( auto  const &  name )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 20:18:19 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto  identifier  =  generator . intern_identifier ( name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // a. If IsConstantDeclaration of LetOrConst is true, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( variable_declaration . is_constant_declaration ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // i. Perform ! environment.CreateImmutableBinding(name, true).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                generator . emit < Bytecode : : Op : : CreateVariable > ( identifier ,  Bytecode : : Op : : EnvironmentMode : : Lexical ,  true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // b. Else,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // i. Perform ! environment.CreateMutableBinding(name, false).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                generator . emit < Bytecode : : Op : : CreateVariable > ( identifier ,  Bytecode : : Op : : EnvironmentMode : : Lexical ,  false ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-27 22:13:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 20:18:19 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // 3. Return unused.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // NOTE: No need to do that as we've inlined this.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // vi. If destructuring is false, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! destructuring )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // 1. Assert: lhs binds a single name.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // 2. Let lhsName be the sole element of BoundNames of lhs.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-06 14:17:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto  lhs_name  =  variable_declaration . declarations ( ) . first ( ) - > target ( ) . get < NonnullRefPtr < Identifier  const > > ( ) - > string ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 20:18:19 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // 3. Let lhsRef be ! ResolveBinding(lhsName).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // NOTE: We're skipping all the completion stuff that the spec does, as the unwinding mechanism will take case of doing that.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  identifier  =  generator . intern_identifier ( lhs_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : SetVariable > ( identifier ,  Bytecode : : Op : : SetVariable : : InitializationMode : : Initialize ,  Bytecode : : Op : : EnvironmentMode : : Lexical ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // i. If destructuring is false, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! destructuring )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // i. If lhsRef is an abrupt completion, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //     1. Let status be lhsRef.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // ii. Else if lhsKind is lexicalBinding, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //     1. Let status be Completion(InitializeReferencedBinding(lhsRef, nextValue)).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // iii. Else,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //     1. Let status be Completion(PutValue(lhsRef, nextValue)).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // NOTE: This is performed above.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //    j. Else,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-09 18:47:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // FIXME: i. If lhsKind is assignment, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //           1. Let status be Completion(DestructuringAssignmentEvaluation of assignmentPattern with argument nextValue).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 20:18:19 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        //  ii. Else if lhsKind is varBinding, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //      1. Assert: lhs is a ForBinding.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //      2. Let status be Completion(BindingInitialization of lhs with arguments nextValue and undefined).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //  iii. Else,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //      1. Assert: lhsKind is lexicalBinding.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //      2. Assert: lhs is a ForDeclaration.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //      3. Let status be Completion(ForDeclarationBindingInitialization of lhs with arguments nextValue and iterationEnv).
 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-09 18:47:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( head_result . lhs_kind  = =  LHSKind : : VarBinding  | |  head_result . lhs_kind  = =  LHSKind : : LexicalBinding )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-19 22:07:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto &  declaration  =  static_cast < VariableDeclaration  const & > ( * lhs . get < NonnullRefPtr < ASTNode  const > > ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-09 18:47:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            VERIFY ( declaration . declarations ( ) . size ( )  = =  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-06 14:17:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto &  binding_pattern  =  declaration . declarations ( ) . first ( ) - > target ( ) . get < NonnullRefPtr < BindingPattern  const > > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-09 18:47:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  value_register  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : Store > ( value_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            TRY ( generate_binding_pattern_bytecode ( generator ,  * binding_pattern ,  head_result . lhs_kind  = =  LHSKind : : VarBinding  ?  Bytecode : : Op : : SetVariable : : InitializationMode : : Set  :  Bytecode : : Op : : SetVariable : : InitializationMode : : Initialize ,  value_register ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  Bytecode : : CodeGenerationError  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                & node , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                " Unimplemented: assignment destructuring in for/of " sv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 20:18:19 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // FIXME: Implement iteration closure.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // k. If status is an abrupt completion, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //     i. Set the running execution context's LexicalEnvironment to oldEnv.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //     ii. If iteratorKind is async, return ? AsyncIteratorClose(iteratorRecord, status).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //     iii. If iterationKind is enumerate, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //         1. Return ? status.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //     iv. Else,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //         1. Assert: iterationKind is iterate.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //         2. Return ? IteratorClose(iteratorRecord, status).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // l. Let result be the result of evaluating stmt.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    TRY ( body . generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // m. Set the running execution context's LexicalEnvironment to oldEnv.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( has_lexical_binding ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . end_variable_scope ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . end_continuable_scope ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . end_breakable_scope ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // NOTE: If we're here, then the loop definitely continues.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // n. If LoopContinues(result, labelSet) is false, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //     i. If iterationKind is enumerate, then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //         1. Return ? UpdateEmpty(result, V).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //     ii. Else,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //         1. Assert: iterationKind is iterate.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //         2. Set status to Completion(UpdateEmpty(result, V)).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //         3. If iteratorKind is async, return ? AsyncIteratorClose(iteratorRecord, status).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //         4. Return ? IteratorClose(iteratorRecord, status).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // o. If result.[[Value]] is not empty, set V to result.[[Value]].
 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-27 18:46:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // The body can contain an unconditional block terminator (e.g. return, throw), so we have to check for that before generating the Jump.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! generator . is_current_block_terminated ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : Jump > ( ) . set_targets ( Bytecode : : Label  {  loop_update  } ,  { } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 20:18:19 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . switch_to_basic_block ( loop_end ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  ForInStatement : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
									
										
										
										
											2022-06-11 23:09:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  generate_labelled_evaluation ( generator ,  { } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// 14.7.5.5 Runtime Semantics: ForInOfLoopEvaluation, https://tc39.es/ecma262/#sec-runtime-semantics-forinofloopevaluation
  
						 
					
						
							
								
									
										
										
										
											2023-01-08 19:23:00 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  ForInStatement : : generate_labelled_evaluation ( Bytecode : : Generator &  generator ,  Vector < DeprecatedFlyString >  const &  label_set )  const  
						 
					
						
							
								
									
										
										
										
											2022-03-18 20:18:19 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  loop_end  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  loop_update  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 23:09:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . begin_breakable_scope ( Bytecode : : Label  {  loop_end  } ,  label_set ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 20:18:19 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  head_result  =  TRY ( for_in_of_head_evaluation ( generator ,  IterationKind : : Enumerate ,  m_lhs ,  m_rhs ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Now perform the rest of ForInOfLoopEvaluation, given that the accumulator holds the iterator we're supposed to iterate over.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 23:09:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  for_in_of_body_evaluation ( generator ,  * this ,  m_lhs ,  body ( ) ,  head_result ,  label_set ,  loop_end ,  loop_update ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 20:18:19 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  ForOfStatement : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
									
										
										
										
											2022-06-11 23:09:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  generate_labelled_evaluation ( generator ,  { } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-08 19:23:00 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  ForOfStatement : : generate_labelled_evaluation ( Bytecode : : Generator &  generator ,  Vector < DeprecatedFlyString >  const &  label_set )  const  
						 
					
						
							
								
									
										
										
										
											2022-03-18 20:18:19 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  loop_end  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  loop_update  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 23:09:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . begin_breakable_scope ( Bytecode : : Label  {  loop_end  } ,  label_set ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 20:18:19 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  head_result  =  TRY ( for_in_of_head_evaluation ( generator ,  IterationKind : : Iterate ,  m_lhs ,  m_rhs ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Now perform the rest of ForInOfLoopEvaluation, given that the accumulator holds the iterator we're supposed to iterate over.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 23:09:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  for_in_of_body_evaluation ( generator ,  * this ,  m_lhs ,  body ( ) ,  head_result ,  label_set ,  loop_end ,  loop_update ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 20:18:19 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-19 19:40:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// 13.3.12.1 Runtime Semantics: Evaluation, https://tc39.es/ecma262/#sec-meta-properties-runtime-semantics-evaluation
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  MetaProperty : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // NewTarget : new . target
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_type  = =  MetaProperty : : Type : : NewTarget )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 1. Return GetNewTarget().
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : GetNewTarget > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // ImportMeta : import . meta
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_type  = =  MetaProperty : : Type : : ImportMeta )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  Bytecode : : CodeGenerationError  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            this , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            " Unimplemented meta property: import.meta " sv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2023-06-17 10:11:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  ClassFieldInitializerStatement : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2023-06-23 14:27:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TRY ( generator . emit_named_evaluation_if_anonymous_function ( * m_expression ,  m_class_field_identifier_name ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-17 10:11:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . perform_needed_unwinds < Bytecode : : Op : : Return > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Return > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-17 14:50:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  Bytecode : : CodeGenerationErrorOr < void >  generate_optional_chain ( Bytecode : : Generator &  generator ,  OptionalChain  const &  optional_chain ,  Bytecode : : Register  current_value_register ,  Bytecode : : Register  current_base_register )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( is < MemberExpression > ( optional_chain . base ( ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  member_expression  =  static_cast < MemberExpression  const & > ( optional_chain . base ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        TRY ( get_base_and_value_from_member_expression ( generator ,  member_expression ,  current_base_register ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  if  ( is < OptionalChain > ( optional_chain . base ( ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  sub_optional_chain  =  static_cast < OptionalChain  const & > ( optional_chain . base ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        TRY ( generate_optional_chain ( generator ,  sub_optional_chain ,  current_value_register ,  current_base_register ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        TRY ( optional_chain . base ( ) . generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Store > ( current_value_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  load_undefined_and_jump_to_end_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  end_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto &  reference  :  optional_chain . references ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  is_optional  =  reference . visit ( [ ] ( auto &  ref )  {  return  ref . mode ;  } )  = =  OptionalChain : : Mode : : Optional ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( is_optional )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto &  not_nullish_block  =  generator . make_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            generator . emit < Bytecode : : Op : : JumpNullish > ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                Bytecode : : Label  {  load_undefined_and_jump_to_end_block  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                Bytecode : : Label  {  not_nullish_block  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            generator . switch_to_basic_block ( not_nullish_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        TRY ( reference . visit ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            [ & ] ( OptionalChain : : Call  const &  call )  - >  Bytecode : : CodeGenerationErrorOr < void >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                TRY ( arguments_to_array_for_call ( generator ,  call . arguments ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                generator . emit < Bytecode : : Op : : Call > ( Bytecode : : Op : : Call : : CallType : : Call ,  current_value_register ,  current_base_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                generator . emit < Bytecode : : Op : : Store > ( current_value_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                generator . emit < Bytecode : : Op : : LoadImmediate > ( js_undefined ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                generator . emit < Bytecode : : Op : : Store > ( current_base_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                generator . emit < Bytecode : : Op : : Load > ( current_value_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            [ & ] ( OptionalChain : : ComputedReference  const &  ref )  - >  Bytecode : : CodeGenerationErrorOr < void >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                generator . emit < Bytecode : : Op : : Store > ( current_base_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                TRY ( ref . expression - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                generator . emit < Bytecode : : Op : : GetByValue > ( current_base_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                generator . emit < Bytecode : : Op : : Store > ( current_value_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            [ & ] ( OptionalChain : : MemberReference  const &  ref )  - >  Bytecode : : CodeGenerationErrorOr < void >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                generator . emit < Bytecode : : Op : : Store > ( current_base_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                generator . emit < Bytecode : : Op : : GetById > ( generator . intern_identifier ( ref . identifier - > string ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                generator . emit < Bytecode : : Op : : Store > ( current_value_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } , 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-23 19:09:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            [ & ] ( OptionalChain : : PrivateMemberReference  const &  ref )  - >  Bytecode : : CodeGenerationErrorOr < void >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                generator . emit < Bytecode : : Op : : Store > ( current_base_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                generator . emit < Bytecode : : Op : : GetPrivateById > ( generator . intern_identifier ( ref . private_identifier - > string ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                generator . emit < Bytecode : : Op : : Store > ( current_value_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-17 14:50:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Jump > ( Bytecode : : Label  {  end_block  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . switch_to_basic_block ( load_undefined_and_jump_to_end_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : LoadImmediate > ( js_undefined ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Jump > ( Bytecode : : Label  {  end_block  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . switch_to_basic_block ( end_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  OptionalChain : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  current_base_register  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  current_value_register  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : LoadImmediate > ( js_undefined ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Store > ( current_base_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  generate_optional_chain ( generator ,  * this ,  current_value_register ,  current_base_register ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-24 15:22:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  ImportCall : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    TRY ( m_specifier - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  specifier_reg  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Store > ( specifier_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_options )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        TRY ( m_options - > generate_bytecode ( generator ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        generator . emit < Bytecode : : Op : : LoadImmediate > ( js_undefined ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  options_reg  =  generator . allocate_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : Store > ( options_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : ImportCall > ( specifier_reg ,  options_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-24 16:07:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Bytecode : : CodeGenerationErrorOr < void >  ExportStatement : : generate_bytecode ( Bytecode : : Generator &  generator )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! is_default_export ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( m_statement )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  m_statement - > generate_bytecode ( generator ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY ( m_statement ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( is < FunctionDeclaration > ( * m_statement )  | |  is < ClassDeclaration > ( * m_statement ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  m_statement - > generate_bytecode ( generator ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( is < ClassExpression > ( * m_statement ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        TODO ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // ExportDeclaration : export default AssignmentExpression ;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY ( is < Expression > ( * m_statement ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    TRY ( generator . emit_named_evaluation_if_anonymous_function ( static_cast < Expression  const & > ( * m_statement ) ,  DeprecatedFlyString ( " default " sv ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . emit < Bytecode : : Op : : SetVariable > ( generator . intern_identifier ( " default " sv ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-04 11:31:13 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}