Explorar o código

LibJS/JIT: Support the NewString bytecode op

This necessitated making the JIT::Compiler aware of the current
Bytecode::Executable, since that's where all the string literals are
held, but that seems like a good thing.
Andreas Kling hai 1 ano
pai
achega
c2fe7af095

+ 2 - 0
Userland/Libraries/LibJS/Bytecode/Op.h

@@ -157,6 +157,8 @@ public:
     ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
     DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
 
+    StringTableIndex index() const { return m_string; }
+
 private:
     StringTableIndex m_string;
 };

+ 20 - 2
Userland/Libraries/LibJS/JIT/Compiler.cpp

@@ -383,12 +383,27 @@ void Compiler::compile_return(Bytecode::Op::Return const&)
     m_assembler.exit();
 }
 
-OwnPtr<NativeExecutable> Compiler::compile(Bytecode::Executable const& bytecode_executable)
+static Value cxx_new_string(VM& vm, DeprecatedString const& string)
+{
+    return PrimitiveString::create(vm, string);
+}
+
+void Compiler::compile_new_string(Bytecode::Op::NewString const& op)
+{
+    auto const& string = m_bytecode_executable.string_table->get(op.index());
+    m_assembler.mov(
+        Assembler::Operand::Register(ARG1),
+        Assembler::Operand::Imm64(bit_cast<u64>(&string)));
+    m_assembler.native_call((void*)cxx_new_string);
+    store_vm_register(Bytecode::Register::accumulator(), RET);
+}
+
+OwnPtr<NativeExecutable> Compiler::compile(Bytecode::Executable& bytecode_executable)
 {
     if (getenv("LIBJS_NO_JIT"))
         return nullptr;
 
-    Compiler compiler;
+    Compiler compiler { bytecode_executable };
 
     compiler.m_assembler.enter();
 
@@ -459,6 +474,9 @@ OwnPtr<NativeExecutable> Compiler::compile(Bytecode::Executable const& bytecode_
             case Bytecode::Instruction::Type::Return:
                 compiler.compile_return(static_cast<Bytecode::Op::Return const&>(op));
                 break;
+            case Bytecode::Instruction::Type::NewString:
+                compiler.compile_new_string(static_cast<Bytecode::Op::NewString const&>(op));
+                break;
             default:
                 dbgln("JIT compilation failed: {}", bytecode_executable.name);
                 dbgln("Unsupported bytecode op: {}", op.to_deprecated_string(bytecode_executable));

+ 8 - 1
Userland/Libraries/LibJS/JIT/Compiler.h

@@ -15,7 +15,7 @@ namespace JS::JIT {
 
 class Compiler {
 public:
-    static OwnPtr<NativeExecutable> compile(Bytecode::Executable const&);
+    static OwnPtr<NativeExecutable> compile(Bytecode::Executable&);
 
 private:
     static constexpr auto GPR0 = Assembler::Reg::RAX;
@@ -46,6 +46,7 @@ private:
     void compile_mul(Bytecode::Op::Mul const&);
     void compile_div(Bytecode::Op::Div const&);
     void compile_return(Bytecode::Op::Return const&);
+    void compile_new_string(Bytecode::Op::NewString const&);
 
     void store_vm_register(Bytecode::Register, Assembler::Reg);
     void load_vm_register(Assembler::Reg, Bytecode::Register);
@@ -60,8 +61,14 @@ private:
     void push_unwind_context(bool valid, Optional<Bytecode::Label> const& handler, Optional<Bytecode::Label> const& finalizer);
     void pop_unwind_context();
 
+    explicit Compiler(Bytecode::Executable& bytecode_executable)
+        : m_bytecode_executable(bytecode_executable)
+    {
+    }
+
     Vector<u8> m_output;
     Assembler m_assembler { m_output };
+    Bytecode::Executable& m_bytecode_executable;
 };
 
 }