diff --git a/Meta/Lagom/Fuzzers/FuzzilliJs.cpp b/Meta/Lagom/Fuzzers/FuzzilliJs.cpp index f66d95c028..95bf3cf4e4 100644 --- a/Meta/Lagom/Fuzzers/FuzzilliJs.cpp +++ b/Meta/Lagom/Fuzzers/FuzzilliJs.cpp @@ -143,9 +143,7 @@ JS_DEFINE_NATIVE_FUNCTION(TestRunnerGlobalObject::fuzzilli) auto operation = TRY_OR_DISCARD(vm.argument(0).to_string(global_object)); if (operation == "FUZZILLI_CRASH") { - auto type = vm.argument(1).to_i32(global_object); - if (vm.exception()) - return {}; + auto type = TRY_OR_DISCARD(vm.argument(1).to_i32(global_object)); switch (type) { case 0: *((int*)0x41414141) = 0x1337; diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator.cpp index 2d0a5d595c..cafd0ec252 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator.cpp @@ -1129,9 +1129,7 @@ static void generate_to_cpp(SourceGenerator& generator, ParameterType& parameter )~~~"); } else if (parameter.type->name == "long") { scoped_generator.append(R"~~~( - auto @cpp_name@ = @js_name@@js_suffix@.to_i32(global_object); - if (vm.exception()) - @return_statement@ + auto @cpp_name@ = TRY_OR_DISCARD(@js_name@@js_suffix@.to_i32(global_object)); )~~~"); } else if (parameter.type->name == "EventHandler") { // x.onfoo = function() { ... } diff --git a/Userland/Applications/Spreadsheet/CellType/Date.cpp b/Userland/Applications/Spreadsheet/CellType/Date.cpp index 5881c2030f..9c257dab65 100644 --- a/Userland/Applications/Spreadsheet/CellType/Date.cpp +++ b/Userland/Applications/Spreadsheet/CellType/Date.cpp @@ -30,7 +30,7 @@ String DateCell::display(Cell& cell, const CellTypeMetadata& metadata) const } } }; auto timestamp = js_value(cell, metadata); - auto string = Core::DateTime::from_timestamp(timestamp.to_i32(cell.sheet().global_object())).to_string(metadata.format.is_empty() ? "%Y-%m-%d %H:%M:%S" : metadata.format.characters()); + auto string = Core::DateTime::from_timestamp(TRY_OR_DISCARD(timestamp.to_i32(cell.sheet().global_object()))).to_string(metadata.format.is_empty() ? "%Y-%m-%d %H:%M:%S" : metadata.format.characters()); if (metadata.length >= 0) return string.substring(0, metadata.length); diff --git a/Userland/Libraries/LibJS/Runtime/ArrayBuffer.h b/Userland/Libraries/LibJS/Runtime/ArrayBuffer.h index 94574ba837..7bceadd133 100644 --- a/Userland/Libraries/LibJS/Runtime/ArrayBuffer.h +++ b/Userland/Libraries/LibJS/Runtime/ArrayBuffer.h @@ -169,7 +169,7 @@ static ByteBuffer numeric_to_raw_bytes(GlobalObject& global_object, Value value, UnderlyingBufferDataType int_value; if constexpr (IsSigned) { if constexpr (sizeof(UnderlyingBufferDataType) == 4) - int_value = value.to_i32(global_object); + int_value = MUST(value.to_i32(global_object)); else if constexpr (sizeof(UnderlyingBufferDataType) == 2) int_value = value.to_i16(global_object); else diff --git a/Userland/Libraries/LibJS/Runtime/DateConstructor.cpp b/Userland/Libraries/LibJS/Runtime/DateConstructor.cpp index 95b998b5c2..349eee7738 100644 --- a/Userland/Libraries/LibJS/Runtime/DateConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/DateConstructor.cpp @@ -310,21 +310,23 @@ JS_DEFINE_NATIVE_FUNCTION(DateConstructor::parse) // 21.4.3.4 Date.UTC ( year [ , month [ , date [ , hours [ , minutes [ , seconds [ , ms ] ] ] ] ] ] ), https://tc39.es/ecma262/#sec-date.utc JS_DEFINE_NATIVE_FUNCTION(DateConstructor::utc) { - auto arg_or = [&vm, &global_object](size_t i, i32 fallback) { return vm.argument_count() > i ? vm.argument(i).to_i32(global_object) : fallback; }; - int year = vm.argument(0).to_i32(global_object); + auto arg_or = [&vm, &global_object](size_t i, i32 fallback) -> ThrowCompletionOr { + return vm.argument_count() > i ? vm.argument(i).to_i32(global_object) : fallback; + }; + int year = TRY_OR_DISCARD(vm.argument(0).to_i32(global_object)); if (year >= 0 && year <= 99) year += 1900; struct tm tm = {}; tm.tm_year = year - 1900; - tm.tm_mon = arg_or(1, 0); // 0-based in both tm and JavaScript - tm.tm_mday = arg_or(2, 1); - tm.tm_hour = arg_or(3, 0); - tm.tm_min = arg_or(4, 0); - tm.tm_sec = arg_or(5, 0); + tm.tm_mon = TRY_OR_DISCARD(arg_or(1, 0)); // 0-based in both tm and JavaScript + tm.tm_mday = TRY_OR_DISCARD(arg_or(2, 1)); + tm.tm_hour = TRY_OR_DISCARD(arg_or(3, 0)); + tm.tm_min = TRY_OR_DISCARD(arg_or(4, 0)); + tm.tm_sec = TRY_OR_DISCARD(arg_or(5, 0)); // timegm() doesn't read tm.tm_wday and tm.tm_yday, no need to fill them in. - int milliseconds = arg_or(6, 0); + int milliseconds = TRY_OR_DISCARD(arg_or(6, 0)); return Value(1000.0 * timegm(&tm) + milliseconds); } diff --git a/Userland/Libraries/LibJS/Runtime/GlobalObject.cpp b/Userland/Libraries/LibJS/Runtime/GlobalObject.cpp index e7c530f121..dad52eb6ce 100644 --- a/Userland/Libraries/LibJS/Runtime/GlobalObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/GlobalObject.cpp @@ -378,9 +378,7 @@ JS_DEFINE_NATIVE_FUNCTION(GlobalObject::parse_int) if (!s.is_empty() && (s[0] == '+' || s[0] == '-')) s = s.substring(1, s.length() - 1); - auto radix = vm.argument(1).to_i32(global_object); - if (vm.exception()) - return {}; + auto radix = TRY_OR_DISCARD(vm.argument(1).to_i32(global_object)); bool strip_prefix = true; if (radix != 0) { diff --git a/Userland/Libraries/LibJS/Runtime/StringConstructor.cpp b/Userland/Libraries/LibJS/Runtime/StringConstructor.cpp index 8277ea8122..da32893924 100644 --- a/Userland/Libraries/LibJS/Runtime/StringConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/StringConstructor.cpp @@ -127,7 +127,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringConstructor::from_code_point) vm.throw_exception(global_object, ErrorType::InvalidCodePoint, next_code_point.to_string_without_side_effects()); return {}; } - auto code_point = next_code_point.to_i32(global_object); + auto code_point = TRY_OR_DISCARD(next_code_point.to_i32(global_object)); if (code_point < 0 || code_point > 0x10FFFF) { vm.throw_exception(global_object, ErrorType::InvalidCodePoint, next_code_point.to_string_without_side_effects()); return {}; diff --git a/Userland/Libraries/LibJS/Runtime/Value.cpp b/Userland/Libraries/LibJS/Runtime/Value.cpp index 0da1cbb2af..453e8f8fb0 100644 --- a/Userland/Libraries/LibJS/Runtime/Value.cpp +++ b/Userland/Libraries/LibJS/Runtime/Value.cpp @@ -567,10 +567,10 @@ ThrowCompletionOr Value::to_property_key(GlobalObject& global_ob return StringOrSymbol { TRY(key.to_string(global_object)) }; } -i32 Value::to_i32_slow_case(GlobalObject& global_object) const +ThrowCompletionOr Value::to_i32_slow_case(GlobalObject& global_object) const { VERIFY(type() != Type::Int32); - double value = TRY_OR_DISCARD(to_number(global_object)).as_double(); + double value = TRY(to_number(global_object)).as_double(); if (!isfinite(value) || value == 0) return 0; auto abs = fabs(value); @@ -584,6 +584,13 @@ i32 Value::to_i32_slow_case(GlobalObject& global_object) const return static_cast(int32bit); } +ThrowCompletionOr Value::to_i32(GlobalObject& global_object) const +{ + if (m_type == Type::Int32) + return m_value.as_i32; + return to_i32_slow_case(global_object); +} + // 7.1.7 ToUint32 ( argument ), https://tc39.es/ecma262/#sec-touint32 u32 Value::to_u32(GlobalObject& global_object) const { @@ -819,7 +826,7 @@ Value bitwise_and(GlobalObject& global_object, Value lhs, Value rhs) if (both_number(lhs_numeric, rhs_numeric)) { if (!lhs_numeric.is_finite_number() || !rhs_numeric.is_finite_number()) return Value(0); - return Value(lhs_numeric.to_i32(global_object) & rhs_numeric.to_i32(global_object)); + return Value(TRY_OR_DISCARD(lhs_numeric.to_i32(global_object)) & TRY_OR_DISCARD(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())); @@ -840,7 +847,7 @@ Value bitwise_or(GlobalObject& global_object, Value lhs, Value rhs) return rhs_numeric; if (!rhs_numeric.is_finite_number()) return lhs_numeric; - return Value(lhs_numeric.to_i32(global_object) | rhs_numeric.to_i32(global_object)); + return Value(TRY_OR_DISCARD(lhs_numeric.to_i32(global_object)) | TRY_OR_DISCARD(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())); @@ -861,7 +868,7 @@ Value bitwise_xor(GlobalObject& global_object, Value lhs, Value rhs) return rhs_numeric; if (!rhs_numeric.is_finite_number()) return lhs_numeric; - return Value(lhs_numeric.to_i32(global_object) ^ rhs_numeric.to_i32(global_object)); + return Value(TRY_OR_DISCARD(lhs_numeric.to_i32(global_object)) ^ TRY_OR_DISCARD(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())); @@ -875,7 +882,7 @@ Value bitwise_not(GlobalObject& global_object, Value lhs) auto& vm = global_object.vm(); auto lhs_numeric = TRY_OR_DISCARD(lhs.to_numeric(global_object)); if (lhs_numeric.is_number()) - return Value(~lhs_numeric.to_i32(global_object)); + return Value(~TRY_OR_DISCARD(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(); @@ -917,7 +924,7 @@ Value left_shift(GlobalObject& global_object, Value lhs, Value rhs) if (!rhs_numeric.is_finite_number()) return lhs_numeric; // Ok, so this performs toNumber() again but that "can't" throw - auto lhs_i32 = lhs_numeric.to_i32(global_object); + auto lhs_i32 = MUST(lhs_numeric.to_i32(global_object)); auto rhs_u32 = rhs_numeric.to_u32(global_object) % 32; return Value(lhs_i32 << rhs_u32); } @@ -943,7 +950,7 @@ Value right_shift(GlobalObject& global_object, Value lhs, Value rhs) return Value(0); if (!rhs_numeric.is_finite_number()) return lhs_numeric; - auto lhs_i32 = lhs_numeric.to_i32(global_object); + auto lhs_i32 = MUST(lhs_numeric.to_i32(global_object)); auto rhs_u32 = rhs_numeric.to_u32(global_object) % 32; return Value(lhs_i32 >> rhs_u32); } @@ -981,8 +988,8 @@ Value add(GlobalObject& global_object, Value lhs, Value rhs) if (both_number(lhs, rhs)) { if (lhs.type() == Value::Type::Int32 && rhs.type() == Value::Type::Int32) { Checked result; - result = lhs.to_i32(global_object); - result += rhs.to_i32(global_object); + result = MUST(lhs.to_i32(global_object)); + result += MUST(rhs.to_i32(global_object)); if (!result.has_overflow()) return Value(result.value()); } @@ -1372,9 +1379,9 @@ bool is_loosely_equal(GlobalObject& global_object, Value lhs, Value rhs) if ((lhs.is_number() && !lhs.is_integral_number()) || (rhs.is_number() && !rhs.is_integral_number())) return false; if (lhs.is_number()) - return Crypto::SignedBigInteger { lhs.to_i32(global_object) } == rhs.as_bigint().big_integer(); + return Crypto::SignedBigInteger { MUST(lhs.to_i32(global_object)) } == rhs.as_bigint().big_integer(); else - return Crypto::SignedBigInteger { rhs.to_i32(global_object) } == lhs.as_bigint().big_integer(); + return Crypto::SignedBigInteger { MUST(rhs.to_i32(global_object)) } == lhs.as_bigint().big_integer(); } // 14. Return false. @@ -1472,12 +1479,12 @@ TriState is_less_than(GlobalObject& global_object, bool left_first, Value lhs, V bool x_lower_than_y; if (x_numeric.is_number()) { x_lower_than_y = x_numeric.is_integral_number() - ? Crypto::SignedBigInteger { x_numeric.to_i32(global_object) } < y_numeric.as_bigint().big_integer() - : (Crypto::SignedBigInteger { x_numeric.to_i32(global_object) } < y_numeric.as_bigint().big_integer() || Crypto::SignedBigInteger { x_numeric.to_i32(global_object) + 1 } < y_numeric.as_bigint().big_integer()); + ? Crypto::SignedBigInteger { MUST(x_numeric.to_i32(global_object)) } < y_numeric.as_bigint().big_integer() + : (Crypto::SignedBigInteger { MUST(x_numeric.to_i32(global_object)) } < y_numeric.as_bigint().big_integer() || Crypto::SignedBigInteger { MUST(x_numeric.to_i32(global_object)) + 1 } < y_numeric.as_bigint().big_integer()); } else { x_lower_than_y = y_numeric.is_integral_number() - ? x_numeric.as_bigint().big_integer() < Crypto::SignedBigInteger { y_numeric.to_i32(global_object) } - : (x_numeric.as_bigint().big_integer() < Crypto::SignedBigInteger { y_numeric.to_i32(global_object) } || x_numeric.as_bigint().big_integer() < Crypto::SignedBigInteger { y_numeric.to_i32(global_object) + 1 }); + ? x_numeric.as_bigint().big_integer() < Crypto::SignedBigInteger { MUST(y_numeric.to_i32(global_object)) } + : (x_numeric.as_bigint().big_integer() < Crypto::SignedBigInteger { MUST(y_numeric.to_i32(global_object)) } || x_numeric.as_bigint().big_integer() < Crypto::SignedBigInteger { MUST(y_numeric.to_i32(global_object)) + 1 }); } if (x_lower_than_y) return TriState::True; diff --git a/Userland/Libraries/LibJS/Runtime/Value.h b/Userland/Libraries/LibJS/Runtime/Value.h index 2aaf733acd..ae3e6a7188 100644 --- a/Userland/Libraries/LibJS/Runtime/Value.h +++ b/Userland/Libraries/LibJS/Runtime/Value.h @@ -315,12 +315,7 @@ public: ThrowCompletionOr to_bigint_uint64(GlobalObject&) const; ThrowCompletionOr to_double(GlobalObject&) const; ThrowCompletionOr to_property_key(GlobalObject&) const; - i32 to_i32(GlobalObject& global_object) const - { - if (m_type == Type::Int32) - return m_value.as_i32; - return to_i32_slow_case(global_object); - } + ThrowCompletionOr to_i32(GlobalObject& global_object) const; u32 to_u32(GlobalObject&) const; i16 to_i16(GlobalObject&) const; u16 to_u16(GlobalObject&) const; @@ -356,7 +351,7 @@ private: [[nodiscard]] ThrowCompletionOr invoke_internal(GlobalObject& global_object, PropertyName const&, Optional arguments); - i32 to_i32_slow_case(GlobalObject&) const; + ThrowCompletionOr to_i32_slow_case(GlobalObject&) const; union { bool as_bool; diff --git a/Userland/Libraries/LibWeb/Bindings/WindowObject.cpp b/Userland/Libraries/LibWeb/Bindings/WindowObject.cpp index 9eed2cebd5..fe0e377f32 100644 --- a/Userland/Libraries/LibWeb/Bindings/WindowObject.cpp +++ b/Userland/Libraries/LibWeb/Bindings/WindowObject.cpp @@ -251,9 +251,7 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::set_interval) } i32 interval = 0; if (vm.argument_count() >= 2) { - interval = vm.argument(1).to_i32(global_object); - if (vm.exception()) - return {}; + interval = TRY_OR_DISCARD(vm.argument(1).to_i32(global_object)); if (interval < 0) interval = 0; } @@ -290,9 +288,7 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::set_timeout) } i32 interval = 0; if (vm.argument_count() >= 2) { - interval = vm.argument(1).to_i32(global_object); - if (vm.exception()) - return {}; + interval = TRY_OR_DISCARD(vm.argument(1).to_i32(global_object)); if (interval < 0) interval = 0; } @@ -310,9 +306,7 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::clear_timeout) vm.throw_exception(global_object, JS::ErrorType::BadArgCountAtLeastOne, "clearTimeout"); return {}; } - i32 timer_id = vm.argument(0).to_i32(global_object); - if (vm.exception()) - return {}; + i32 timer_id = TRY_OR_DISCARD(vm.argument(0).to_i32(global_object)); impl->clear_timeout(timer_id); return JS::js_undefined(); } @@ -326,9 +320,7 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::clear_interval) vm.throw_exception(global_object, JS::ErrorType::BadArgCountAtLeastOne, "clearInterval"); return {}; } - i32 timer_id = vm.argument(0).to_i32(global_object); - if (vm.exception()) - return {}; + i32 timer_id = TRY_OR_DISCARD(vm.argument(0).to_i32(global_object)); impl->clear_interval(timer_id); return JS::js_undefined(); } @@ -359,9 +351,7 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::cancel_animation_frame) vm.throw_exception(global_object, JS::ErrorType::BadArgCountOne, "cancelAnimationFrame"); return {}; } - auto id = vm.argument(0).to_i32(global_object); - if (vm.exception()) - return {}; + auto id = TRY_OR_DISCARD(vm.argument(0).to_i32(global_object)); impl->cancel_animation_frame(id); return JS::js_undefined(); } diff --git a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyObject.cpp b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyObject.cpp index 2b49e3b74d..51e21fbdde 100644 --- a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyObject.cpp +++ b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyObject.cpp @@ -397,9 +397,7 @@ Optional to_webassembly_value(JS::Value value, const Wasm::ValueTyp return Wasm::Value { integer }; } case Wasm::ValueType::I32: { - auto _i32 = value.to_i32(global_object); - if (vm.exception()) - return {}; + auto _i32 = TRY_OR_DISCARD(value.to_i32(global_object)); return Wasm::Value { static_cast(_i32) }; } case Wasm::ValueType::F64: {