From b8f101888bf5cc16f7074266bf16ebde4744f452 Mon Sep 17 00:00:00 2001 From: Idan Horowitz Date: Sat, 16 Oct 2021 21:42:32 +0300 Subject: [PATCH] LibJS: Convert to_numeric() to ThrowCompletionOr --- Userland/Libraries/LibJS/AST.cpp | 4 +- Userland/Libraries/LibJS/Bytecode/Op.cpp | 10 +- .../LibJS/Runtime/NumberConstructor.cpp | 4 +- Userland/Libraries/LibJS/Runtime/Value.cpp | 122 +++++------------- Userland/Libraries/LibJS/Runtime/Value.h | 2 +- 5 files changed, 44 insertions(+), 98 deletions(-) diff --git a/Userland/Libraries/LibJS/AST.cpp b/Userland/Libraries/LibJS/AST.cpp index 3d175393c1..5a33244f75 100644 --- a/Userland/Libraries/LibJS/AST.cpp +++ b/Userland/Libraries/LibJS/AST.cpp @@ -2055,9 +2055,7 @@ Value UpdateExpression::execute(Interpreter& interpreter, GlobalObject& global_o auto old_value = reference.get_value(global_object); if (interpreter.exception()) return {}; - old_value = old_value.to_numeric(global_object); - if (interpreter.exception()) - return {}; + old_value = TRY_OR_DISCARD(old_value.to_numeric(global_object)); Value new_value; switch (m_op) { diff --git a/Userland/Libraries/LibJS/Bytecode/Op.cpp b/Userland/Libraries/LibJS/Bytecode/Op.cpp index 461071769e..6a3fc3202a 100644 --- a/Userland/Libraries/LibJS/Bytecode/Op.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Op.cpp @@ -351,9 +351,10 @@ void Return::execute_impl(Bytecode::Interpreter& interpreter) const void Increment::execute_impl(Bytecode::Interpreter& interpreter) const { - auto old_value = interpreter.accumulator().to_numeric(interpreter.global_object()); - if (interpreter.vm().exception()) + auto old_value_or_error = interpreter.accumulator().to_numeric(interpreter.global_object()); + if (old_value_or_error.is_error()) return; + auto old_value = old_value_or_error.release_value(); if (old_value.is_number()) interpreter.accumulator() = Value(old_value.as_double() + 1); @@ -363,9 +364,10 @@ void Increment::execute_impl(Bytecode::Interpreter& interpreter) const void Decrement::execute_impl(Bytecode::Interpreter& interpreter) const { - auto old_value = interpreter.accumulator().to_numeric(interpreter.global_object()); - if (interpreter.vm().exception()) + auto old_value_or_error = interpreter.accumulator().to_numeric(interpreter.global_object()); + if (old_value_or_error.is_error()) return; + auto old_value = old_value_or_error.release_value(); if (old_value.is_number()) interpreter.accumulator() = Value(old_value.as_double() - 1); diff --git a/Userland/Libraries/LibJS/Runtime/NumberConstructor.cpp b/Userland/Libraries/LibJS/Runtime/NumberConstructor.cpp index 817c7ca758..302f466fc5 100644 --- a/Userland/Libraries/LibJS/Runtime/NumberConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/NumberConstructor.cpp @@ -66,9 +66,7 @@ static Value get_value_from_constructor_argument(GlobalObject& global_object) Value number; if (vm.argument_count() > 0) { - auto primitive = vm.argument(0).to_numeric(global_object); - if (vm.exception()) - return {}; + auto primitive = TRY_OR_DISCARD(vm.argument(0).to_numeric(global_object)); if (primitive.is_bigint()) { // FIXME: How should huge values be handled here? auto& big_integer = primitive.as_bigint().big_integer(); diff --git a/Userland/Libraries/LibJS/Runtime/Value.cpp b/Userland/Libraries/LibJS/Runtime/Value.cpp index a5888068af..d8587bddef 100644 --- a/Userland/Libraries/LibJS/Runtime/Value.cpp +++ b/Userland/Libraries/LibJS/Runtime/Value.cpp @@ -459,12 +459,16 @@ ThrowCompletionOr Value::to_object(GlobalObject& global_object) const } // 7.1.3 ToNumeric ( value ), https://tc39.es/ecma262/#sec-tonumeric -FLATTEN Value Value::to_numeric(GlobalObject& global_object) const +FLATTEN ThrowCompletionOr Value::to_numeric(GlobalObject& global_object) const { - auto primitive = TRY_OR_DISCARD(to_primitive(global_object, Value::PreferredType::Number)); + auto& vm = global_object.vm(); + auto primitive = TRY(to_primitive(global_object, Value::PreferredType::Number)); if (primitive.is_bigint()) return primitive; - return primitive.to_number(global_object); + auto number = primitive.to_number(global_object); + if (auto* exception = vm.exception()) + return throw_completion(exception->value()); + return number; } // 7.1.4 ToNumber ( argument ), https://tc39.es/ecma262/#sec-tonumber @@ -853,12 +857,8 @@ Value less_than_equals(GlobalObject& global_object, Value lhs, Value rhs) Value bitwise_and(GlobalObject& global_object, Value lhs, Value rhs) { auto& vm = global_object.vm(); - auto lhs_numeric = lhs.to_numeric(global_object); - if (vm.exception()) - return {}; - auto rhs_numeric = rhs.to_numeric(global_object); - if (vm.exception()) - return {}; + auto lhs_numeric = TRY_OR_DISCARD(lhs.to_numeric(global_object)); + auto rhs_numeric = TRY_OR_DISCARD(rhs.to_numeric(global_object)); if (both_number(lhs_numeric, rhs_numeric)) { if (!lhs_numeric.is_finite_number() || !rhs_numeric.is_finite_number()) return Value(0); @@ -874,12 +874,8 @@ Value bitwise_and(GlobalObject& global_object, Value lhs, Value rhs) Value bitwise_or(GlobalObject& global_object, Value lhs, Value rhs) { auto& vm = global_object.vm(); - auto lhs_numeric = lhs.to_numeric(global_object); - if (vm.exception()) - return {}; - auto rhs_numeric = rhs.to_numeric(global_object); - if (vm.exception()) - return {}; + auto lhs_numeric = TRY_OR_DISCARD(lhs.to_numeric(global_object)); + auto rhs_numeric = TRY_OR_DISCARD(rhs.to_numeric(global_object)); if (both_number(lhs_numeric, rhs_numeric)) { if (!lhs_numeric.is_finite_number() && !rhs_numeric.is_finite_number()) return Value(0); @@ -899,12 +895,8 @@ Value bitwise_or(GlobalObject& global_object, Value lhs, Value rhs) Value bitwise_xor(GlobalObject& global_object, Value lhs, Value rhs) { auto& vm = global_object.vm(); - auto lhs_numeric = lhs.to_numeric(global_object); - if (vm.exception()) - return {}; - auto rhs_numeric = rhs.to_numeric(global_object); - if (vm.exception()) - return {}; + auto lhs_numeric = TRY_OR_DISCARD(lhs.to_numeric(global_object)); + auto rhs_numeric = TRY_OR_DISCARD(rhs.to_numeric(global_object)); if (both_number(lhs_numeric, rhs_numeric)) { if (!lhs_numeric.is_finite_number() && !rhs_numeric.is_finite_number()) return Value(0); @@ -924,9 +916,7 @@ Value bitwise_xor(GlobalObject& global_object, Value lhs, Value rhs) Value bitwise_not(GlobalObject& global_object, Value lhs) { auto& vm = global_object.vm(); - auto lhs_numeric = lhs.to_numeric(global_object); - if (vm.exception()) - return {}; + auto lhs_numeric = TRY_OR_DISCARD(lhs.to_numeric(global_object)); if (lhs_numeric.is_number()) return Value(~lhs_numeric.to_i32(global_object)); auto big_integer_bitwise_not = lhs_numeric.as_bigint().big_integer(); @@ -945,9 +935,7 @@ Value unary_plus(GlobalObject& global_object, Value lhs) Value unary_minus(GlobalObject& global_object, Value lhs) { auto& vm = global_object.vm(); - auto lhs_numeric = lhs.to_numeric(global_object); - if (vm.exception()) - return {}; + auto lhs_numeric = TRY_OR_DISCARD(lhs.to_numeric(global_object)); if (lhs_numeric.is_number()) { if (lhs_numeric.is_nan()) return js_nan(); @@ -964,12 +952,8 @@ Value unary_minus(GlobalObject& global_object, Value lhs) Value left_shift(GlobalObject& global_object, Value lhs, Value rhs) { auto& vm = global_object.vm(); - auto lhs_numeric = lhs.to_numeric(global_object); - if (vm.exception()) - return {}; - auto rhs_numeric = rhs.to_numeric(global_object); - if (vm.exception()) - return {}; + auto lhs_numeric = TRY_OR_DISCARD(lhs.to_numeric(global_object)); + auto rhs_numeric = TRY_OR_DISCARD(rhs.to_numeric(global_object)); if (both_number(lhs_numeric, rhs_numeric)) { if (!lhs_numeric.is_finite_number()) return Value(0); @@ -995,12 +979,8 @@ Value left_shift(GlobalObject& global_object, Value lhs, Value rhs) Value right_shift(GlobalObject& global_object, Value lhs, Value rhs) { auto& vm = global_object.vm(); - auto lhs_numeric = lhs.to_numeric(global_object); - if (vm.exception()) - return {}; - auto rhs_numeric = rhs.to_numeric(global_object); - if (vm.exception()) - return {}; + auto lhs_numeric = TRY_OR_DISCARD(lhs.to_numeric(global_object)); + auto rhs_numeric = TRY_OR_DISCARD(rhs.to_numeric(global_object)); if (both_number(lhs_numeric, rhs_numeric)) { if (!lhs_numeric.is_finite_number()) return Value(0); @@ -1022,12 +1002,8 @@ Value right_shift(GlobalObject& global_object, Value lhs, Value rhs) // 13.9.3 The Unsigned Right Shift Operator ( >>> ), https://tc39.es/ecma262/#sec-unsigned-right-shift-operator Value unsigned_right_shift(GlobalObject& global_object, Value lhs, Value rhs) { - auto lhs_numeric = lhs.to_numeric(global_object); - if (global_object.vm().exception()) - return {}; - auto rhs_numeric = rhs.to_numeric(global_object); - if (global_object.vm().exception()) - return {}; + auto lhs_numeric = TRY_OR_DISCARD(lhs.to_numeric(global_object)); + auto rhs_numeric = TRY_OR_DISCARD(rhs.to_numeric(global_object)); if (both_number(lhs_numeric, rhs_numeric)) { if (!lhs_numeric.is_finite_number()) return Value(0); @@ -1083,12 +1059,8 @@ Value add(GlobalObject& global_object, Value lhs, Value rhs) return js_string(vm, builder.to_string()); } - auto lhs_numeric = lhs_primitive.to_numeric(global_object); - if (vm.exception()) - return {}; - auto rhs_numeric = rhs_primitive.to_numeric(global_object); - if (vm.exception()) - return {}; + auto lhs_numeric = TRY_OR_DISCARD(lhs_primitive.to_numeric(global_object)); + auto rhs_numeric = TRY_OR_DISCARD(rhs_primitive.to_numeric(global_object)); if (both_number(lhs_numeric, rhs_numeric)) return Value(lhs_numeric.as_double() + rhs_numeric.as_double()); if (both_bigint(lhs_numeric, rhs_numeric)) @@ -1101,12 +1073,8 @@ Value add(GlobalObject& global_object, Value lhs, Value rhs) Value sub(GlobalObject& global_object, Value lhs, Value rhs) { auto& vm = global_object.vm(); - auto lhs_numeric = lhs.to_numeric(global_object); - if (vm.exception()) - return {}; - auto rhs_numeric = rhs.to_numeric(global_object); - if (vm.exception()) - return {}; + auto lhs_numeric = TRY_OR_DISCARD(lhs.to_numeric(global_object)); + auto rhs_numeric = TRY_OR_DISCARD(rhs.to_numeric(global_object)); if (both_number(lhs_numeric, rhs_numeric)) return Value(lhs_numeric.as_double() - rhs_numeric.as_double()); if (both_bigint(lhs_numeric, rhs_numeric)) @@ -1119,12 +1087,8 @@ Value sub(GlobalObject& global_object, Value lhs, Value rhs) Value mul(GlobalObject& global_object, Value lhs, Value rhs) { auto& vm = global_object.vm(); - auto lhs_numeric = lhs.to_numeric(global_object); - if (vm.exception()) - return {}; - auto rhs_numeric = rhs.to_numeric(global_object); - if (vm.exception()) - return {}; + auto lhs_numeric = TRY_OR_DISCARD(lhs.to_numeric(global_object)); + auto rhs_numeric = TRY_OR_DISCARD(rhs.to_numeric(global_object)); if (both_number(lhs_numeric, rhs_numeric)) return Value(lhs_numeric.as_double() * rhs_numeric.as_double()); if (both_bigint(lhs_numeric, rhs_numeric)) @@ -1137,12 +1101,8 @@ Value mul(GlobalObject& global_object, Value lhs, Value rhs) Value div(GlobalObject& global_object, Value lhs, Value rhs) { auto& vm = global_object.vm(); - auto lhs_numeric = lhs.to_numeric(global_object); - if (vm.exception()) - return {}; - auto rhs_numeric = rhs.to_numeric(global_object); - if (vm.exception()) - return {}; + auto lhs_numeric = TRY_OR_DISCARD(lhs.to_numeric(global_object)); + auto rhs_numeric = TRY_OR_DISCARD(rhs.to_numeric(global_object)); if (both_number(lhs_numeric, rhs_numeric)) return Value(lhs_numeric.as_double() / rhs_numeric.as_double()); if (both_bigint(lhs_numeric, rhs_numeric)) { @@ -1160,12 +1120,8 @@ Value div(GlobalObject& global_object, Value lhs, Value rhs) Value mod(GlobalObject& global_object, Value lhs, Value rhs) { auto& vm = global_object.vm(); - auto lhs_numeric = lhs.to_numeric(global_object); - if (vm.exception()) - return {}; - auto rhs_numeric = rhs.to_numeric(global_object); - if (vm.exception()) - return {}; + auto lhs_numeric = TRY_OR_DISCARD(lhs.to_numeric(global_object)); + auto rhs_numeric = TRY_OR_DISCARD(rhs.to_numeric(global_object)); if (both_number(lhs_numeric, rhs_numeric)) { // 6.1.6.1.6 Number::remainder ( n, d ), https://tc39.es/ecma262/#sec-numeric-types-number-remainder @@ -1214,12 +1170,8 @@ Value mod(GlobalObject& global_object, Value lhs, Value rhs) Value exp(GlobalObject& global_object, Value lhs, Value rhs) { auto& vm = global_object.vm(); - auto lhs_numeric = lhs.to_numeric(global_object); - if (vm.exception()) - return {}; - auto rhs_numeric = rhs.to_numeric(global_object); - if (vm.exception()) - return {}; + auto lhs_numeric = TRY_OR_DISCARD(lhs.to_numeric(global_object)); + auto rhs_numeric = TRY_OR_DISCARD(rhs.to_numeric(global_object)); if (both_number(lhs_numeric, rhs_numeric)) return Value(pow(lhs_numeric.as_double(), rhs_numeric.as_double())); if (both_bigint(lhs_numeric, rhs_numeric)) { @@ -1534,12 +1486,8 @@ TriState is_less_than(GlobalObject& global_object, bool left_first, Value lhs, V return TriState::False; } - auto x_numeric = x_primitive.to_numeric(global_object); - if (global_object.vm().exception()) - return {}; - auto y_numeric = y_primitive.to_numeric(global_object); - if (global_object.vm().exception()) - return {}; + auto x_numeric = TRY_OR_DISCARD(x_primitive.to_numeric(global_object)); + auto y_numeric = TRY_OR_DISCARD(y_primitive.to_numeric(global_object)); if (x_numeric.is_nan() || y_numeric.is_nan()) return TriState::Unknown; diff --git a/Userland/Libraries/LibJS/Runtime/Value.h b/Userland/Libraries/LibJS/Runtime/Value.h index 62ae09cbdb..ddf1e5f85b 100644 --- a/Userland/Libraries/LibJS/Runtime/Value.h +++ b/Userland/Libraries/LibJS/Runtime/Value.h @@ -308,7 +308,7 @@ public: ThrowCompletionOr to_primitive_string(GlobalObject&); ThrowCompletionOr to_primitive(GlobalObject&, PreferredType preferred_type = PreferredType::Default) const; ThrowCompletionOr to_object(GlobalObject&) const; - Value to_numeric(GlobalObject&) const; + ThrowCompletionOr to_numeric(GlobalObject&) const; Value to_number(GlobalObject&) const; BigInt* to_bigint(GlobalObject&) const; i64 to_bigint_int64(GlobalObject&) const;