diff --git a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp index e770e7773b..5c8be88eb0 100644 --- a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp +++ b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp @@ -845,24 +845,33 @@ Bytecode::CodeGenerationErrorOr ObjectExpression::generate_bytecode(Byteco Bytecode::CodeGenerationErrorOr ArrayExpression::generate_bytecode(Bytecode::Generator& generator) const { Vector element_regs; + for (auto& element : m_elements) { + if (element && is(*element)) { + return Bytecode::CodeGenerationError { + this, + "Unimplemented element kind: SpreadExpression"sv, + }; + } + element_regs.append(generator.allocate_register()); + } + size_t i = 0; for (auto& element : m_elements) { if (element) { TRY(element->generate_bytecode(generator)); - if (is(*element)) { - return Bytecode::CodeGenerationError { - this, - "Unimplemented element kind: SpreadExpression"sv, - }; - } + if (is(*element)) + VERIFY_NOT_REACHED(); } else { generator.emit(Value {}); } - auto element_reg = generator.allocate_register(); + auto& element_reg = element_regs[i++]; generator.emit(element_reg); - element_regs.append(element_reg); } - generator.emit_with_extra_register_slots(element_regs.size(), element_regs); + if (element_regs.is_empty()) { + generator.emit(); + } else { + generator.emit_with_extra_register_slots(2u, AK::Array { element_regs.first(), element_regs.last() }); + } return {}; } @@ -1394,14 +1403,24 @@ Bytecode::CodeGenerationErrorOr TaggedTemplateLiteral::generate_bytecode(B for (size_t i = 0; i < expressions.size(); ++i) { if (i % 2 != 0) continue; - - TRY(expressions[i].generate_bytecode(generator)); - auto string_reg = generator.allocate_register(); - generator.emit(string_reg); - string_regs.append(string_reg); + string_regs.append(generator.allocate_register()); } - generator.emit_with_extra_register_slots(string_regs.size(), string_regs); + size_t reg_index = 0; + for (size_t i = 0; i < expressions.size(); ++i) { + if (i % 2 != 0) + continue; + + TRY(expressions[i].generate_bytecode(generator)); + auto string_reg = string_regs[reg_index++]; + generator.emit(string_reg); + } + + if (string_regs.is_empty()) { + generator.emit(); + } else { + generator.emit_with_extra_register_slots(2u, AK::Array { string_regs.first(), string_regs.last() }); + } auto strings_reg = generator.allocate_register(); generator.emit(strings_reg); @@ -1418,14 +1437,22 @@ Bytecode::CodeGenerationErrorOr TaggedTemplateLiteral::generate_bytecode(B } Vector raw_string_regs; + for ([[maybe_unused]] auto& raw_string : m_template_literal->raw_strings()) + string_regs.append(generator.allocate_register()); + + reg_index = 0; for (auto& raw_string : m_template_literal->raw_strings()) { TRY(raw_string.generate_bytecode(generator)); - auto raw_string_reg = generator.allocate_register(); + auto raw_string_reg = string_regs[reg_index++]; generator.emit(raw_string_reg); raw_string_regs.append(raw_string_reg); } - generator.emit_with_extra_register_slots(raw_string_regs.size(), raw_string_regs); + if (raw_string_regs.is_empty()) { + generator.emit(); + } else { + generator.emit_with_extra_register_slots(2u, AK::Array { raw_string_regs.first(), raw_string_regs.last() }); + } auto raw_strings_reg = generator.allocate_register(); generator.emit(raw_strings_reg); diff --git a/Userland/Libraries/LibJS/Bytecode/Op.cpp b/Userland/Libraries/LibJS/Bytecode/Op.cpp index 795ae98e0e..942725271b 100644 --- a/Userland/Libraries/LibJS/Bytecode/Op.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Op.cpp @@ -129,7 +129,7 @@ ThrowCompletionOr NewArray::execute_impl(Bytecode::Interpreter& interprete { auto* array = MUST(Array::create(interpreter.global_object(), 0)); for (size_t i = 0; i < m_element_count; i++) { - auto& value = interpreter.reg(m_elements[i]); + auto& value = interpreter.reg(Register(m_elements[0].index() + i)); array->indexed_properties().put(i, value, default_attributes); } interpreter.accumulator() = array; diff --git a/Userland/Libraries/LibJS/Bytecode/Op.h b/Userland/Libraries/LibJS/Bytecode/Op.h index b286e925e0..ced232b32e 100644 --- a/Userland/Libraries/LibJS/Bytecode/Op.h +++ b/Userland/Libraries/LibJS/Bytecode/Op.h @@ -232,12 +232,12 @@ public: { } - explicit NewArray(Vector const& elements) + explicit NewArray(AK::Array const& elements_range) : Instruction(Type::NewArray) - , m_element_count(elements.size()) + , m_element_count(elements_range[1].index() - elements_range[0].index() + 1) { - for (size_t i = 0; i < m_element_count; ++i) - m_elements[i] = elements[i]; + m_elements[0] = elements_range[0]; + m_elements[1] = elements_range[1]; } ThrowCompletionOr execute_impl(Bytecode::Interpreter&) const; @@ -246,7 +246,7 @@ public: size_t length_impl() const { - return sizeof(*this) + sizeof(Register) * m_element_count; + return sizeof(*this) + sizeof(Register) * (m_element_count == 0 ? 0 : 2); } private: