Bläddra i källkod

LibJS/JIT: Add builtin for Math.pow()

Andreas Kling 1 år sedan
förälder
incheckning
5e976d611e

+ 1 - 0
Userland/Libraries/LibJS/Bytecode/Builtins.h

@@ -15,6 +15,7 @@ namespace JS::Bytecode {
 #define JS_ENUMERATE_BUILTINS(O)       \
 #define JS_ENUMERATE_BUILTINS(O)       \
     O(MathAbs, math_abs, Math, abs, 1) \
     O(MathAbs, math_abs, Math, abs, 1) \
     O(MathLog, math_log, Math, log, 1) \
     O(MathLog, math_log, Math, log, 1) \
+    O(MathPow, math_pow, Math, pow, 2) \
     O(MathSqrt, math_sqrt, Math, sqrt, 1)
     O(MathSqrt, math_sqrt, Math, sqrt, 1)
 
 
 enum class Builtin {
 enum class Builtin {

+ 13 - 0
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);
     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)
 void Compiler::compile_builtin_math_abs(Assembler::Label& slow_case, Assembler::Label& end)
 {
 {
     branch_if_int32(ARG2, [&] {
     branch_if_int32(ARG2, [&] {

+ 10 - 4
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.sin, sin, 1, attr);
     define_native_function(realm, vm.names.cos, cos, 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.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.exp, exp, 1, attr);
     define_native_function(realm, vm.names.expm1, expm1, 1, attr);
     define_native_function(realm, vm.names.expm1, expm1, 1, attr);
     define_native_function(realm, vm.names.sign, sign, 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
 // 21.3.2.26 Math.pow ( base, exponent ), https://tc39.es/ecma262/#sec-math.pow
-JS_DEFINE_NATIVE_FUNCTION(MathObject::pow)
+ThrowCompletionOr<Value> MathObject::pow_impl(VM& vm, Value base, Value exponent)
 {
 {
     // Set base to ? ToNumber(base).
     // 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).
     // 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).
     // 3. Return Number::exponentiate(base, exponent).
     return JS::exp(vm, 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
 // 21.3.2.27 Math.random ( ), https://tc39.es/ecma262/#sec-math.random
 JS_DEFINE_NATIVE_FUNCTION(MathObject::random)
 JS_DEFINE_NATIVE_FUNCTION(MathObject::random)
 {
 {

+ 1 - 0
Userland/Libraries/LibJS/Runtime/MathObject.h

@@ -20,6 +20,7 @@ public:
 
 
     static ThrowCompletionOr<Value> log_impl(VM&, Value);
     static ThrowCompletionOr<Value> log_impl(VM&, Value);
     static ThrowCompletionOr<Value> sqrt_impl(VM&, Value);
     static ThrowCompletionOr<Value> sqrt_impl(VM&, Value);
+    static ThrowCompletionOr<Value> pow_impl(VM&, Value base, Value exponent);
 
 
 private:
 private:
     explicit MathObject(Realm&);
     explicit MathObject(Realm&);