diff --git a/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp b/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp index 8b0b763842..4531bc5a74 100644 --- a/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -970,6 +971,33 @@ ThrowCompletionOr JumpUndefined::execute_impl(Bytecode::Interpreter&) cons __builtin_unreachable(); } +static ThrowCompletionOr dispatch_builtin_call(Bytecode::Interpreter& interpreter, Bytecode::Builtin builtin, Register first_argument) +{ + switch (builtin) { + case Builtin::MathAbs: + return TRY(MathObject::abs_impl(interpreter.vm(), interpreter.reg(first_argument))); + case Builtin::MathLog: + return TRY(MathObject::log_impl(interpreter.vm(), interpreter.reg(first_argument))); + case Builtin::MathPow: { + auto exponent = interpreter.reg(Register { first_argument.index() + 1 }); + return TRY(MathObject::pow_impl(interpreter.vm(), interpreter.reg(first_argument), exponent)); + } + case Builtin::MathExp: + return TRY(MathObject::exp_impl(interpreter.vm(), interpreter.reg(first_argument))); + case Builtin::MathCeil: + return TRY(MathObject::ceil_impl(interpreter.vm(), interpreter.reg(first_argument))); + case Builtin::MathFloor: + return TRY(MathObject::floor_impl(interpreter.vm(), interpreter.reg(first_argument))); + case Builtin::MathRound: + return TRY(MathObject::round_impl(interpreter.vm(), interpreter.reg(first_argument))); + case Builtin::MathSqrt: + return TRY(MathObject::sqrt_impl(interpreter.vm(), interpreter.reg(first_argument))); + case Bytecode::Builtin::__Count: + VERIFY_NOT_REACHED(); + } + VERIFY_NOT_REACHED(); +} + ThrowCompletionOr Call::execute_impl(Bytecode::Interpreter& interpreter) const { auto& vm = interpreter.vm(); @@ -977,6 +1005,11 @@ ThrowCompletionOr Call::execute_impl(Bytecode::Interpreter& interpreter) c TRY(throw_if_needed_for_call(interpreter, callee, call_type(), expression_string())); + if (m_builtin.has_value() && m_argument_count == Bytecode::builtin_argument_count(m_builtin.value()) && interpreter.realm().get_builtin_value(m_builtin.value()) == callee) { + interpreter.accumulator() = TRY(dispatch_builtin_call(interpreter, m_builtin.value(), m_first_argument)); + return {}; + } + MarkedVector argument_values(vm.heap()); argument_values.ensure_capacity(m_argument_count); for (u32 i = 0; i < m_argument_count; ++i) { diff --git a/Userland/Libraries/LibJS/Runtime/MathObject.cpp b/Userland/Libraries/LibJS/Runtime/MathObject.cpp index 4fa109ec56..26107ab8cd 100644 --- a/Userland/Libraries/LibJS/Runtime/MathObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/MathObject.cpp @@ -80,10 +80,8 @@ void MathObject::initialize(Realm& realm) } // 21.3.2.1 Math.abs ( x ), https://tc39.es/ecma262/#sec-math.abs -JS_DEFINE_NATIVE_FUNCTION(MathObject::abs) +ThrowCompletionOr MathObject::abs_impl(VM& vm, Value x) { - auto x = vm.argument(0); - // OPTIMIZATION: Fast path for Int32 values. if (x.is_int32()) return Value(AK::abs(x.as_i32())); @@ -108,6 +106,12 @@ JS_DEFINE_NATIVE_FUNCTION(MathObject::abs) return Value(number.as_double() < 0 ? -number.as_double() : number.as_double()); } +// 21.3.2.1 Math.abs ( x ), https://tc39.es/ecma262/#sec-math.abs +JS_DEFINE_NATIVE_FUNCTION(MathObject::abs) +{ + return abs_impl(vm, vm.argument(0)); +} + // 21.3.2.2 Math.acos ( x ), https://tc39.es/ecma262/#sec-math.acos JS_DEFINE_NATIVE_FUNCTION(MathObject::acos) { diff --git a/Userland/Libraries/LibJS/Runtime/MathObject.h b/Userland/Libraries/LibJS/Runtime/MathObject.h index 1ba9ae2e50..1cdaaf0a4c 100644 --- a/Userland/Libraries/LibJS/Runtime/MathObject.h +++ b/Userland/Libraries/LibJS/Runtime/MathObject.h @@ -25,6 +25,7 @@ public: static ThrowCompletionOr ceil_impl(VM&, Value); static ThrowCompletionOr round_impl(VM&, Value); static ThrowCompletionOr exp_impl(VM&, Value); + static ThrowCompletionOr abs_impl(VM&, Value); private: explicit MathObject(Realm&); diff --git a/Userland/Libraries/LibJS/Runtime/Realm.h b/Userland/Libraries/LibJS/Runtime/Realm.h index 5a42d6a649..5be4c4967b 100644 --- a/Userland/Libraries/LibJS/Runtime/Realm.h +++ b/Userland/Libraries/LibJS/Runtime/Realm.h @@ -57,6 +57,11 @@ public: m_builtins[to_underlying(builtin)] = value; } + Value get_builtin_value(Bytecode::Builtin builtin) + { + return m_builtins[to_underlying(builtin)]; + } + static FlatPtr global_environment_offset() { return OFFSET_OF(Realm, m_global_environment); } static FlatPtr builtins_offset() { return OFFSET_OF(Realm, m_builtins); }