diff --git a/Userland/Libraries/LibJS/JIT/Compiler.cpp b/Userland/Libraries/LibJS/JIT/Compiler.cpp index a535fd9885..29b0166c86 100644 --- a/Userland/Libraries/LibJS/JIT/Compiler.cpp +++ b/Userland/Libraries/LibJS/JIT/Compiler.cpp @@ -237,6 +237,19 @@ void Compiler::compile_jump_undefined(Bytecode::Op::JumpUndefined const& op) return BigInt::create(vm, old_value.as_bigint().big_integer().plus(Crypto::SignedBigInteger { 1 })); } +void Compiler::jump_if_int32(Assembler::Reg reg, Assembler::Label& label) +{ + // GPR0 = reg >> 48; + m_assembler.mov(Assembler::Operand::Register(GPR0), Assembler::Operand::Register(reg)); + m_assembler.shift_right(Assembler::Operand::Register(GPR0), Assembler::Operand::Imm(48)); + + m_assembler.jump_if( + Assembler::Operand::Register(GPR0), + Assembler::Condition::EqualTo, + Assembler::Operand::Imm(INT32_TAG), + label); +} + template void Compiler::branch_if_int32(Assembler::Reg reg, Codegen codegen) { @@ -909,10 +922,16 @@ static Value cxx_to_numeric(VM& vm, Value value) void Compiler::compile_to_numeric(Bytecode::Op::ToNumeric const&) { + Assembler::Label fast_case {}; + load_vm_register(ARG1, Bytecode::Register::accumulator()); + jump_if_int32(ARG1, fast_case); + native_call((void*)cxx_to_numeric); store_vm_register(Bytecode::Register::accumulator(), RET); check_exception(); + + fast_case.link(m_assembler); } static Value cxx_resolve_this_binding(VM& vm) diff --git a/Userland/Libraries/LibJS/JIT/Compiler.h b/Userland/Libraries/LibJS/JIT/Compiler.h index fb21624ec5..b9bd929316 100644 --- a/Userland/Libraries/LibJS/JIT/Compiler.h +++ b/Userland/Libraries/LibJS/JIT/Compiler.h @@ -166,6 +166,8 @@ private: void native_call(void* function_address, Vector const& stack_arguments = {}); + void jump_if_int32(Assembler::Reg, Assembler::Label&); + template void branch_if_int32(Assembler::Reg, Codegen);