diff --git a/Userland/Libraries/LibJS/AST.h b/Userland/Libraries/LibJS/AST.h index 18c8a0b130..f99363a96b 100644 --- a/Userland/Libraries/LibJS/AST.h +++ b/Userland/Libraries/LibJS/AST.h @@ -1115,6 +1115,7 @@ public: virtual Value execute(Interpreter&, GlobalObject&) const override; virtual void dump(int indent) const override; + virtual void generate_bytecode(Bytecode::Generator&) const override; private: const NonnullRefPtr m_tag; diff --git a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp index d97aefe0c6..18ff42d866 100644 --- a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp +++ b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp @@ -653,6 +653,62 @@ void TemplateLiteral::generate_bytecode(Bytecode::Generator& generator) const generator.emit(string_reg); } +void TaggedTemplateLiteral::generate_bytecode(Bytecode::Generator& generator) const +{ + Vector string_regs; + auto& expressions = m_template_literal->expressions(); + for (size_t i = 0; i < expressions.size(); ++i) { + if (i % 2 != 0) + continue; + + expressions[i].generate_bytecode(generator); + auto string_reg = generator.allocate_register(); + generator.emit(string_reg); + string_regs.append(string_reg); + } + + generator.emit_with_extra_register_slots(string_regs.size(), string_regs); + auto strings_reg = generator.allocate_register(); + generator.emit(strings_reg); + + Vector argument_regs; + argument_regs.append(strings_reg); + for (size_t i = 0; i < expressions.size(); ++i) { + if (i % 2 == 0) + continue; + + expressions[i].generate_bytecode(generator); + auto string_reg = generator.allocate_register(); + generator.emit(string_reg); + argument_regs.append(string_reg); + } + + Vector raw_string_regs; + for (auto& raw_string : m_template_literal->raw_strings()) { + raw_string.generate_bytecode(generator); + auto raw_string_reg = generator.allocate_register(); + 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); + auto raw_strings_reg = generator.allocate_register(); + generator.emit(raw_strings_reg); + + generator.emit(strings_reg); + generator.emit(raw_strings_reg, generator.intern_string("raw")); + + m_tag->generate_bytecode(generator); + auto tag_reg = generator.allocate_register(); + generator.emit(tag_reg); + + generator.emit(js_undefined()); + auto this_reg = generator.allocate_register(); + generator.emit(this_reg); + + generator.emit_with_extra_register_slots(argument_regs.size(), tag_reg, this_reg, move(argument_regs)); +} + void UpdateExpression::generate_bytecode(Bytecode::Generator& generator) const { if (is(*m_argument)) {