소스 검색

LibJS/JIT: Support all the binary bytecode ops :^)

(And use the X macro to avoid repeating ourselves!)
Andreas Kling 1 년 전
부모
커밋
b923ca392d
2개의 변경된 파일39개의 추가작업 그리고 76개의 파일을 삭제
  1. 32 71
      Userland/Libraries/LibJS/JIT/Compiler.cpp
  2. 7 5
      Userland/Libraries/LibJS/JIT/Compiler.h

+ 32 - 71
Userland/Libraries/LibJS/JIT/Compiler.cpp

@@ -158,20 +158,6 @@ void Compiler::compile_jump_conditional(Bytecode::Op::JumpConditional const& op)
         const_cast<Bytecode::BasicBlock&>(op.false_target()->block()));
 }
 
-[[maybe_unused]] static Value cxx_less_than(VM& vm, Value lhs, Value rhs)
-{
-    return TRY_OR_SET_EXCEPTION(less_than(vm, lhs, rhs));
-}
-
-void Compiler::compile_less_than(Bytecode::Op::LessThan const& op)
-{
-    load_vm_register(ARG1, op.lhs());
-    load_vm_register(ARG2, Bytecode::Register::accumulator());
-    m_assembler.native_call((void*)cxx_less_than);
-    store_vm_register(Bytecode::Register::accumulator(), RET);
-    check_exception();
-}
-
 [[maybe_unused]] static Value cxx_increment(VM& vm, Value value)
 {
     auto old_value = TRY_OR_SET_EXCEPTION(value.to_numeric(vm));
@@ -320,61 +306,43 @@ void Compiler::compile_throw(Bytecode::Op::Throw const&)
     check_exception();
 }
 
-static Value cxx_add(VM& vm, Value lhs, Value rhs)
+static ThrowCompletionOr<Value> abstract_inequals(VM& vm, Value src1, Value src2)
 {
-    return TRY_OR_SET_EXCEPTION(add(vm, lhs, rhs));
+    return Value(!TRY(is_loosely_equal(vm, src1, src2)));
 }
 
-void Compiler::compile_add(Bytecode::Op::Add const& op)
+static ThrowCompletionOr<Value> abstract_equals(VM& vm, Value src1, Value src2)
 {
-    load_vm_register(ARG1, op.lhs());
-    load_vm_register(ARG2, Bytecode::Register::accumulator());
-    m_assembler.native_call((void*)cxx_add);
-    store_vm_register(Bytecode::Register::accumulator(), RET);
-    check_exception();
-}
-
-static Value cxx_sub(VM& vm, Value lhs, Value rhs)
-{
-    return TRY_OR_SET_EXCEPTION(sub(vm, lhs, rhs));
-}
-
-void Compiler::compile_sub(Bytecode::Op::Sub const& op)
-{
-    load_vm_register(ARG1, op.lhs());
-    load_vm_register(ARG2, Bytecode::Register::accumulator());
-    m_assembler.native_call((void*)cxx_sub);
-    store_vm_register(Bytecode::Register::accumulator(), RET);
-    check_exception();
+    return Value(TRY(is_loosely_equal(vm, src1, src2)));
 }
 
-static Value cxx_mul(VM& vm, Value lhs, Value rhs)
+static ThrowCompletionOr<Value> typed_inequals(VM&, Value src1, Value src2)
 {
-    return TRY_OR_SET_EXCEPTION(mul(vm, lhs, rhs));
+    return Value(!is_strictly_equal(src1, src2));
 }
 
-void Compiler::compile_mul(Bytecode::Op::Mul const& op)
+static ThrowCompletionOr<Value> typed_equals(VM&, Value src1, Value src2)
 {
-    load_vm_register(ARG1, op.lhs());
-    load_vm_register(ARG2, Bytecode::Register::accumulator());
-    m_assembler.native_call((void*)cxx_mul);
-    store_vm_register(Bytecode::Register::accumulator(), RET);
-    check_exception();
+    return Value(is_strictly_equal(src1, src2));
 }
 
