diff --git a/Userland/Libraries/LibJS/Bytecode/Builtins.h b/Userland/Libraries/LibJS/Bytecode/Builtins.h index eb647d1cf4..4832579359 100644 --- a/Userland/Libraries/LibJS/Bytecode/Builtins.h +++ b/Userland/Libraries/LibJS/Bytecode/Builtins.h @@ -12,10 +12,11 @@ namespace JS::Bytecode { // TitleCaseName, snake_case_name, base, property, argument_count -#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) \ +#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(MathFloor, math_floor, Math, floor, 1) \ 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 1bc017fab9..7f6136ad5b 100644 --- a/Userland/Libraries/LibJS/JIT/Compiler.cpp +++ b/Userland/Libraries/LibJS/JIT/Compiler.cpp @@ -2663,6 +2663,19 @@ void Compiler::compile_builtin_math_pow(Assembler::Label&, Assembler::Label& end m_assembler.jump(end); } +static Value cxx_math_floor(VM& vm, Value, Value value) +{ + return TRY_OR_SET_EXCEPTION(MathObject::floor_impl(vm, value)); +} + +void Compiler::compile_builtin_math_floor(Assembler::Label&, Assembler::Label& end) +{ + native_call((void*)cxx_math_floor); + 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 edbcaa0130..31b4dc4f15 100644 --- a/Userland/Libraries/LibJS/Runtime/MathObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/MathObject.cpp @@ -32,7 +32,7 @@ void MathObject::initialize(Realm& realm) define_native_function(realm, vm.names.abs, abs, 1, attr, Bytecode::Builtin::MathAbs); define_native_function(realm, vm.names.random, random, 0, attr); define_native_function(realm, vm.names.sqrt, sqrt, 1, attr, Bytecode::Builtin::MathSqrt); - define_native_function(realm, vm.names.floor, floor, 1, attr); + define_native_function(realm, vm.names.floor, floor, 1, attr, Bytecode::Builtin::MathFloor); define_native_function(realm, vm.names.ceil, ceil, 1, attr); define_native_function(realm, vm.names.round, round, 1, attr); define_native_function(realm, vm.names.max, max, 2, attr); @@ -456,10 +456,10 @@ JS_DEFINE_NATIVE_FUNCTION(MathObject::expm1) } // 21.3.2.16 Math.floor ( x ), https://tc39.es/ecma262/#sec-math.floor -JS_DEFINE_NATIVE_FUNCTION(MathObject::floor) +ThrowCompletionOr MathObject::floor_impl(VM& vm, Value x) { // 1. Let n be ? ToNumber(x). - auto number = TRY(vm.argument(0).to_number(vm)); + auto number = TRY(x.to_number(vm)); // 2. If n is not finite or n is either +0𝔽 or -0𝔽, return n. if (!number.is_finite_number() || number.as_double() == 0) @@ -471,6 +471,12 @@ JS_DEFINE_NATIVE_FUNCTION(MathObject::floor) return Value(::floor(number.as_double())); } +// 21.3.2.16 Math.floor ( x ), https://tc39.es/ecma262/#sec-math.floor +JS_DEFINE_NATIVE_FUNCTION(MathObject::floor) +{ + return floor_impl(vm, vm.argument(0)); +} + // 21.3.2.17 Math.fround ( x ), https://tc39.es/ecma262/#sec-math.fround JS_DEFINE_NATIVE_FUNCTION(MathObject::fround) { diff --git a/Userland/Libraries/LibJS/Runtime/MathObject.h b/Userland/Libraries/LibJS/Runtime/MathObject.h index aefe843e95..e02ec4e7c8 100644 --- a/Userland/Libraries/LibJS/Runtime/MathObject.h +++ b/Userland/Libraries/LibJS/Runtime/MathObject.h @@ -21,6 +21,7 @@ public: static ThrowCompletionOr log_impl(VM&, Value); static ThrowCompletionOr sqrt_impl(VM&, Value); static ThrowCompletionOr pow_impl(VM&, Value base, Value exponent); + static ThrowCompletionOr floor_impl(VM&, Value); private: explicit MathObject(Realm&);