diff --git a/Userland/Libraries/LibJS/AST.h b/Userland/Libraries/LibJS/AST.h index 2e06c10ed1e..deba2be7984 100644 --- a/Userland/Libraries/LibJS/AST.h +++ b/Userland/Libraries/LibJS/AST.h @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -646,6 +647,8 @@ struct BindingPattern : RefCounted { bool contains_expression() const; + Bytecode::CodeGenerationErrorOr generate_bytecode(Bytecode::Generator&, Bytecode::Op::SetVariable::InitializationMode initialization_mode, Bytecode::ScopedOperand const& object, bool create_variables) const; + Vector entries; Kind kind { Kind::Object }; }; diff --git a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp index e15c5a879ae..8fdc2d7eaa4 100644 --- a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp +++ b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp @@ -459,8 +459,6 @@ Bytecode::CodeGenerationErrorOr> SuperCall::generate_byt return dst; } -static Bytecode::CodeGenerationErrorOr generate_binding_pattern_bytecode(Bytecode::Generator& generator, BindingPattern const& pattern, Bytecode::Op::SetVariable::InitializationMode, ScopedOperand const& input_value, bool create_variables); - Bytecode::CodeGenerationErrorOr> AssignmentExpression::generate_bytecode(Bytecode::Generator& generator, Optional preferred_dst) const { Bytecode::Generator::SourceLocationScope scope(generator, *this); @@ -588,7 +586,7 @@ Bytecode::CodeGenerationErrorOr> AssignmentExpression::g auto rval = TRY(m_rhs->generate_bytecode(generator)).value(); // 5. Perform ? DestructuringAssignmentEvaluation of assignmentPattern with argument rval. - TRY(generate_binding_pattern_bytecode(generator, pattern, Bytecode::Op::SetVariable::InitializationMode::Set, rval, false)); + TRY(pattern->generate_bytecode(generator, Bytecode::Op::SetVariable::InitializationMode::Set, rval, false)); // 6. Return rval. return rval; @@ -1265,7 +1263,7 @@ static Bytecode::CodeGenerationErrorOr generate_object_binding_pattern_byt auto& binding_pattern = *alias.get>(); auto nested_value = generator.allocate_register(); generator.emit(nested_value, value); - TRY(generate_binding_pattern_bytecode(generator, binding_pattern, initialization_mode, nested_value, create_variables)); + TRY(binding_pattern.generate_bytecode(generator, initialization_mode, nested_value, create_variables)); } else if (alias.has()) { if (name.has>()) { // This needs some sort of SetVariableByValue opcode, as it's a runtime binding @@ -1336,7 +1334,7 @@ static Bytecode::CodeGenerationErrorOr generate_array_binding_pattern_byte return {}; }, [&](NonnullRefPtr const& pattern) -> Bytecode::CodeGenerationErrorOr { - return generate_binding_pattern_bytecode(generator, pattern, initialization_mode, value, create_variables); + return pattern->generate_bytecode(generator, initialization_mode, value, create_variables); }, [&](NonnullRefPtr const& expr) -> Bytecode::CodeGenerationErrorOr { (void)generator.emit_store_to_reference(*expr, value); @@ -1469,12 +1467,12 @@ static Bytecode::CodeGenerationErrorOr generate_array_binding_pattern_byte return {}; } -static Bytecode::CodeGenerationErrorOr generate_binding_pattern_bytecode(Bytecode::Generator& generator, BindingPattern const& pattern, Bytecode::Op::SetVariable::InitializationMode initialization_mode, ScopedOperand const& input_value, bool create_variables) +Bytecode::CodeGenerationErrorOr BindingPattern::generate_bytecode(Bytecode::Generator& generator, Bytecode::Op::SetVariable::InitializationMode initialization_mode, ScopedOperand const& input_value, bool create_variables) const { - if (pattern.kind == BindingPattern::Kind::Object) - return generate_object_binding_pattern_bytecode(generator, pattern, initialization_mode, input_value, create_variables); + if (kind == Kind::Object) + return generate_object_binding_pattern_bytecode(generator, *this, initialization_mode, input_value, create_variables); - return generate_array_binding_pattern_bytecode(generator, pattern, initialization_mode, input_value, create_variables); + return generate_array_binding_pattern_bytecode(generator, *this, initialization_mode, input_value, create_variables); } static Bytecode::CodeGenerationErrorOr assign_value_to_variable_declarator(Bytecode::Generator& generator, VariableDeclarator const& declarator, VariableDeclaration const& declaration, ScopedOperand value) @@ -1487,7 +1485,7 @@ static Bytecode::CodeGenerationErrorOr assign_value_to_variable_declarator return {}; }, [&](NonnullRefPtr const& pattern) -> Bytecode::CodeGenerationErrorOr { - return generate_binding_pattern_bytecode(generator, pattern, initialization_mode, value, false); + return pattern->generate_bytecode(generator, initialization_mode, value, false); }); } @@ -2563,7 +2561,7 @@ Bytecode::CodeGenerationErrorOr> TryStatement::generate_ [&](NonnullRefPtr const& binding_pattern) -> Bytecode::CodeGenerationErrorOr { generator.begin_variable_scope(); did_create_variable_scope_for_catch_clause = true; - TRY(generate_binding_pattern_bytecode(generator, *binding_pattern, Bytecode::Op::SetVariable::InitializationMode::Initialize, caught_value, true)); + TRY(binding_pattern->generate_bytecode(generator, Bytecode::Op::SetVariable::InitializationMode::Initialize, caught_value, true)); return {}; })); @@ -3076,7 +3074,7 @@ static Bytecode::CodeGenerationErrorOr> for_in_of_body_e TRY(generator.emit_store_to_reference(**ptr, next_value)); } else { auto& binding_pattern = lhs.get>(); - TRY(generate_binding_pattern_bytecode(generator, *binding_pattern, Bytecode::Op::SetVariable::InitializationMode::Set, next_value, false)); + TRY(binding_pattern->generate_bytecode(generator, Bytecode::Op::SetVariable::InitializationMode::Set, next_value, false)); } } } @@ -3161,9 +3159,8 @@ static Bytecode::CodeGenerationErrorOr> for_in_of_body_e auto& declaration = static_cast(*lhs.get>()); VERIFY(declaration.declarations().size() == 1); auto& binding_pattern = declaration.declarations().first()->target().get>(); - (void)TRY(generate_binding_pattern_bytecode( + (void)TRY(binding_pattern->generate_bytecode( generator, - *binding_pattern, head_result.lhs_kind == LHSKind::VarBinding ? Bytecode::Op::SetVariable::InitializationMode::Set : Bytecode::Op::SetVariable::InitializationMode::Initialize, next_value, false));