diff --git a/Userland/Libraries/LibJS/Bytecode/Builtins.h b/Userland/Libraries/LibJS/Bytecode/Builtins.h index 651e4ffed8..eb647d1cf4 100644 --- a/Userland/Libraries/LibJS/Bytecode/Builtins.h +++ b/Userland/Libraries/LibJS/Bytecode/Builtins.h @@ -15,6 +15,7 @@ namespace JS::Bytecode { #define JS_ENUMERATE_BUILTINS(O) \ O(MathAbs, math_abs, Math, abs, 1) \ O(MathLog, math_log, Math, log, 1) \ + O(MathPow, math_pow, Math, pow, 2) \ O(MathSqrt, math_sqrt, Math, sqrt, 1) enum class Builtin { diff --git a/Userland/Libraries/LibJS/JIT/Compiler.cpp b/Userland/Libraries/LibJS/JIT/Compiler.cpp index 64deff02c7..1bc017fab9 100644 --- a/Userland/Libraries/LibJS/JIT/Compiler.cpp +++ b/Userland/Libraries/LibJS/JIT/Compiler.cpp @@ -2650,6 +2650,19 @@ void Compiler::compile_builtin_math_sqrt(Assembler::Label&, Assembler::Label& en m_assembler.jump(end); } +static Value cxx_math_pow(VM& vm, Value, Value base, Value exponent) +{ + return TRY_OR_SET_EXCEPTION(MathObject::pow_impl(vm, base, exponent)); +} + +void Compiler::compile_builtin_math_pow(Assembler::Label&, Assembler::Label& end) +{ + native_call((void*)cxx_math_pow); + store_accumulator(RET); + check_exception(); + m_assembler.jump(end); +} + void Compiler::compile_builtin_math_abs(Assembler::Label& slow_case, Assembler::Label& end) { branch_if_int32(ARG2, [&] { diff --git a/Userland/Libraries/LibJS/Runtime/MathObject.cpp b/Userland/Libraries/LibJS/Runtime/MathObject.cpp index 0d731d1cc2..edbcaa0130 100644 --- a/Userland/Libraries/LibJS/Runtime/MathObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/MathObject.cpp @@ -41,7 +41,7 @@ void MathObject::initialize(Realm& realm) define_native_function(realm, vm.names.sin, sin, 1, attr); define_native_function(realm, vm.names.cos, cos, 1, attr); define_native_function(realm, vm.names.tan, tan, 1, attr); - define_native_function(realm, vm.names.pow, pow, 2, attr); + define_native_function(realm, vm.names.pow, pow, 2, attr, Bytecode::Builtin::MathPow); define_native_function(realm, vm.names.exp, exp, 1, attr); define_native_function(realm, vm.names.expm1, expm1, 1, attr); define_native_function(realm, vm.names.sign, sign, 1, attr); @@ -729,18 +729,24 @@ JS_DEFINE_NATIVE_FUNCTION(MathObject::min) } // 21.3.2.26 Math.pow ( base, exponent ), https://tc39.es/ecma262/#sec-math.pow -JS_DEFINE_NATIVE_FUNCTION(MathObject::pow) +ThrowCompletionOr MathObject::pow_impl(VM& vm, Value base, Value exponent) { // Set base to ? ToNumber(base). - auto base = TRY(vm.argument(0).to_number(vm)); + base = TRY(base.to_number(vm)); // 2. Set exponent to ? ToNumber(exponent). - auto exponent = TRY(vm.argument(1).to_number(vm)); + exponent = TRY(exponent.to_number(vm)); // 3. Return Number::exponentiate(base, exponent). return JS::exp(vm, base, exponent); } +// 21.3.2.26 Math.pow ( base, exponent ), https://tc39.es/ecma262/#sec-math.pow +JS_DEFINE_NATIVE_FUNCTION(MathObject::pow) +{ + return pow_impl(vm, vm.argument(0), vm.argument(1)); +} + // 21.3.2.27 Math.random ( ), https://tc39.es/ecma262/#sec-math.random JS_DEFINE_NATIVE_FUNCTION(MathObject::random) { diff --git a/Userland/Libraries/LibJS/Runtime/MathObject.h b/Userland/Libraries/LibJS/Runtime/MathObject.h index 8bf0bf4b34..aefe843e95 100644 --- a/Userland/Libraries/LibJS/Runtime/MathObject.h +++ b/Userland/Libraries/LibJS/Runtime/MathObject.h @@ -20,6 +20,7 @@ public: static ThrowCompletionOr log_impl(VM&, Value); static ThrowCompletionOr sqrt_impl(VM&, Value); + static ThrowCompletionOr pow_impl(VM&, Value base, Value exponent); private: explicit MathObject(Realm&);