diff --git a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp index 501bf08909..9dfc601c42 100644 --- a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp +++ b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp @@ -353,7 +353,7 @@ Bytecode::CodeGenerationErrorOr SuperCall::generate_bytecode(Bytecode::Gen return {}; } -static Bytecode::CodeGenerationErrorOr generate_binding_pattern_bytecode(Bytecode::Generator& generator, BindingPattern const& pattern, Bytecode::Op::SetVariable::InitializationMode, Bytecode::Register const& value_reg); +static Bytecode::CodeGenerationErrorOr generate_binding_pattern_bytecode(Bytecode::Generator& generator, BindingPattern const& pattern, Bytecode::Op::SetVariable::InitializationMode, Bytecode::Register const& value_reg, bool create_variables); Bytecode::CodeGenerationErrorOr AssignmentExpression::generate_bytecode(Bytecode::Generator& generator) const { @@ -450,7 +450,7 @@ Bytecode::CodeGenerationErrorOr AssignmentExpression::generate_bytecode(By generator.emit(value_register); // 5. Perform ? DestructuringAssignmentEvaluation of assignmentPattern with argument rval. - TRY(generate_binding_pattern_bytecode(generator, pattern, Bytecode::Op::SetVariable::InitializationMode::Set, value_register)); + TRY(generate_binding_pattern_bytecode(generator, pattern, Bytecode::Op::SetVariable::InitializationMode::Set, value_register, false)); // 6. Return rval. generator.emit(value_register); @@ -991,7 +991,7 @@ Bytecode::CodeGenerationErrorOr FunctionExpression::generate_bytecode(Byte return generate_bytecode_with_lhs_name(generator, {}); } -static Bytecode::CodeGenerationErrorOr generate_object_binding_pattern_bytecode(Bytecode::Generator& generator, BindingPattern const& pattern, Bytecode::Op::SetVariable::InitializationMode initialization_mode, Bytecode::Register const& value_reg) +static Bytecode::CodeGenerationErrorOr generate_object_binding_pattern_bytecode(Bytecode::Generator& generator, BindingPattern const& pattern, Bytecode::Op::SetVariable::InitializationMode initialization_mode, Bytecode::Register const& value_reg, bool create_variables) { Vector excluded_property_names; auto has_rest = false; @@ -1008,6 +1008,8 @@ static Bytecode::CodeGenerationErrorOr generate_object_binding_pattern_byt auto interned_identifier = generator.intern_identifier(identifier); generator.emit_with_extra_register_slots(excluded_property_names.size(), value_reg, excluded_property_names); + if (create_variables) + generator.emit(interned_identifier, Bytecode::Op::EnvironmentMode::Lexical, false); generator.emit(interned_identifier, initialization_mode); return {}; @@ -1066,7 +1068,7 @@ static Bytecode::CodeGenerationErrorOr generate_object_binding_pattern_byt auto& binding_pattern = *alias.get>(); auto nested_value_reg = generator.allocate_register(); generator.emit(nested_value_reg); - TRY(generate_binding_pattern_bytecode(generator, binding_pattern, initialization_mode, nested_value_reg)); + TRY(generate_binding_pattern_bytecode(generator, binding_pattern, initialization_mode, nested_value_reg, create_variables)); } else if (alias.has()) { if (name.has>()) { // This needs some sort of SetVariableByValue opcode, as it's a runtime binding @@ -1077,16 +1079,22 @@ static Bytecode::CodeGenerationErrorOr generate_object_binding_pattern_byt } auto& identifier = name.get>()->string(); - generator.emit(generator.intern_identifier(identifier), initialization_mode); + auto identifier_ref = generator.intern_identifier(identifier); + if (create_variables) + generator.emit(identifier_ref, Bytecode::Op::EnvironmentMode::Lexical, false); + generator.emit(identifier_ref, initialization_mode); } else { auto& identifier = alias.get>()->string(); - generator.emit(generator.intern_identifier(identifier), initialization_mode); + auto identifier_ref = generator.intern_identifier(identifier); + if (create_variables) + generator.emit(identifier_ref, Bytecode::Op::EnvironmentMode::Lexical, false); + generator.emit(identifier_ref, initialization_mode); } } return {}; } -static Bytecode::CodeGenerationErrorOr generate_array_binding_pattern_bytecode(Bytecode::Generator& generator, BindingPattern const& pattern, Bytecode::Op::SetVariable::InitializationMode initialization_mode, Bytecode::Register const& value_reg) +static Bytecode::CodeGenerationErrorOr generate_array_binding_pattern_bytecode(Bytecode::Generator& generator, BindingPattern const& pattern, Bytecode::Op::SetVariable::InitializationMode initialization_mode, Bytecode::Register const& value_reg, bool create_variables) { /* * Consider the following destructuring assignment: @@ -1127,6 +1135,8 @@ static Bytecode::CodeGenerationErrorOr generate_array_binding_pattern_byte }, [&](NonnullRefPtr const& identifier) -> Bytecode::CodeGenerationErrorOr { auto interned_index = generator.intern_identifier(identifier->string()); + if (create_variables) + generator.emit(interned_index, Bytecode::Op::EnvironmentMode::Lexical, false); generator.emit(interned_index, initialization_mode); return {}; }, @@ -1134,7 +1144,7 @@ static Bytecode::CodeGenerationErrorOr generate_array_binding_pattern_byte // Store the accumulator value in a permanent register auto target_reg = generator.allocate_register(); generator.emit(target_reg); - return generate_binding_pattern_bytecode(generator, pattern, initialization_mode, target_reg); + return generate_binding_pattern_bytecode(generator, pattern, initialization_mode, target_reg, create_variables); }, [&](NonnullRefPtr const& expr) -> Bytecode::CodeGenerationErrorOr { return generator.emit_store_to_reference(*expr); @@ -1263,12 +1273,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, Bytecode::Register const& value_reg) +static Bytecode::CodeGenerationErrorOr generate_binding_pattern_bytecode(Bytecode::Generator& generator, BindingPattern const& pattern, Bytecode::Op::SetVariable::InitializationMode initialization_mode, Bytecode::Register const& value_reg, bool create_variables) { if (pattern.kind == BindingPattern::Kind::Object) - return generate_object_binding_pattern_bytecode(generator, pattern, initialization_mode, value_reg); + return generate_object_binding_pattern_bytecode(generator, pattern, initialization_mode, value_reg, create_variables); - return generate_array_binding_pattern_bytecode(generator, pattern, initialization_mode, value_reg); + return generate_array_binding_pattern_bytecode(generator, pattern, initialization_mode, value_reg, create_variables); } static Bytecode::CodeGenerationErrorOr assign_accumulator_to_variable_declarator(Bytecode::Generator& generator, VariableDeclarator const& declarator, VariableDeclaration const& declaration) @@ -1283,7 +1293,7 @@ static Bytecode::CodeGenerationErrorOr assign_accumulator_to_variable_decl [&](NonnullRefPtr const& pattern) -> Bytecode::CodeGenerationErrorOr { auto value_register = generator.allocate_register(); generator.emit(value_register); - return generate_binding_pattern_bytecode(generator, pattern, initialization_mode, value_register); + return generate_binding_pattern_bytecode(generator, pattern, initialization_mode, value_register, false); }); } @@ -2051,12 +2061,11 @@ Bytecode::CodeGenerationErrorOr TryStatement::generate_bytecode(Bytecode:: } return {}; }, - [&](NonnullRefPtr const&) -> Bytecode::CodeGenerationErrorOr { - // FIXME: Implement this path when the above DeclarativeEnvironment issue is dealt with. - return Bytecode::CodeGenerationError { - this, - "Unimplemented catch argument: BindingPattern"sv, - }; + [&](NonnullRefPtr const& binding_pattern) -> Bytecode::CodeGenerationErrorOr { + auto value_register = generator.allocate_register(); + generator.emit(value_register); + TRY(generate_binding_pattern_bytecode(generator, *binding_pattern, Bytecode::Op::SetVariable::InitializationMode::Initialize, value_register, true)); + return {}; })); TRY(m_handler->body().generate_bytecode(generator)); @@ -2457,7 +2466,7 @@ static Bytecode::CodeGenerationErrorOr for_in_of_body_evaluation(Bytecode: auto& binding_pattern = lhs.get>(); auto value_register = generator.allocate_register(); generator.emit(value_register); - TRY(generate_binding_pattern_bytecode(generator, *binding_pattern, Bytecode::Op::SetVariable::InitializationMode::Set, value_register)); + TRY(generate_binding_pattern_bytecode(generator, *binding_pattern, Bytecode::Op::SetVariable::InitializationMode::Set, value_register, false)); } } } @@ -2534,7 +2543,7 @@ static Bytecode::CodeGenerationErrorOr for_in_of_body_evaluation(Bytecode: auto value_register = generator.allocate_register(); generator.emit(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)); + 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, false)); } else { return Bytecode::CodeGenerationError { &node,