summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibJS
diff options
context:
space:
mode:
authorLinus Groh <mail@linusgroh.de>2022-05-06 20:17:16 +0200
committerLinus Groh <mail@linusgroh.de>2022-05-06 22:32:47 +0200
commitb9b3d01bea2b8e5455f17eedf1acd6ac9ffe31ec (patch)
tree8c0310bf318ac0b16f08d3936a22c70ce4ee848f /Userland/Libraries/LibJS
parent875e59b74018233b6d669aa3f6024f35ed40e468 (diff)
downloadserenity-b9b3d01bea2b8e5455f17eedf1acd6ac9ffe31ec.zip
LibJS: Add variant of to_integer_or_infinity() for plain doubles
In many cases we already know a certain value is a number, or don't have JS values at all and would need to wrap doubles in a value. To optimize these cases and avoid having to pass a global object into functions that won't ever allocate or throw, add a standalone implementation of this function that takes and returns doubles directly.
Diffstat (limited to 'Userland/Libraries/LibJS')
-rw-r--r--Userland/Libraries/LibJS/Runtime/Value.cpp28
-rw-r--r--Userland/Libraries/LibJS/Runtime/Value.h2
2 files changed, 30 insertions, 0 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/Value.cpp b/Userland/Libraries/LibJS/Runtime/Value.cpp
index c0918acabd..8d20e21300 100644
--- a/Userland/Libraries/LibJS/Runtime/Value.cpp
+++ b/Userland/Libraries/LibJS/Runtime/Value.cpp
@@ -805,6 +805,34 @@ ThrowCompletionOr<double> Value::to_integer_or_infinity(GlobalObject& global_obj
return integer;
}
+// Standalone variant using plain doubles for cases where we already got numbers and know the AO won't throw.
+double to_integer_or_infinity(double number)
+{
+ // 1. Let number be ? ToNumber(argument).
+
+ // 2. If number is NaN, +0𝔽, or -0𝔽, return 0.
+ if (isnan(number) || number == 0)
+ return 0;
+
+ // 3. If number is +∞𝔽, return +∞.
+ if (__builtin_isinf_sign(number) > 0)
+ return static_cast<double>(INFINITY);
+
+ // 4. If number is -∞𝔽, return -∞.
+ if (__builtin_isinf_sign(number) < 0)
+ return static_cast<double>(-INFINITY);
+
+ // 5. Let integer be floor(abs(ℝ(number))).
+ auto integer = floor(fabs(number));
+
+ // 6. If number < -0𝔽, set integer to -integer.
+ if (number < 0 && integer != 0)
+ integer = -integer;
+
+ // 7. Return integer.
+ return integer;
+}
+
// 7.3.3 GetV ( V, P ), https://tc39.es/ecma262/#sec-getv
ThrowCompletionOr<Value> Value::get(GlobalObject& global_object, PropertyKey const& property_key) const
{
diff --git a/Userland/Libraries/LibJS/Runtime/Value.h b/Userland/Libraries/LibJS/Runtime/Value.h
index 0b1f1aac59..553a760744 100644
--- a/Userland/Libraries/LibJS/Runtime/Value.h
+++ b/Userland/Libraries/LibJS/Runtime/Value.h
@@ -431,6 +431,8 @@ bool same_value_zero(Value lhs, Value rhs);
bool same_value_non_numeric(Value lhs, Value rhs);
ThrowCompletionOr<TriState> is_less_than(GlobalObject&, bool left_first, Value lhs, Value rhs);
+double to_integer_or_infinity(double);
+
inline bool Value::operator==(Value const& value) const { return same_value(*this, value); }
}