Преглед изворни кода

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.
Linus Groh пре 3 година
родитељ
комит
b9b3d01bea
2 измењених фајлова са 30 додато и 0 уклоњено
  1. 28 0
      Userland/Libraries/LibJS/Runtime/Value.cpp
  2. 2 0
      Userland/Libraries/LibJS/Runtime/Value.h

+ 28 - 0
Userland/Libraries/LibJS/Runtime/Value.cpp

@@ -805,6 +805,34 @@ ThrowCompletionOr<double> Value::to_integer_or_infinity(GlobalObject& global_obj
     return integer;
     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
 // 7.3.3 GetV ( V, P ), https://tc39.es/ecma262/#sec-getv
 ThrowCompletionOr<Value> Value::get(GlobalObject& global_object, PropertyKey const& property_key) const
 ThrowCompletionOr<Value> Value::get(GlobalObject& global_object, PropertyKey const& property_key) const
 {
 {

+ 2 - 0
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);
 bool same_value_non_numeric(Value lhs, Value rhs);
 ThrowCompletionOr<TriState> is_less_than(GlobalObject&, bool left_first, 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); }
 inline bool Value::operator==(Value const& value) const { return same_value(*this, value); }
 
 
 }
 }