From 545d403f6b00f1753cc93add1752e2aab1641471 Mon Sep 17 00:00:00 2001 From: Idan Horowitz Date: Tue, 19 Oct 2021 00:13:29 +0300 Subject: LibJS: Convert Value operator AOs to ThrowCompletionOr --- Userland/Libraries/LibJS/AST.cpp | 66 +++--- Userland/Libraries/LibJS/Bytecode/Op.cpp | 65 +++--- .../Libraries/LibJS/Runtime/FunctionPrototype.cpp | 2 +- Userland/Libraries/LibJS/Runtime/Value.cpp | 247 +++++++++------------ Userland/Libraries/LibJS/Runtime/Value.h | 44 ++-- 5 files changed, 204 insertions(+), 220 deletions(-) diff --git a/Userland/Libraries/LibJS/AST.cpp b/Userland/Libraries/LibJS/AST.cpp index 0340c5e889..c3fdfdb512 100644 --- a/Userland/Libraries/LibJS/AST.cpp +++ b/Userland/Libraries/LibJS/AST.cpp @@ -909,17 +909,17 @@ Value BinaryExpression::execute(Interpreter& interpreter, GlobalObject& global_o switch (m_op) { case BinaryOp::Addition: - return add(global_object, lhs_result, rhs_result); + return TRY_OR_DISCARD(add(global_object, lhs_result, rhs_result)); case BinaryOp::Subtraction: - return sub(global_object, lhs_result, rhs_result); + return TRY_OR_DISCARD(sub(global_object, lhs_result, rhs_result)); case BinaryOp::Multiplication: - return mul(global_object, lhs_result, rhs_result); + return TRY_OR_DISCARD(mul(global_object, lhs_result, rhs_result)); case BinaryOp::Division: - return div(global_object, lhs_result, rhs_result); + return TRY_OR_DISCARD(div(global_object, lhs_result, rhs_result)); case BinaryOp::Modulo: - return mod(global_object, lhs_result, rhs_result); + return TRY_OR_DISCARD(mod(global_object, lhs_result, rhs_result)); case BinaryOp::Exponentiation: - return exp(global_object, lhs_result, rhs_result); + return TRY_OR_DISCARD(exp(global_object, lhs_result, rhs_result)); case BinaryOp::StrictlyEquals: return Value(is_strictly_equal(lhs_result, rhs_result)); case BinaryOp::StrictlyInequals: @@ -929,29 +929,29 @@ Value BinaryExpression::execute(Interpreter& interpreter, GlobalObject& global_o case BinaryOp::LooselyInequals: return Value(!TRY_OR_DISCARD(is_loosely_equal(global_object, lhs_result, rhs_result))); case BinaryOp::GreaterThan: - return greater_than(global_object, lhs_result, rhs_result); + return TRY_OR_DISCARD(greater_than(global_object, lhs_result, rhs_result)); case BinaryOp::GreaterThanEquals: - return greater_than_equals(global_object, lhs_result, rhs_result); + return TRY_OR_DISCARD(greater_than_equals(global_object, lhs_result, rhs_result)); case BinaryOp::LessThan: - return less_than(global_object, lhs_result, rhs_result); + return TRY_OR_DISCARD(less_than(global_object, lhs_result, rhs_result)); case BinaryOp::LessThanEquals: - return less_than_equals(global_object, lhs_result, rhs_result); + return TRY_OR_DISCARD(less_than_equals(global_object, lhs_result, rhs_result)); case BinaryOp::BitwiseAnd: - return bitwise_and(global_object, lhs_result, rhs_result); + return TRY_OR_DISCARD(bitwise_and(global_object, lhs_result, rhs_result)); case BinaryOp::BitwiseOr: - return bitwise_or(global_object, lhs_result, rhs_result); + return TRY_OR_DISCARD(bitwise_or(global_object, lhs_result, rhs_result)); case BinaryOp::BitwiseXor: - return bitwise_xor(global_object, lhs_result, rhs_result); + return TRY_OR_DISCARD(bitwise_xor(global_object, lhs_result, rhs_result)); case BinaryOp::LeftShift: - return left_shift(global_object, lhs_result, rhs_result); + return TRY_OR_DISCARD(left_shift(global_object, lhs_result, rhs_result)); case BinaryOp::RightShift: - return right_shift(global_object, lhs_result, rhs_result); + return TRY_OR_DISCARD(right_shift(global_object, lhs_result, rhs_result)); case BinaryOp::UnsignedRightShift: - return unsigned_right_shift(global_object, lhs_result, rhs_result); + return TRY_OR_DISCARD(unsigned_right_shift(global_object, lhs_result, rhs_result)); case BinaryOp::In: - return in(global_object, lhs_result, rhs_result); + return TRY_OR_DISCARD(in(global_object, lhs_result, rhs_result)); case BinaryOp::InstanceOf: - return instance_of(global_object, lhs_result, rhs_result); + return TRY_OR_DISCARD(instance_of(global_object, lhs_result, rhs_result)); } VERIFY_NOT_REACHED(); @@ -1134,13 +1134,13 @@ Value UnaryExpression::execute(Interpreter& interpreter, GlobalObject& global_ob switch (m_op) { case UnaryOp::BitwiseNot: - return bitwise_not(global_object, lhs_result); + return TRY_OR_DISCARD(bitwise_not(global_object, lhs_result)); case UnaryOp::Not: return Value(!lhs_result.to_boolean()); case UnaryOp::Plus: - return unary_plus(global_object, lhs_result); + return TRY_OR_DISCARD(unary_plus(global_object, lhs_result)); case UnaryOp::Minus: - return unary_minus(global_object, lhs_result); + return TRY_OR_DISCARD(unary_minus(global_object, lhs_result)); case UnaryOp::Typeof: return js_string(vm, lhs_result.typeof()); case UnaryOp::Void: @@ -1987,40 +1987,40 @@ Value AssignmentExpression::execute(Interpreter& interpreter, GlobalObject& glob switch (m_op) { case AssignmentOp::AdditionAssignment: - rhs_result = add(global_object, lhs_result, rhs_result); + rhs_result = TRY_OR_DISCARD(add(global_object, lhs_result, rhs_result)); break; case AssignmentOp::SubtractionAssignment: - rhs_result = sub(global_object, lhs_result, rhs_result); + rhs_result = TRY_OR_DISCARD(sub(global_object, lhs_result, rhs_result)); break; case AssignmentOp::MultiplicationAssignment: - rhs_result = mul(global_object, lhs_result, rhs_result); + rhs_result = TRY_OR_DISCARD(mul(global_object, lhs_result, rhs_result)); break; case AssignmentOp::DivisionAssignment: - rhs_result = div(global_object, lhs_result, rhs_result); + rhs_result = TRY_OR_DISCARD(div(global_object, lhs_result, rhs_result)); break; case AssignmentOp::ModuloAssignment: - rhs_result = mod(global_object, lhs_result, rhs_result); + rhs_result = TRY_OR_DISCARD(mod(global_object, lhs_result, rhs_result)); break; case AssignmentOp::ExponentiationAssignment: - rhs_result = exp(global_object, lhs_result, rhs_result); + rhs_result = TRY_OR_DISCARD(exp(global_object, lhs_result, rhs_result)); break; case AssignmentOp::BitwiseAndAssignment: - rhs_result = bitwise_and(global_object, lhs_result, rhs_result); + rhs_result = TRY_OR_DISCARD(bitwise_and(global_object, lhs_result, rhs_result)); break; case AssignmentOp::BitwiseOrAssignment: - rhs_result = bitwise_or(global_object, lhs_result, rhs_result); + rhs_result = TRY_OR_DISCARD(bitwise_or(global_object, lhs_result, rhs_result)); break; case AssignmentOp::BitwiseXorAssignment: - rhs_result = bitwise_xor(global_object, lhs_result, rhs_result); + rhs_result = TRY_OR_DISCARD(bitwise_xor(global_object, lhs_result, rhs_result)); break; case AssignmentOp::LeftShiftAssignment: - rhs_result = left_shift(global_object, lhs_result, rhs_result); + rhs_result = TRY_OR_DISCARD(left_shift(global_object, lhs_result, rhs_result)); break; case AssignmentOp::RightShiftAssignment: - rhs_result = right_shift(global_object, lhs_result, rhs_result); + rhs_result = TRY_OR_DISCARD(right_shift(global_object, lhs_result, rhs_result)); break; case AssignmentOp::UnsignedRightShiftAssignment: - rhs_result = unsigned_right_shift(global_object, lhs_result, rhs_result); + rhs_result = TRY_OR_DISCARD(unsigned_right_shift(global_object, lhs_result, rhs_result)); break; case AssignmentOp::Assignment: case AssignmentOp::AndAssignment: diff --git a/Userland/Libraries/LibJS/Bytecode/Op.cpp b/Userland/Libraries/LibJS/Bytecode/Op.cpp index e930e75ed0..1b8a9b719b 100644 --- a/Userland/Libraries/LibJS/Bytecode/Op.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Op.cpp @@ -55,58 +55,64 @@ void Store::execute_impl(Bytecode::Interpreter& interpreter) const interpreter.reg(m_dst) = interpreter.accumulator(); } -static Value abstract_inequals(GlobalObject& global_object, Value src1, Value src2) +static ThrowCompletionOr abstract_inequals(GlobalObject& global_object, Value src1, Value src2) { - return Value(!TRY_OR_DISCARD(is_loosely_equal(global_object, src1, src2))); + return Value(!TRY(is_loosely_equal(global_object, src1, src2))); } -static Value abstract_equals(GlobalObject& global_object, Value src1, Value src2) +static ThrowCompletionOr abstract_equals(GlobalObject& global_object, Value src1, Value src2) { - return Value(TRY_OR_DISCARD(is_loosely_equal(global_object, src1, src2))); + return Value(TRY(is_loosely_equal(global_object, src1, src2))); } -static Value typed_inequals(GlobalObject&, Value src1, Value src2) +static ThrowCompletionOr typed_inequals(GlobalObject&, Value src1, Value src2) { return Value(!is_strictly_equal(src1, src2)); } -static Value typed_equals(GlobalObject&, Value src1, Value src2) +static ThrowCompletionOr typed_equals(GlobalObject&, Value src1, Value src2) { return Value(is_strictly_equal(src1, src2)); } -#define JS_DEFINE_COMMON_BINARY_OP(OpTitleCase, op_snake_case) \ - void OpTitleCase::execute_impl(Bytecode::Interpreter& interpreter) const \ - { \ - auto lhs = interpreter.reg(m_lhs_reg); \ - auto rhs = interpreter.accumulator(); \ - interpreter.accumulator() = op_snake_case(interpreter.global_object(), lhs, rhs); \ - } \ - String OpTitleCase::to_string_impl(Bytecode::Executable const&) const \ - { \ - return String::formatted(#OpTitleCase " {}", m_lhs_reg); \ +#define JS_DEFINE_COMMON_BINARY_OP(OpTitleCase, op_snake_case) \ + void OpTitleCase::execute_impl(Bytecode::Interpreter& interpreter) const \ + { \ + auto lhs = interpreter.reg(m_lhs_reg); \ + auto rhs = interpreter.accumulator(); \ + auto result_or_error = op_snake_case(interpreter.global_object(), lhs, rhs); \ + if (result_or_error.is_error()) \ + return; \ + interpreter.accumulator() = result_or_error.release_value(); \ + } \ + String OpTitleCase::to_string_impl(Bytecode::Executable const&) const \ + { \ + return String::formatted(#OpTitleCase " {}", m_lhs_reg); \ } JS_ENUMERATE_COMMON_BINARY_OPS(JS_DEFINE_COMMON_BINARY_OP) -static Value not_(GlobalObject&, Value value) +static ThrowCompletionOr not_(GlobalObject&, Value value) { return Value(!value.to_boolean()); } -static Value typeof_(GlobalObject& global_object, Value value) +static ThrowCompletionOr typeof_(GlobalObject& global_object, Value value) { - return js_string(global_object.vm(), value.typeof()); + return Value(js_string(global_object.vm(), value.typeof())); } -#define JS_DEFINE_COMMON_UNARY_OP(OpTitleCase, op_snake_case) \ - void OpTitleCase::execute_impl(Bytecode::Interpreter& interpreter) const \ - { \ - interpreter.accumulator() = op_snake_case(interpreter.global_object(), interpreter.accumulator()); \ - } \ - String OpTitleCase::to_string_impl(Bytecode::Executable const&) const \ - { \ - return #OpTitleCase; \ +#define JS_DEFINE_COMMON_UNARY_OP(OpTitleCase, op_snake_case) \ + void OpTitleCase::execute_impl(Bytecode::Interpreter& interpreter) const \ + { \ + auto result_or_error = op_snake_case(interpreter.global_object(), interpreter.accumulator()); \ + if (result_or_error.is_error()) \ + return; \ + interpreter.accumulator() = result_or_error.release_value(); \ + } \ + String OpTitleCase::to_string_impl(Bytecode::Executable const&) const \ + { \ + return #OpTitleCase; \ } JS_ENUMERATE_COMMON_UNARY_OPS(JS_DEFINE_COMMON_UNARY_OP) @@ -218,7 +224,10 @@ void CopyObjectExcludingProperties::execute_impl(Bytecode::Interpreter& interpre void ConcatString::execute_impl(Bytecode::Interpreter& interpreter) const { - interpreter.reg(m_lhs) = add(interpreter.global_object(), interpreter.reg(m_lhs), interpreter.accumulator()); + auto result_or_error = add(interpreter.global_object(), interpreter.reg(m_lhs), interpreter.accumulator()); + if (result_or_error.is_error()) + return; + interpreter.reg(m_lhs) = result_or_error.release_value(); } void GetVariable::execute_impl(Bytecode::Interpreter& interpreter) const diff --git a/Userland/Libraries/LibJS/Runtime/FunctionPrototype.cpp b/Userland/Libraries/LibJS/Runtime/FunctionPrototype.cpp index 2f5464010b..90a0966eae 100644 --- a/Userland/Libraries/LibJS/Runtime/FunctionPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/FunctionPrototype.cpp @@ -151,7 +151,7 @@ JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::to_string) // 20.2.3.6 Function.prototype [ @@hasInstance ] ( V ), https://tc39.es/ecma262/#sec-function.prototype-@@hasinstance JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::symbol_has_instance) { - return ordinary_has_instance(global_object, vm.argument(0), vm.this_value(global_object)); + return TRY_OR_DISCARD(ordinary_has_instance(global_object, vm.argument(0), vm.this_value(global_object))); } } diff --git a/Userland/Libraries/LibJS/Runtime/Value.cpp b/Userland/Libraries/LibJS/Runtime/Value.cpp index 93964005e5..38f9ecf55f 100644 --- a/Userland/Libraries/LibJS/Runtime/Value.cpp +++ b/Userland/Libraries/LibJS/Runtime/Value.cpp @@ -769,64 +769,63 @@ ThrowCompletionOr Value::get_method(GlobalObject& global_object } // 13.10 Relational Operators, https://tc39.es/ecma262/#sec-relational-operators -Value greater_than(GlobalObject& global_object, Value lhs, Value rhs) +ThrowCompletionOr greater_than(GlobalObject& global_object, Value lhs, Value rhs) { - TriState relation = TRY_OR_DISCARD(is_less_than(global_object, false, lhs, rhs)); + TriState relation = TRY(is_less_than(global_object, false, lhs, rhs)); if (relation == TriState::Unknown) return Value(false); return Value(relation == TriState::True); } // 13.10 Relational Operators, https://tc39.es/ecma262/#sec-relational-operators -Value greater_than_equals(GlobalObject& global_object, Value lhs, Value rhs) +ThrowCompletionOr greater_than_equals(GlobalObject& global_object, Value lhs, Value rhs) { - TriState relation = TRY_OR_DISCARD(is_less_than(global_object, true, lhs, rhs)); + TriState relation = TRY(is_less_than(global_object, true, lhs, rhs)); if (relation == TriState::Unknown || relation == TriState::True) return Value(false); return Value(true); } // 13.10 Relational Operators, https://tc39.es/ecma262/#sec-relational-operators -Value less_than(GlobalObject& global_object, Value lhs, Value rhs) +ThrowCompletionOr less_than(GlobalObject& global_object, Value lhs, Value rhs) { - TriState relation = TRY_OR_DISCARD(is_less_than(global_object, true, lhs, rhs)); + TriState relation = TRY(is_less_than(global_object, true, lhs, rhs)); if (relation == TriState::Unknown) return Value(false); return Value(relation == TriState::True); } // 13.10 Relational Operators, https://tc39.es/ecma262/#sec-relational-operators -Value less_than_equals(GlobalObject& global_object, Value lhs, Value rhs) +ThrowCompletionOr less_than_equals(GlobalObject& global_object, Value lhs, Value rhs) { - TriState relation = TRY_OR_DISCARD(is_less_than(global_object, false, lhs, rhs)); + TriState relation = TRY(is_less_than(global_object, false, lhs, rhs)); if (relation == TriState::Unknown || relation == TriState::True) return Value(false); return Value(true); } // 13.12 Binary Bitwise Operators, https://tc39.es/ecma262/#sec-binary-bitwise-operators -Value bitwise_and(GlobalObject& global_object, Value lhs, Value rhs) +ThrowCompletionOr bitwise_and(GlobalObject& global_object, Value lhs, Value rhs) { auto& vm = global_object.vm(); - auto lhs_numeric = TRY_OR_DISCARD(lhs.to_numeric(global_object)); - auto rhs_numeric = TRY_OR_DISCARD(rhs.to_numeric(global_object)); + auto lhs_numeric = TRY(lhs.to_numeric(global_object)); + auto rhs_numeric = TRY(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); - return Value(TRY_OR_DISCARD(lhs_numeric.to_i32(global_object)) & TRY_OR_DISCARD(rhs_numeric.to_i32(global_object))); + return Value(TRY(lhs_numeric.to_i32(global_object)) & TRY(rhs_numeric.to_i32(global_object))); } if (both_bigint(lhs_numeric, rhs_numeric)) - return js_bigint(vm, lhs_numeric.as_bigint().big_integer().bitwise_and(rhs_numeric.as_bigint().big_integer())); - vm.throw_exception(global_object, ErrorType::BigIntBadOperatorOtherType, "bitwise AND"); - return {}; + return Value(js_bigint(vm, lhs_numeric.as_bigint().big_integer().bitwise_and(rhs_numeric.as_bigint().big_integer()))); + return vm.throw_completion(global_object, ErrorType::BigIntBadOperatorOtherType, "bitwise AND"); } // 13.12 Binary Bitwise Operators, https://tc39.es/ecma262/#sec-binary-bitwise-operators -Value bitwise_or(GlobalObject& global_object, Value lhs, Value rhs) +ThrowCompletionOr bitwise_or(GlobalObject& global_object, Value lhs, Value rhs) { auto& vm = global_object.vm(); - auto lhs_numeric = TRY_OR_DISCARD(lhs.to_numeric(global_object)); - auto rhs_numeric = TRY_OR_DISCARD(rhs.to_numeric(global_object)); + auto lhs_numeric = TRY(lhs.to_numeric(global_object)); + auto rhs_numeric = TRY(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); @@ -834,20 +833,19 @@ Value bitwise_or(GlobalObject& global_object, Value lhs, Value rhs) return rhs_numeric; if (!rhs_numeric.is_finite_number()) return lhs_numeric; - return Value(TRY_OR_DISCARD(lhs_numeric.to_i32(global_object)) | TRY_OR_DISCARD(rhs_numeric.to_i32(global_object))); + return Value(TRY(lhs_numeric.to_i32(global_object)) | TRY(rhs_numeric.to_i32(global_object))); } if (both_bigint(lhs_numeric, rhs_numeric)) - return js_bigint(vm, lhs_numeric.as_bigint().big_integer().bitwise_or(rhs_numeric.as_bigint().big_integer())); - vm.throw_exception(global_object, ErrorType::BigIntBadOperatorOtherType, "bitwise OR"); - return {}; + return Value(js_bigint(vm, lhs_numeric.as_bigint().big_integer().bitwise_or(rhs_numeric.as_bigint().big_integer()))); + return vm.throw_completion(global_object, ErrorType::BigIntBadOperatorOtherType, "bitwise OR"); } // 13.12 Binary Bitwise Operators, https://tc39.es/ecma262/#sec-binary-bitwise-operators -Value bitwise_xor(GlobalObject& global_object, Value lhs, Value rhs) +ThrowCompletionOr bitwise_xor(GlobalObject& global_object, Value lhs, Value rhs) { auto& vm = global_object.vm(); - auto lhs_numeric = TRY_OR_DISCARD(lhs.to_numeric(global_object)); - auto rhs_numeric = TRY_OR_DISCARD(rhs.to_numeric(global_object)); + auto lhs_numeric = TRY(lhs.to_numeric(global_object)); + auto rhs_numeric = TRY(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); @@ -855,56 +853,55 @@ Value bitwise_xor(GlobalObject& global_object, Value lhs, Value rhs) return rhs_numeric; if (!rhs_numeric.is_finite_number()) return lhs_numeric; - return Value(TRY_OR_DISCARD(lhs_numeric.to_i32(global_object)) ^ TRY_OR_DISCARD(rhs_numeric.to_i32(global_object))); + return Value(TRY(lhs_numeric.to_i32(global_object)) ^ TRY(rhs_numeric.to_i32(global_object))); } if (both_bigint(lhs_numeric, rhs_numeric)) - return js_bigint(vm, lhs_numeric.as_bigint().big_integer().bitwise_xor(rhs_numeric.as_bigint().big_integer())); - vm.throw_exception(global_object, ErrorType::BigIntBadOperatorOtherType, "bitwise XOR"); - return {}; + return Value(js_bigint(vm, lhs_numeric.as_bigint().big_integer().bitwise_xor(rhs_numeric.as_bigint().big_integer()))); + return vm.throw_completion(global_object, ErrorType::BigIntBadOperatorOtherType, "bitwise XOR"); } // 13.5.6 Bitwise NOT Operator ( ~ ), https://tc39.es/ecma262/#sec-bitwise-not-operator -Value bitwise_not(GlobalObject& global_object, Value lhs) +ThrowCompletionOr bitwise_not(GlobalObject& global_object, Value lhs) { auto& vm = global_object.vm(); - auto lhs_numeric = TRY_OR_DISCARD(lhs.to_numeric(global_object)); + auto lhs_numeric = TRY(lhs.to_numeric(global_object)); if (lhs_numeric.is_number()) - return Value(~TRY_OR_DISCARD(lhs_numeric.to_i32(global_object))); + return Value(~TRY(lhs_numeric.to_i32(global_object))); auto big_integer_bitwise_not = lhs_numeric.as_bigint().big_integer(); big_integer_bitwise_not = big_integer_bitwise_not.plus(Crypto::SignedBigInteger { 1 }); big_integer_bitwise_not.negate(); - return js_bigint(vm, big_integer_bitwise_not); + return Value(js_bigint(vm, big_integer_bitwise_not)); } // 13.5.4 Unary + Operator, https://tc39.es/ecma262/#sec-unary-plus-operator -Value unary_plus(GlobalObject& global_object, Value lhs) +ThrowCompletionOr unary_plus(GlobalObject& global_object, Value lhs) { - return TRY_OR_DISCARD(lhs.to_number(global_object)); + return TRY(lhs.to_number(global_object)); } // 13.5.5 Unary - Operator, https://tc39.es/ecma262/#sec-unary-minus-operator -Value unary_minus(GlobalObject& global_object, Value lhs) +ThrowCompletionOr unary_minus(GlobalObject& global_object, Value lhs) { auto& vm = global_object.vm(); - auto lhs_numeric = TRY_OR_DISCARD(lhs.to_numeric(global_object)); + auto lhs_numeric = TRY(lhs.to_numeric(global_object)); if (lhs_numeric.is_number()) { if (lhs_numeric.is_nan()) return js_nan(); return Value(-lhs_numeric.as_double()); } if (lhs_numeric.as_bigint().big_integer() == BIGINT_ZERO) - return js_bigint(vm, BIGINT_ZERO); + return Value(js_bigint(vm, BIGINT_ZERO)); auto big_integer_negated = lhs_numeric.as_bigint().big_integer(); big_integer_negated.negate(); - return js_bigint(vm, big_integer_negated); + return Value(js_bigint(vm, big_integer_negated)); } // 13.9.1 The Left Shift Operator ( << ), https://tc39.es/ecma262/#sec-left-shift-operator -Value left_shift(GlobalObject& global_object, Value lhs, Value rhs) +ThrowCompletionOr left_shift(GlobalObject& global_object, Value lhs, Value rhs) { auto& vm = global_object.vm(); - auto lhs_numeric = TRY_OR_DISCARD(lhs.to_numeric(global_object)); - auto rhs_numeric = TRY_OR_DISCARD(rhs.to_numeric(global_object)); + auto lhs_numeric = TRY(lhs.to_numeric(global_object)); + auto rhs_numeric = TRY(rhs.to_numeric(global_object)); if (both_number(lhs_numeric, rhs_numeric)) { if (!lhs_numeric.is_finite_number()) return Value(0); @@ -918,20 +915,19 @@ Value left_shift(GlobalObject& global_object, Value lhs, Value rhs) if (both_bigint(lhs_numeric, rhs_numeric)) { auto multiplier_divisor = Crypto::SignedBigInteger { Crypto::NumberTheory::Power(Crypto::UnsignedBigInteger(2), rhs_numeric.as_bigint().big_integer().unsigned_value()) }; if (rhs_numeric.as_bigint().big_integer().is_negative()) - return js_bigint(vm, lhs_numeric.as_bigint().big_integer().divided_by(multiplier_divisor).quotient); + return Value(js_bigint(vm, lhs_numeric.as_bigint().big_integer().divided_by(multiplier_divisor).quotient)); else - return js_bigint(vm, lhs_numeric.as_bigint().big_integer().multiplied_by(multiplier_divisor)); + return Value(js_bigint(vm, lhs_numeric.as_bigint().big_integer().multiplied_by(multiplier_divisor))); } - global_object.vm().throw_exception(global_object, ErrorType::BigIntBadOperatorOtherType, "left-shift"); - return {}; + return vm.throw_completion(global_object, ErrorType::BigIntBadOperatorOtherType, "left-shift"); } // 13.9.2 The Signed Right Shift Operator ( >> ), https://tc39.es/ecma262/#sec-signed-right-shift-operator -Value right_shift(GlobalObject& global_object, Value lhs, Value rhs) +ThrowCompletionOr right_shift(GlobalObject& global_object, Value lhs, Value rhs) { auto& vm = global_object.vm(); - auto lhs_numeric = TRY_OR_DISCARD(lhs.to_numeric(global_object)); - auto rhs_numeric = TRY_OR_DISCARD(rhs.to_numeric(global_object)); + auto lhs_numeric = TRY(lhs.to_numeric(global_object)); + auto rhs_numeric = TRY(rhs.to_numeric(global_object)); if (both_number(lhs_numeric, rhs_numeric)) { if (!lhs_numeric.is_finite_number()) return Value(0); @@ -946,15 +942,15 @@ Value right_shift(GlobalObject& global_object, Value lhs, Value rhs) rhs_negated.negate(); return left_shift(global_object, lhs, js_bigint(vm, rhs_negated)); } - global_object.vm().throw_exception(global_object, ErrorType::BigIntBadOperatorOtherType, "right-shift"); - return {}; + return vm.throw_completion(global_object, ErrorType::BigIntBadOperatorOtherType, "right-shift"); } // 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) +ThrowCompletionOr unsigned_right_shift(GlobalObject& global_object, Value lhs, Value rhs) { - auto lhs_numeric = TRY_OR_DISCARD(lhs.to_numeric(global_object)); - auto rhs_numeric = TRY_OR_DISCARD(rhs.to_numeric(global_object)); + auto& vm = global_object.vm(); + auto lhs_numeric = TRY(lhs.to_numeric(global_object)); + auto rhs_numeric = TRY(rhs.to_numeric(global_object)); if (both_number(lhs_numeric, rhs_numeric)) { if (!lhs_numeric.is_finite_number()) return Value(0); @@ -965,12 +961,11 @@ Value unsigned_right_shift(GlobalObject& global_object, Value lhs, Value rhs) auto rhs_u32 = MUST(rhs_numeric.to_u32(global_object)) % 32; return Value(lhs_u32 >> rhs_u32); } - global_object.vm().throw_exception(global_object, ErrorType::BigIntBadOperator, "unsigned right-shift"); - return {}; + return vm.throw_completion(global_object, ErrorType::BigIntBadOperator, "unsigned right-shift"); } // 13.8.1 The Addition Operator ( + ), https://tc39.es/ecma262/#sec-addition-operator-plus -Value add(GlobalObject& global_object, Value lhs, Value rhs) +ThrowCompletionOr add(GlobalObject& global_object, Value lhs, Value rhs) { if (both_number(lhs, rhs)) { if (lhs.type() == Value::Type::Int32 && rhs.type() == Value::Type::Int32) { @@ -983,8 +978,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 = TRY_OR_DISCARD(lhs.to_primitive(global_object)); - auto rhs_primitive = TRY_OR_DISCARD(rhs.to_primitive(global_object)); + auto lhs_primitive = TRY(lhs.to_primitive(global_object)); + auto rhs_primitive = TRY(rhs.to_primitive(global_object)); if (lhs_primitive.is_string() && rhs_primitive.is_string()) { auto const& lhs_string = lhs_primitive.as_string(); @@ -998,81 +993,75 @@ Value add(GlobalObject& global_object, Value lhs, Value rhs) combined.ensure_capacity(lhs_utf16_string.length_in_code_units() + rhs_utf16_string.length_in_code_units()); combined.extend(lhs_utf16_string.string()); combined.extend(rhs_utf16_string.string()); - return js_string(vm.heap(), Utf16String(move(combined))); + return Value(js_string(vm.heap(), Utf16String(move(combined)))); } } if (lhs_primitive.is_string() || rhs_primitive.is_string()) { - auto lhs_string = TRY_OR_DISCARD(lhs_primitive.to_string(global_object)); - auto rhs_string = TRY_OR_DISCARD(rhs_primitive.to_string(global_object)); + auto lhs_string = TRY(lhs_primitive.to_string(global_object)); + auto rhs_string = TRY(rhs_primitive.to_string(global_object)); StringBuilder builder(lhs_string.length() + rhs_string.length()); builder.append(lhs_string); builder.append(rhs_string); - return js_string(vm, builder.to_string()); + return Value(js_string(vm, builder.to_string())); } - auto lhs_numeric = TRY_OR_DISCARD(lhs_primitive.to_numeric(global_object)); - auto rhs_numeric = TRY_OR_DISCARD(rhs_primitive.to_numeric(global_object)); + auto lhs_numeric = TRY(lhs_primitive.to_numeric(global_object)); + auto rhs_numeric = TRY(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)) - return js_bigint(vm, lhs_numeric.as_bigint().big_integer().plus(rhs_numeric.as_bigint().big_integer())); - vm.throw_exception(global_object, ErrorType::BigIntBadOperatorOtherType, "addition"); - return {}; + return Value(js_bigint(vm, lhs_numeric.as_bigint().big_integer().plus(rhs_numeric.as_bigint().big_integer()))); + return vm.throw_completion(global_object, ErrorType::BigIntBadOperatorOtherType, "addition"); } // 13.8.2 The Subtraction Operator ( - ), https://tc39.es/ecma262/#sec-subtraction-operator-minus -Value sub(GlobalObject& global_object, Value lhs, Value rhs) +ThrowCompletionOr sub(GlobalObject& global_object, Value lhs, Value rhs) { auto& vm = global_object.vm(); - auto lhs_numeric = TRY_OR_DISCARD(lhs.to_numeric(global_object)); - auto rhs_numeric = TRY_OR_DISCARD(rhs.to_numeric(global_object)); + auto lhs_numeric = TRY(lhs.to_numeric(global_object)); + auto rhs_numeric = TRY(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)) - return js_bigint(vm, lhs_numeric.as_bigint().big_integer().minus(rhs_numeric.as_bigint().big_integer())); - vm.throw_exception(global_object, ErrorType::BigIntBadOperatorOtherType, "subtraction"); - return {}; + return Value(js_bigint(vm, lhs_numeric.as_bigint().big_integer().minus(rhs_numeric.as_bigint().big_integer()))); + return vm.throw_completion(global_object, ErrorType::BigIntBadOperatorOtherType, "subtraction"); } // 13.7 Multiplicative Operators, https://tc39.es/ecma262/#sec-multiplicative-operators -Value mul(GlobalObject& global_object, Value lhs, Value rhs) +ThrowCompletionOr mul(GlobalObject& global_object, Value lhs, Value rhs) { auto& vm = global_object.vm(); - auto lhs_numeric = TRY_OR_DISCARD(lhs.to_numeric(global_object)); - auto rhs_numeric = TRY_OR_DISCARD(rhs.to_numeric(global_object)); + auto lhs_numeric = TRY(lhs.to_numeric(global_object)); + auto rhs_numeric = TRY(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)) - return js_bigint(vm, lhs_numeric.as_bigint().big_integer().multiplied_by(rhs_numeric.as_bigint().big_integer())); - vm.throw_exception(global_object, ErrorType::BigIntBadOperatorOtherType, "multiplication"); - return {}; + return Value(js_bigint(vm, lhs_numeric.as_bigint().big_integer().multiplied_by(rhs_numeric.as_bigint().big_integer()))); + return vm.throw_completion(global_object, ErrorType::BigIntBadOperatorOtherType, "multiplication"); } // 13.7 Multiplicative Operators, https://tc39.es/ecma262/#sec-multiplicative-operators -Value div(GlobalObject& global_object, Value lhs, Value rhs) +ThrowCompletionOr div(GlobalObject& global_object, Value lhs, Value rhs) { auto& vm = global_object.vm(); - auto lhs_numeric = TRY_OR_DISCARD(lhs.to_numeric(global_object)); - auto rhs_numeric = TRY_OR_DISCARD(rhs.to_numeric(global_object)); + auto lhs_numeric = TRY(lhs.to_numeric(global_object)); + auto rhs_numeric = TRY(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)) { - if (rhs_numeric.as_bigint().big_integer() == BIGINT_ZERO) { - vm.throw_exception(global_object, ErrorType::DivisionByZero); - return {}; - } - return js_bigint(vm, lhs_numeric.as_bigint().big_integer().divided_by(rhs_numeric.as_bigint().big_integer()).quotient); + if (rhs_numeric.as_bigint().big_integer() == BIGINT_ZERO) + return vm.throw_completion(global_object, ErrorType::DivisionByZero); + return Value(js_bigint(vm, lhs_numeric.as_bigint().big_integer().divided_by(rhs_numeric.as_bigint().big_integer()).quotient)); } - vm.throw_exception(global_object, ErrorType::BigIntBadOperatorOtherType, "division"); - return {}; + return vm.throw_completion(global_object, ErrorType::BigIntBadOperatorOtherType, "division"); } // 13.7 Multiplicative Operators, https://tc39.es/ecma262/#sec-multiplicative-operators -Value mod(GlobalObject& global_object, Value lhs, Value rhs) +ThrowCompletionOr mod(GlobalObject& global_object, Value lhs, Value rhs) { auto& vm = global_object.vm(); - auto lhs_numeric = TRY_OR_DISCARD(lhs.to_numeric(global_object)); - auto rhs_numeric = TRY_OR_DISCARD(rhs.to_numeric(global_object)); + auto lhs_numeric = TRY(lhs.to_numeric(global_object)); + auto rhs_numeric = TRY(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 @@ -1107,67 +1096,55 @@ Value mod(GlobalObject& global_object, Value lhs, Value rhs) return Value(index - trunc * period); } if (both_bigint(lhs_numeric, rhs_numeric)) { - if (rhs_numeric.as_bigint().big_integer() == BIGINT_ZERO) { - vm.throw_exception(global_object, ErrorType::DivisionByZero); - return {}; - } - return js_bigint(vm, lhs_numeric.as_bigint().big_integer().divided_by(rhs_numeric.as_bigint().big_integer()).remainder); + if (rhs_numeric.as_bigint().big_integer() == BIGINT_ZERO) + return vm.throw_completion(global_object, ErrorType::DivisionByZero); + return Value(js_bigint(vm, lhs_numeric.as_bigint().big_integer().divided_by(rhs_numeric.as_bigint().big_integer()).remainder)); } - vm.throw_exception(global_object, ErrorType::BigIntBadOperatorOtherType, "modulo"); - return {}; + return vm.throw_completion(global_object, ErrorType::BigIntBadOperatorOtherType, "modulo"); } // 13.6 Exponentiation Operator, https://tc39.es/ecma262/#sec-exp-operator -Value exp(GlobalObject& global_object, Value lhs, Value rhs) +ThrowCompletionOr exp(GlobalObject& global_object, Value lhs, Value rhs) { auto& vm = global_object.vm(); - auto lhs_numeric = TRY_OR_DISCARD(lhs.to_numeric(global_object)); - auto rhs_numeric = TRY_OR_DISCARD(rhs.to_numeric(global_object)); + auto lhs_numeric = TRY(lhs.to_numeric(global_object)); + auto rhs_numeric = TRY(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)) { - if (rhs_numeric.as_bigint().big_integer().is_negative()) { - vm.throw_exception(global_object, ErrorType::NegativeExponent); - return {}; - } - return js_bigint(vm, Crypto::NumberTheory::Power(lhs_numeric.as_bigint().big_integer(), rhs_numeric.as_bigint().big_integer())); + if (rhs_numeric.as_bigint().big_integer().is_negative()) + return vm.throw_completion(global_object, ErrorType::NegativeExponent); + return Value(js_bigint(vm, Crypto::NumberTheory::Power(lhs_numeric.as_bigint().big_integer(), rhs_numeric.as_bigint().big_integer()))); } - vm.throw_exception(global_object, ErrorType::BigIntBadOperatorOtherType, "exponentiation"); - return {}; + return vm.throw_completion(global_object, ErrorType::BigIntBadOperatorOtherType, "exponentiation"); } -Value in(GlobalObject& global_object, Value lhs, Value rhs) +ThrowCompletionOr in(GlobalObject& global_object, Value lhs, Value rhs) { - if (!rhs.is_object()) { - global_object.vm().throw_exception(global_object, ErrorType::InOperatorWithObject); - return {}; - } - auto lhs_property_key = TRY_OR_DISCARD(lhs.to_property_key(global_object)); - return Value(TRY_OR_DISCARD(rhs.as_object().has_property(lhs_property_key))); + if (!rhs.is_object()) + return global_object.vm().throw_completion(global_object, ErrorType::InOperatorWithObject); + auto lhs_property_key = TRY(lhs.to_property_key(global_object)); + return Value(TRY(rhs.as_object().has_property(lhs_property_key))); } // 13.10.2 InstanceofOperator ( V, target ), https://tc39.es/ecma262/#sec-instanceofoperator -Value instance_of(GlobalObject& global_object, Value lhs, Value rhs) +ThrowCompletionOr instance_of(GlobalObject& global_object, Value lhs, Value rhs) { auto& vm = global_object.vm(); - if (!rhs.is_object()) { - vm.throw_exception(global_object, ErrorType::NotAnObject, rhs.to_string_without_side_effects()); - return {}; - } - auto has_instance_method = TRY_OR_DISCARD(rhs.get_method(global_object, *vm.well_known_symbol_has_instance())); + if (!rhs.is_object()) + return vm.throw_completion(global_object, ErrorType::NotAnObject, rhs.to_string_without_side_effects()); + auto has_instance_method = TRY(rhs.get_method(global_object, *vm.well_known_symbol_has_instance())); if (has_instance_method) { - auto has_instance_result = TRY_OR_DISCARD(vm.call(*has_instance_method, rhs, lhs)); + auto has_instance_result = TRY(vm.call(*has_instance_method, rhs, lhs)); return Value(has_instance_result.to_boolean()); } - if (!rhs.is_function()) { - vm.throw_exception(global_object, ErrorType::NotAFunction, rhs.to_string_without_side_effects()); - return {}; - } - return ordinary_has_instance(global_object, lhs, rhs); + if (!rhs.is_function()) + return vm.throw_completion(global_object, ErrorType::NotAFunction, rhs.to_string_without_side_effects()); + return TRY(ordinary_has_instance(global_object, lhs, rhs)); } // 7.3.21 OrdinaryHasInstance ( C, O ), https://tc39.es/ecma262/#sec-ordinaryhasinstance -Value ordinary_has_instance(GlobalObject& global_object, Value lhs, Value rhs) +ThrowCompletionOr ordinary_has_instance(GlobalObject& global_object, Value lhs, Value rhs) { auto& vm = global_object.vm(); if (!rhs.is_function()) @@ -1183,13 +1160,11 @@ Value ordinary_has_instance(GlobalObject& global_object, Value lhs, Value rhs) return Value(false); Object* lhs_object = &lhs.as_object(); - auto rhs_prototype = TRY_OR_DISCARD(rhs_function.get(vm.names.prototype)); - if (!rhs_prototype.is_object()) { - vm.throw_exception(global_object, ErrorType::InstanceOfOperatorBadPrototype, rhs.to_string_without_side_effects()); - return {}; - } + auto rhs_prototype = TRY(rhs_function.get(vm.names.prototype)); + if (!rhs_prototype.is_object()) + return vm.throw_completion(global_object, ErrorType::InstanceOfOperatorBadPrototype, rhs.to_string_without_side_effects()); while (true) { - lhs_object = TRY_OR_DISCARD(lhs_object->internal_get_prototype_of()); + lhs_object = TRY(lhs_object->internal_get_prototype_of()); if (!lhs_object) return Value(false); if (same_value(rhs_prototype, lhs_object)) diff --git a/Userland/Libraries/LibJS/Runtime/Value.h b/Userland/Libraries/LibJS/Runtime/Value.h index d212086630..c66e028f58 100644 --- a/Userland/Libraries/LibJS/Runtime/Value.h +++ b/Userland/Libraries/LibJS/Runtime/Value.h @@ -399,28 +399,28 @@ inline void Cell::Visitor::visit(Value value) visit_impl(value.as_cell()); } -Value greater_than(GlobalObject&, Value lhs, Value rhs); -Value greater_than_equals(GlobalObject&, Value lhs, Value rhs); -Value less_than(GlobalObject&, Value lhs, Value rhs); -Value less_than_equals(GlobalObject&, Value lhs, Value rhs); -Value bitwise_and(GlobalObject&, Value lhs, Value rhs); -Value bitwise_or(GlobalObject&, Value lhs, Value rhs); -Value bitwise_xor(GlobalObject&, Value lhs, Value rhs); -Value bitwise_not(GlobalObject&, Value); -Value unary_plus(GlobalObject&, Value); -Value unary_minus(GlobalObject&, Value); -Value left_shift(GlobalObject&, Value lhs, Value rhs); -Value right_shift(GlobalObject&, Value lhs, Value rhs); -Value unsigned_right_shift(GlobalObject&, Value lhs, Value rhs); -Value add(GlobalObject&, Value lhs, Value rhs); -Value sub(GlobalObject&, Value lhs, Value rhs); -Value mul(GlobalObject&, Value lhs, Value rhs); -Value div(GlobalObject&, Value lhs, Value rhs); -Value mod(GlobalObject&, Value lhs, Value rhs); -Value exp(GlobalObject&, Value lhs, Value rhs); -Value in(GlobalObject&, Value lhs, Value rhs); -Value instance_of(GlobalObject&, Value lhs, Value rhs); -Value ordinary_has_instance(GlobalObject&, Value lhs, Value rhs); +ThrowCompletionOr greater_than(GlobalObject&, Value lhs, Value rhs); +ThrowCompletionOr greater_than_equals(GlobalObject&, Value lhs, Value rhs); +ThrowCompletionOr less_than(GlobalObject&, Value lhs, Value rhs); +ThrowCompletionOr less_than_equals(GlobalObject&, Value lhs, Value rhs); +ThrowCompletionOr bitwise_and(GlobalObject&, Value lhs, Value rhs); +ThrowCompletionOr bitwise_or(GlobalObject&, Value lhs, Value rhs); +ThrowCompletionOr bitwise_xor(GlobalObject&, Value lhs, Value rhs); +ThrowCompletionOr bitwise_not(GlobalObject&, Value); +ThrowCompletionOr unary_plus(GlobalObject&, Value); +ThrowCompletionOr unary_minus(GlobalObject&, Value); +ThrowCompletionOr left_shift(GlobalObject&, Value lhs, Value rhs); +ThrowCompletionOr right_shift(GlobalObject&, Value lhs, Value rhs); +ThrowCompletionOr unsigned_right_shift(GlobalObject&, Value lhs, Value rhs); +ThrowCompletionOr add(GlobalObject&, Value lhs, Value rhs); +ThrowCompletionOr sub(GlobalObject&, Value lhs, Value rhs); +ThrowCompletionOr mul(GlobalObject&, Value lhs, Value rhs); +ThrowCompletionOr div(GlobalObject&, Value lhs, Value rhs); +ThrowCompletionOr mod(GlobalObject&, Value lhs, Value rhs); +ThrowCompletionOr exp(GlobalObject&, Value lhs, Value rhs); +ThrowCompletionOr in(GlobalObject&, Value lhs, Value rhs); +ThrowCompletionOr instance_of(GlobalObject&, Value lhs, Value rhs); +ThrowCompletionOr ordinary_has_instance(GlobalObject&, Value lhs, Value rhs); ThrowCompletionOr is_loosely_equal(GlobalObject&, Value lhs, Value rhs); bool is_strictly_equal(Value lhs, Value rhs); -- cgit v1.2.3