-static Value cxx_div(VM& vm, Value lhs, Value rhs)
-{
-    return TRY_OR_SET_EXCEPTION(div(vm, lhs, rhs));
-}
+#define DO_COMPILE_COMMON_BINARY_OP(TitleCaseName, snake_case_name)                 \
+    static Value cxx_##snake_case_name(VM& vm, Value lhs, Value rhs)                \
+    {                                                                               \
+        return TRY_OR_SET_EXCEPTION(snake_case_name(vm, lhs, rhs));                 \
+    }                                                                               \
+                                                                                    \
+    void Compiler::compile_##snake_case_name(Bytecode::Op::TitleCaseName const& op) \
+    {                                                                               \
+        load_vm_register(ARG1, op.lhs());                                           \
+        load_vm_register(ARG2, Bytecode::Register::accumulator());                  \
+        m_assembler.native_call((void*)cxx_##snake_case_name);                      \
+        store_vm_register(Bytecode::Register::accumulator(), RET);                  \
+        check_exception();                                                          \
+    }
 
-void Compiler::compile_div(Bytecode::Op::Div const& op)
-{
-    load_vm_register(ARG1, op.lhs());
-    load_vm_register(ARG2, Bytecode::Register::accumulator());
-    m_assembler.native_call((void*)cxx_div);
-    store_vm_register(Bytecode::Register::accumulator(), RET);
-    check_exception();
-}
+JS_ENUMERATE_COMMON_BINARY_OPS(DO_COMPILE_COMMON_BINARY_OP)
+#undef DO_COMPILE_COMMON_BINARY_OP
 
 void Compiler::compile_return(Bytecode::Op::Return const&)
 {
@@ -444,9 +412,6 @@ OwnPtr<NativeExecutable> Compiler::compile(Bytecode::Executable& bytecode_execut
             case Bytecode::Instruction::Type::JumpConditional:
                 compiler.compile_jump_conditional(static_cast<Bytecode::Op::JumpConditional const&>(op));
                 break;
-            case Bytecode::Instruction::Type::LessThan:
-                compiler.compile_less_than(static_cast<Bytecode::Op::LessThan const&>(op));
-                break;
             case Bytecode::Instruction::Type::Increment:
                 compiler.compile_increment(static_cast<Bytecode::Op::Increment const&>(op));
                 break;
@@ -459,24 +424,20 @@ OwnPtr<NativeExecutable> Compiler::compile(Bytecode::Executable& bytecode_execut
             case Bytecode::Instruction::Type::Throw:
                 compiler.compile_throw(static_cast<Bytecode::Op::Throw const&>(op));
                 break;
-            case Bytecode::Instruction::Type::Add:
-                compiler.compile_add(static_cast<Bytecode::Op::Add const&>(op));
-                break;
-            case Bytecode::Instruction::Type::Sub:
-                compiler.compile_sub(static_cast<Bytecode::Op::Sub const&>(op));
-                break;
-            case Bytecode::Instruction::Type::Mul:
-                compiler.compile_mul(static_cast<Bytecode::Op::Mul const&>(op));
-                break;
-            case Bytecode::Instruction::Type::Div:
-                compiler.compile_div(static_cast<Bytecode::Op::Div const&>(op));
-                break;
             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;
+
+#define DO_COMPILE_COMMON_BINARY_OP(TitleCaseName, snake_case_name)                              \
+    case Bytecode::Instruction::Type::TitleCaseName:                                             \
+        compiler.compile_##snake_case_name(static_cast<Bytecode::Op::TitleCaseName const&>(op)); \
+        break;
+                JS_ENUMERATE_COMMON_BINARY_OPS(DO_COMPILE_COMMON_BINARY_OP)
+#undef DO_COMPILE_COMMON_BINARY_OP
+
             default:
                 dbgln("JIT compilation failed: {}", bytecode_executable.name);
                 dbgln("Unsupported bytecode op: {}", op.to_deprecated_string(bytecode_executable));

+ 7 - 5
Userland/Libraries/LibJS/JIT/Compiler.h

@@ -36,15 +36,17 @@ private:
     void compile_set_local(Bytecode::Op::SetLocal const&);
     void compile_jump(Bytecode::Op::Jump const&);
     void compile_jump_conditional(Bytecode::Op::JumpConditional const&);
-    void compile_less_than(Bytecode::Op::LessThan const&);
     void compile_increment(Bytecode::Op::Increment const&);
     void compile_enter_unwind_context(Bytecode::Op::EnterUnwindContext const&);
     void compile_leave_unwind_context(Bytecode::Op::LeaveUnwindContext const&);
     void compile_throw(Bytecode::Op::Throw const&);
-    void compile_add(Bytecode::Op::Add const&);
-    void compile_sub(Bytecode::Op::Sub const&);
-    void compile_mul(Bytecode::Op::Mul const&);
-    void compile_div(Bytecode::Op::Div const&);
+
+#define DO_COMPILE_COMMON_BINARY_OP(OpTitleCase, op_snake_case) \
+    void compile_##op_snake_case(Bytecode::Op::OpTitleCase const&);
+
+    JS_ENUMERATE_COMMON_BINARY_OPS(DO_COMPILE_COMMON_BINARY_OP)
+#undef DO_COMPILE_COMMON_BINARY_OP
+
     void compile_return(Bytecode::Op::Return const&);
     void compile_new_string(Bytecode::Op::NewString const&);