From 9eb065a1f62f34f62f2484139cf3063ef42565dd Mon Sep 17 00:00:00 2001 From: Linus Groh Date: Tue, 12 Oct 2021 18:09:14 +0100 Subject: [PATCH] LibJS: Convert to_primitive() to ThrowCompletionOr --- .../LibJS/Runtime/BigIntConstructor.cpp | 4 +- .../Libraries/LibJS/Runtime/DatePrototype.cpp | 4 +- Userland/Libraries/LibJS/Runtime/Value.cpp | 63 ++++++------------- Userland/Libraries/LibJS/Runtime/Value.h | 2 +- 4 files changed, 21 insertions(+), 52 deletions(-) diff --git a/Userland/Libraries/LibJS/Runtime/BigIntConstructor.cpp b/Userland/Libraries/LibJS/Runtime/BigIntConstructor.cpp index ecd74945c9..44ae17c1b1 100644 --- a/Userland/Libraries/LibJS/Runtime/BigIntConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/BigIntConstructor.cpp @@ -48,9 +48,7 @@ Value BigIntConstructor::call() auto value = vm.argument(0); // 2. Let prim be ? ToPrimitive(value, number). - auto primitive = value.to_primitive(global_object, Value::PreferredType::Number); - if (vm.exception()) - return {}; + auto primitive = TRY_OR_DISCARD(value.to_primitive(global_object, Value::PreferredType::Number)); // 3. If Type(prim) is Number, return ? NumberToBigInt(prim). if (primitive.is_number()) diff --git a/Userland/Libraries/LibJS/Runtime/DatePrototype.cpp b/Userland/Libraries/LibJS/Runtime/DatePrototype.cpp index 0357997900..6cdb9efa81 100644 --- a/Userland/Libraries/LibJS/Runtime/DatePrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/DatePrototype.cpp @@ -835,9 +835,7 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_json) { auto this_value = vm.this_value(global_object); - auto time_value = this_value.to_primitive(global_object, Value::PreferredType::Number); - if (vm.exception()) - return {}; + auto time_value = TRY_OR_DISCARD(this_value.to_primitive(global_object, Value::PreferredType::Number)); if (time_value.is_number() && !time_value.is_finite_number()) return js_null(); diff --git a/Userland/Libraries/LibJS/Runtime/Value.cpp b/Userland/Libraries/LibJS/Runtime/Value.cpp index 920cc88932..8dafd1cbb6 100644 --- a/Userland/Libraries/LibJS/Runtime/Value.cpp +++ b/Userland/Libraries/LibJS/Runtime/Value.cpp @@ -353,9 +353,7 @@ ThrowCompletionOr Value::to_string(GlobalObject& global_object) const case Type::BigInt: return m_value.as_bigint->big_integer().to_base(10); case Type::Object: { - auto primitive_value = to_primitive(global_object, PreferredType::String); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto primitive_value = TRY(to_primitive(global_object, PreferredType::String)); return primitive_value.to_string(global_object); } default: @@ -404,7 +402,7 @@ bool Value::to_boolean() const } // 7.1.1 ToPrimitive ( input [ , preferredType ] ), https://tc39.es/ecma262/#sec-toprimitive -Value Value::to_primitive(GlobalObject& global_object, PreferredType preferred_type) const +ThrowCompletionOr Value::to_primitive(GlobalObject& global_object, PreferredType preferred_type) const { auto get_hint_for_preferred_type = [&]() -> String { switch (preferred_type) { @@ -420,18 +418,17 @@ Value Value::to_primitive(GlobalObject& global_object, PreferredType preferred_t }; if (is_object()) { auto& vm = global_object.vm(); - auto to_primitive_method = TRY_OR_DISCARD(get_method(global_object, *vm.well_known_symbol_to_primitive())); + auto to_primitive_method = TRY(get_method(global_object, *vm.well_known_symbol_to_primitive())); if (to_primitive_method) { auto hint = get_hint_for_preferred_type(); - auto result = TRY_OR_DISCARD(vm.call(*to_primitive_method, *this, js_string(vm, hint))); + auto result = TRY(vm.call(*to_primitive_method, *this, js_string(vm, hint))); if (!result.is_object()) return result; - vm.throw_exception(global_object, ErrorType::ToPrimitiveReturnedObject, to_string_without_side_effects(), hint); - return {}; + return vm.throw_completion(global_object, ErrorType::ToPrimitiveReturnedObject, to_string_without_side_effects(), hint); } if (preferred_type == PreferredType::Default) preferred_type = PreferredType::Number; - return TRY_OR_DISCARD(as_object().ordinary_to_primitive(preferred_type)); + return as_object().ordinary_to_primitive(preferred_type); } return *this; } @@ -466,9 +463,7 @@ Object* 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 { - auto primitive = to_primitive(global_object, Value::PreferredType::Number); - if (global_object.vm().exception()) - return {}; + auto primitive = TRY_OR_DISCARD(to_primitive(global_object, Value::PreferredType::Number)); if (primitive.is_bigint()) return primitive; return primitive.to_number(global_object); @@ -508,9 +503,7 @@ Value Value::to_number(GlobalObject& global_object) const global_object.vm().throw_exception(global_object, ErrorType::Convert, "BigInt", "number"); return {}; case Type::Object: { - auto primitive = to_primitive(global_object, PreferredType::Number); - if (global_object.vm().exception()) - return {}; + auto primitive = TRY_OR_DISCARD(to_primitive(global_object, PreferredType::Number)); return primitive.to_number(global_object); } default: @@ -522,9 +515,7 @@ Value Value::to_number(GlobalObject& global_object) const BigInt* Value::to_bigint(GlobalObject& global_object) const { auto& vm = global_object.vm(); - auto primitive = to_primitive(global_object, PreferredType::Number); - if (vm.exception()) - return nullptr; + auto primitive = TRY_OR_DISCARD(to_primitive(global_object, PreferredType::Number)); switch (primitive.type()) { case Type::Undefined: vm.throw_exception(global_object, ErrorType::Convert, "undefined", "BigInt"); @@ -587,9 +578,7 @@ double Value::to_double(GlobalObject& global_object) const // 7.1.19 ToPropertyKey ( argument ), https://tc39.es/ecma262/#sec-topropertykey StringOrSymbol Value::to_property_key(GlobalObject& global_object) const { - auto key = to_primitive(global_object, PreferredType::String); - if (global_object.vm().exception()) - return {}; + auto key = TRY_OR_DISCARD(to_primitive(global_object, PreferredType::String)); if (key.is_symbol()) return &key.as_symbol(); return TRY_OR_DISCARD(key.to_string(global_object)); @@ -1073,12 +1062,8 @@ Value add(GlobalObject& global_object, Value lhs, Value rhs) return Value(lhs.as_double() + rhs.as_double()); } auto& vm = global_object.vm(); - auto lhs_primitive = lhs.to_primitive(global_object); - if (vm.exception()) - return {}; - auto rhs_primitive = rhs.to_primitive(global_object); - if (vm.exception()) - return {}; + auto lhs_primitive = TRY_OR_DISCARD(lhs.to_primitive(global_object)); + auto rhs_primitive = TRY_OR_DISCARD(rhs.to_primitive(global_object)); if (lhs_primitive.is_string() && rhs_primitive.is_string()) { auto const& lhs_string = lhs_primitive.as_string(); @@ -1445,16 +1430,12 @@ bool is_loosely_equal(GlobalObject& global_object, Value lhs, Value rhs) return is_loosely_equal(global_object, lhs, rhs.to_number(global_object)); if ((lhs.is_string() || lhs.is_number() || lhs.is_bigint() || lhs.is_symbol()) && rhs.is_object()) { - auto rhs_primitive = rhs.to_primitive(global_object); - if (vm.exception()) - return false; + auto rhs_primitive = TRY_OR_DISCARD(rhs.to_primitive(global_object)); return is_loosely_equal(global_object, lhs, rhs_primitive); } if (lhs.is_object() && (rhs.is_string() || rhs.is_number() || lhs.is_bigint() || rhs.is_symbol())) { - auto lhs_primitive = lhs.to_primitive(global_object); - if (vm.exception()) - return false; + auto lhs_primitive = TRY_OR_DISCARD(lhs.to_primitive(global_object)); return is_loosely_equal(global_object, lhs_primitive, rhs); } @@ -1479,19 +1460,11 @@ TriState is_less_than(GlobalObject& global_object, bool left_first, Value lhs, V Value y_primitive; if (left_first) { - x_primitive = lhs.to_primitive(global_object, Value::PreferredType::Number); - if (global_object.vm().exception()) - return {}; - y_primitive = rhs.to_primitive(global_object, Value::PreferredType::Number); - if (global_object.vm().exception()) - return {}; + x_primitive = TRY_OR_DISCARD(lhs.to_primitive(global_object, Value::PreferredType::Number)); + y_primitive = TRY_OR_DISCARD(rhs.to_primitive(global_object, Value::PreferredType::Number)); } else { - y_primitive = lhs.to_primitive(global_object, Value::PreferredType::Number); - if (global_object.vm().exception()) - return {}; - x_primitive = rhs.to_primitive(global_object, Value::PreferredType::Number); - if (global_object.vm().exception()) - return {}; + y_primitive = TRY_OR_DISCARD(lhs.to_primitive(global_object, Value::PreferredType::Number)); + x_primitive = TRY_OR_DISCARD(rhs.to_primitive(global_object, Value::PreferredType::Number)); } if (x_primitive.is_string() && y_primitive.is_string()) { diff --git a/Userland/Libraries/LibJS/Runtime/Value.h b/Userland/Libraries/LibJS/Runtime/Value.h index 8b296c9781..70c51f3af6 100644 --- a/Userland/Libraries/LibJS/Runtime/Value.h +++ b/Userland/Libraries/LibJS/Runtime/Value.h @@ -306,7 +306,7 @@ public: ThrowCompletionOr to_string(GlobalObject&) const; ThrowCompletionOr to_utf16_string(GlobalObject&) const; ThrowCompletionOr to_primitive_string(GlobalObject&); - Value to_primitive(GlobalObject&, PreferredType preferred_type = PreferredType::Default) const; + ThrowCompletionOr to_primitive(GlobalObject&, PreferredType preferred_type = PreferredType::Default) const; Object* to_object(GlobalObject&) const; Value to_numeric(GlobalObject&) const; Value to_number(GlobalObject&) const;