diff options
61 files changed, 326 insertions, 686 deletions
diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator.cpp index 0177f3db8a..22bfe2e36e 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator.cpp @@ -1112,9 +1112,10 @@ static void generate_to_cpp(SourceGenerator& generator, ParameterType& parameter if (@js_name@@js_suffix@.is_nullish()) { @member_name@ = JS::js_undefined(); } else { - @member_name@ = @js_name@@js_suffix@.as_object().get("@member_key@"); - if (vm.exception()) + auto @member_name@_or_error = @js_name@@js_suffix@.as_object().get("@member_key@"); + if (@member_name@_or_error.is_error()) @return_statement@ + @member_name@ = @member_name@_or_error.release_value(); } )~~~"); if (member.required) { @@ -2956,7 +2957,7 @@ void @prototype_class@::initialize(JS::GlobalObject& global_object) define_native_function(vm.names.keys, keys, 0, default_attributes); define_native_function(vm.names.values, values, 0, default_attributes); - define_direct_property(*vm.well_known_symbol_iterator(), Object::get(vm.names.entries), JS::Attribute::Configurable | JS::Attribute::Writable); + define_direct_property(*vm.well_known_symbol_iterator(), get_without_side_effects(vm.names.entries), JS::Attribute::Configurable | JS::Attribute::Writable); )~~~"); } diff --git a/Userland/Applications/Spreadsheet/Spreadsheet.cpp b/Userland/Applications/Spreadsheet/Spreadsheet.cpp index 5c4278bd96..85b58501cf 100644 --- a/Userland/Applications/Spreadsheet/Spreadsheet.cpp +++ b/Userland/Applications/Spreadsheet/Spreadsheet.cpp @@ -378,8 +378,8 @@ RefPtr<Sheet> Sheet::from_json(const JsonObject& object, Workbook& workbook) sheet->add_column(); } - auto json = sheet->interpreter().global_object().get("JSON"); - auto& parse_function = json.as_object().get("parse").as_function(); + auto json = sheet->interpreter().global_object().get_without_side_effects("JSON"); + auto& parse_function = json.as_object().get_without_side_effects("parse").as_function(); auto read_format = [](auto& format, const auto& obj) { if (auto value = obj.get("foreground_color"); value.is_string()) @@ -532,8 +532,8 @@ JsonObject Sheet::to_json() const data.set("kind", it.value->kind() == Cell::Kind::Formula ? "Formula" : "LiteralString"); if (it.value->kind() == Cell::Formula) { data.set("source", it.value->data()); - auto json = interpreter().global_object().get("JSON"); - auto stringified_or_error = interpreter().vm().call(json.as_object().get("stringify").as_function(), json, it.value->evaluated_data()); + auto json = interpreter().global_object().get_without_side_effects("JSON"); + auto stringified_or_error = interpreter().vm().call(json.as_object().get_without_side_effects("stringify").as_function(), json, it.value->evaluated_data()); VERIFY(!stringified_or_error.is_error()); data.set("value", stringified_or_error.release_value().to_string_without_side_effects()); } else { @@ -651,7 +651,7 @@ JsonObject Sheet::gather_documentation() const const JS::PropertyName doc_name { "__documentation" }; auto add_docs_from = [&](auto& it, auto& global_object) { - auto value = global_object.get(it.key); + auto value = global_object.get(it.key).release_value(); if (!value.is_function() && !value.is_object()) return; @@ -660,7 +660,7 @@ JsonObject Sheet::gather_documentation() const return; dbgln("Found '{}'", it.key.to_display_string()); - auto doc = value_object.get(doc_name); + auto doc = value_object.get(doc_name).release_value(); if (!doc.is_string()) return; diff --git a/Userland/Applications/Spreadsheet/SpreadsheetModel.cpp b/Userland/Applications/Spreadsheet/SpreadsheetModel.cpp index 8bb29da7b7..49e7e5bf04 100644 --- a/Userland/Applications/Spreadsheet/SpreadsheetModel.cpp +++ b/Userland/Applications/Spreadsheet/SpreadsheetModel.cpp @@ -35,7 +35,7 @@ GUI::Variant SheetModel::data(const GUI::ModelIndex& index, GUI::ModelRole role) if (value.is_object()) { auto& object = value.as_object(); if (is<JS::Error>(object)) { - auto error = object.get("message").to_string_without_side_effects(); + auto error = object.get_without_side_effects("message").to_string_without_side_effects(); builder.append(error); return builder.to_string(); } diff --git a/Userland/Libraries/LibJS/AST.cpp b/Userland/Libraries/LibJS/AST.cpp index 91abbb0ae0..15b0e9523f 100644 --- a/Userland/Libraries/LibJS/AST.cpp +++ b/Userland/Libraries/LibJS/AST.cpp @@ -1216,9 +1216,7 @@ ThrowCompletionOr<Value> ClassExpression::class_definition_evaluation(Interprete Object* super_constructor_prototype = nullptr; if (!super_constructor.is_null()) { - auto super_constructor_prototype_value = super_constructor.as_object().get(vm.names.prototype); - if (auto* exception = interpreter.exception()) - return throw_completion(exception->value()); + auto super_constructor_prototype_value = TRY(super_constructor.as_object().get(vm.names.prototype)); if (!super_constructor_prototype_value.is_object() && !super_constructor_prototype_value.is_null()) return interpreter.vm().throw_completion<TypeError>(global_object, ErrorType::ClassExtendsValueInvalidPrototype, super_constructor_prototype_value.to_string_without_side_effects()); @@ -1237,9 +1235,7 @@ ThrowCompletionOr<Value> ClassExpression::class_definition_evaluation(Interprete TRY(class_constructor->internal_set_prototype_of(super_constructor.is_null() ? global_object.function_prototype() : &super_constructor.as_object())); } - auto class_prototype = class_constructor->get(vm.names.prototype); - if (auto* exception = interpreter.exception()) - return throw_completion(exception->value()); + auto class_prototype = TRY(class_constructor->get(vm.names.prototype)); if (!class_prototype.is_object()) return interpreter.vm().throw_completion<TypeError>(global_object, ErrorType::NotAnObject, "Class prototype"); @@ -2294,9 +2290,7 @@ Value ObjectExpression::execute(Interpreter& interpreter, GlobalObject& global_o if (key.is_object() && is<Array>(key.as_object())) { auto& array_to_spread = static_cast<Array&>(key.as_object()); for (auto& entry : array_to_spread.indexed_properties()) { - auto value = array_to_spread.get(entry.index()); - if (interpreter.exception()) - return {}; + auto value = TRY_OR_DISCARD(array_to_spread.get(entry.index())); object->indexed_properties().put(entry.index(), value); if (interpreter.exception()) return {}; @@ -2306,7 +2300,7 @@ Value ObjectExpression::execute(Interpreter& interpreter, GlobalObject& global_o for (auto& it : obj_to_spread.shape().property_table_ordered()) { if (it.value.attributes.is_enumerable()) { - object->define_direct_property(it.key, obj_to_spread.get(it.key), JS::default_attributes); + object->define_direct_property(it.key, TRY_OR_DISCARD(obj_to_spread.get(it.key)), JS::default_attributes); if (interpreter.exception()) return {}; } diff --git a/Userland/Libraries/LibJS/Bytecode/Op.cpp b/Userland/Libraries/LibJS/Bytecode/Op.cpp index 939395cad9..88c59e7079 100644 --- a/Userland/Libraries/LibJS/Bytecode/Op.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Op.cpp @@ -200,9 +200,10 @@ void CopyObjectExcludingProperties::execute_impl(Bytecode::Interpreter& interpre for (auto& key : own_keys) { if (!excluded_names.contains(key)) { auto property_name = PropertyName(key.to_property_key(interpreter.global_object())); - auto property_value = from_object->get(property_name); - if (interpreter.vm().exception()) + auto property_value_or_error = from_object->get(property_name); + if (property_value_or_error.is_error()) return; + auto property_value = property_value_or_error.release_value(); to_object->define_direct_property(property_name, property_value, JS::default_attributes); } } @@ -237,8 +238,12 @@ void SetVariable::execute_impl(Bytecode::Interpreter& interpreter) const void GetById::execute_impl(Bytecode::Interpreter& interpreter) const { - if (auto* object = interpreter.accumulator().to_object(interpreter.global_object())) - interpreter.accumulator() = object->get(interpreter.current_executable().get_string(m_property)); + if (auto* object = interpreter.accumulator().to_object(interpreter.global_object())) { + auto value_or_error = object->get(interpreter.current_executable().get_string(m_property)); + if (value_or_error.is_error()) + return; + interpreter.accumulator() = value_or_error.release_value(); + } } void PutById::execute_impl(Bytecode::Interpreter& interpreter) const @@ -429,7 +434,10 @@ void GetByValue::execute_impl(Bytecode::Interpreter& interpreter) const auto property_key = interpreter.accumulator().to_property_key(interpreter.global_object()); if (interpreter.vm().exception()) return; - interpreter.accumulator() = object->get(property_key); + auto value_or_error = object->get(property_key); + if (value_or_error.is_error()) + return; + interpreter.accumulator() = value_or_error.release_value(); } } diff --git a/Userland/Libraries/LibJS/MarkupGenerator.cpp b/Userland/Libraries/LibJS/MarkupGenerator.cpp index e4859eb327..ff82823b00 100644 --- a/Userland/Libraries/LibJS/MarkupGenerator.cpp +++ b/Userland/Libraries/LibJS/MarkupGenerator.cpp @@ -99,7 +99,7 @@ void MarkupGenerator::array_to_html(const Array& array, StringBuilder& html_outp html_output.append(wrap_string_in_style(", ", StyleType::Punctuation)); first = false; // FIXME: Exception check - value_to_html(array.get(it.index()), html_output, seen_objects); + value_to_html(array.get(it.index()).release_value(), html_output, seen_objects); } html_output.append(wrap_string_in_style(" ]", StyleType::Punctuation)); } @@ -115,7 +115,7 @@ void MarkupGenerator::object_to_html(const Object& object, StringBuilder& html_o html_output.append(wrap_string_in_style(String::number(entry.index()), StyleType::Number)); html_output.append(wrap_string_in_style(": ", StyleType::Punctuation)); // FIXME: Exception check - value_to_html(object.get(entry.index()), html_output, seen_objects); + value_to_html(object.get(entry.index()).release_value(), html_output, seen_objects); } if (!object.indexed_properties().is_empty() && object.shape().property_count()) diff --git a/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp b/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp index 7660e286ff..4086024a2d 100644 --- a/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp +++ b/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp @@ -46,9 +46,7 @@ ThrowCompletionOr<Value> require_object_coercible(GlobalObject& global_object, V ThrowCompletionOr<size_t> length_of_array_like(GlobalObject& global_object, Object const& object) { auto& vm = global_object.vm(); - auto result = object.get(vm.names.length); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto result = TRY(object.get(vm.names.length)); auto length = result.to_length(global_object); if (auto* exception = vm.exception()) return throw_completion(exception->value()); @@ -82,9 +80,7 @@ ThrowCompletionOr<MarkedValueList> create_list_from_array_like(GlobalObject& glo auto index_name = String::number(i); // b. Let next be ? Get(obj, indexName). - auto next = array_like.get(index_name); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto next = TRY(array_like.get(index_name)); // c. If Type(next) is not an element of elementTypes, throw a TypeError exception. if (check_value) @@ -104,9 +100,7 @@ ThrowCompletionOr<FunctionObject*> species_constructor(GlobalObject& global_obje auto& vm = global_object.vm(); // 1. Let C be ? Get(O, "constructor"). - auto constructor = object.get(vm.names.constructor); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto constructor = TRY(object.get(vm.names.constructor)); // 2. If C is undefined, return defaultConstructor. if (constructor.is_undefined()) @@ -117,9 +111,7 @@ ThrowCompletionOr<FunctionObject*> species_constructor(GlobalObject& global_obje return vm.throw_completion<TypeError>(global_object, ErrorType::NotAConstructor, constructor.to_string_without_side_effects()); // 4. Let S be ? Get(C, @@species). - auto species = constructor.as_object().get(*vm.well_known_symbol_species()); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto species = TRY(constructor.as_object().get(*vm.well_known_symbol_species())); // 5. If S is either undefined or null, return defaultConstructor. if (species.is_nullish()) @@ -340,9 +332,7 @@ ThrowCompletionOr<Object*> get_prototype_from_constructor(GlobalObject& global_o // 1. Assert: intrinsicDefaultProto is this specification's name of an intrinsic object. The corresponding object must be an intrinsic that is intended to be used as the [[Prototype]] value of an object. // 2. Let proto be ? Get(constructor, "prototype"). - auto prototype = constructor.get(vm.names.prototype); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto prototype = TRY(constructor.get(vm.names.prototype)); // 3. If Type(proto) is not Object, then if (!prototype.is_object()) { @@ -917,9 +907,7 @@ ThrowCompletionOr<String> get_substitution(GlobalObject& global_object, Utf16Vie auto group_name_view = replace_view.substring_view(start_position, *end_position - start_position); auto group_name = group_name_view.to_utf8(Utf16View::AllowInvalidCodeUnits::Yes); - auto capture = named_captures.as_object().get(group_name); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto capture = TRY(named_captures.as_object().get(group_name)); if (!capture.is_undefined()) { auto capture_string = capture.to_string(global_object); diff --git a/Userland/Libraries/LibJS/Runtime/ArgumentsObject.cpp b/Userland/Libraries/LibJS/Runtime/ArgumentsObject.cpp index f5e500c9f2..1bb4605c4c 100644 --- a/Userland/Libraries/LibJS/Runtime/ArgumentsObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/ArgumentsObject.cpp @@ -117,7 +117,7 @@ ThrowCompletionOr<Optional<PropertyDescriptor>> ArgumentsObject::internal_get_ow // 5. If isMapped is true, then if (is_mapped) { // a. Set desc.[[Value]] to Get(map, P). - desc->value = m_parameter_map->get(property_name); + desc->value = TRY(m_parameter_map->get(property_name)); } // 6. Return desc. return desc; @@ -142,7 +142,7 @@ ThrowCompletionOr<bool> ArgumentsObject::internal_define_own_property(PropertyNa // i. Set newArgDesc to a copy of Desc. new_arg_desc = descriptor; // ii. Set newArgDesc.[[Value]] to Get(map, P). - new_arg_desc.value = map.get(property_name); + new_arg_desc.value = TRY(map.get(property_name)); } } diff --git a/Userland/Libraries/LibJS/Runtime/ArrayConstructor.cpp b/Userland/Libraries/LibJS/Runtime/ArrayConstructor.cpp index e4eab82991..6d777d3e63 100644 --- a/Userland/Libraries/LibJS/Runtime/ArrayConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/ArrayConstructor.cpp @@ -189,9 +189,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::from) auto& array_object = array.as_object(); for (size_t k = 0; k < length; ++k) { - auto k_value = array_like->get(k); - if (vm.exception()) - return {}; + auto k_value = TRY_OR_DISCARD(array_like->get(k)); Value mapped_value; if (map_fn) mapped_value = TRY_OR_DISCARD(vm.call(*map_fn, this_arg, k_value, Value(k))); diff --git a/Userland/Libraries/LibJS/Runtime/ArrayIteratorPrototype.cpp b/Userland/Libraries/LibJS/Runtime/ArrayIteratorPrototype.cpp index 164f4f1d07..9988f438be 100644 --- a/Userland/Libraries/LibJS/Runtime/ArrayIteratorPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/ArrayIteratorPrototype.cpp @@ -75,9 +75,8 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayIteratorPrototype::next) if (iteration_kind == Object::PropertyKind::Key) return create_iterator_result_object(global_object, Value(static_cast<i32>(index)), false); - auto value = array.get(index); - if (vm.exception()) - return {}; + auto value = TRY_OR_DISCARD(array.get(index)); + if (iteration_kind == Object::PropertyKind::Value) return create_iterator_result_object(global_object, value, false); diff --git a/Userland/Libraries/LibJS/Runtime/ArrayPrototype.cpp b/Userland/Libraries/LibJS/Runtime/ArrayPrototype.cpp index c419432ed6..cfebf37f2f 100644 --- a/Userland/Libraries/LibJS/Runtime/ArrayPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/ArrayPrototype.cpp @@ -77,7 +77,7 @@ void ArrayPrototype::initialize(GlobalObject& global_object) // Object.is(Array.prototype[Symbol.iterator], Array.prototype.values) // evaluates to true // 23.1.3.33 Array.prototype [ @@iterator ] ( ), https://tc39.es/ecma262/#sec-array.prototype-@@iterator - define_direct_property(*vm.well_known_symbol_iterator(), get(vm.names.values), attr); + define_direct_property(*vm.well_known_symbol_iterator(), get_without_side_effects(vm.names.values), attr); // 23.1.3.34 Array.prototype [ @@unscopables ], https://tc39.es/ecma262/#sec-array.prototype-@@unscopables // With proposal, https://tc39.es/proposal-array-find-from-last/index.html#sec-array.prototype-@@unscopables @@ -116,9 +116,7 @@ static Object* array_species_create(GlobalObject& global_object, Object& origina return array; } - auto constructor = original_array.get(vm.names.constructor); - if (vm.exception()) - return {}; + auto constructor = TRY_OR_DISCARD(original_array.get(vm.names.constructor)); if (constructor.is_constructor()) { auto& constructor_function = constructor.as_function(); auto* this_realm = vm.current_realm(); @@ -130,9 +128,7 @@ static Object* array_species_create(GlobalObject& global_object, Object& origina } if (constructor.is_object()) { - constructor = constructor.as_object().get(*vm.well_known_symbol_species()); - if (vm.exception()) - return {}; + constructor = TRY_OR_DISCARD(constructor.as_object().get(*vm.well_known_symbol_species())); if (constructor.is_null()) constructor = js_undefined(); } @@ -201,9 +197,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::filter) // c. If kPresent is true, then if (k_present) { // i. Let kValue be ? Get(O, Pk). - auto k_value = object->get(k); - if (vm.exception()) - return {}; + auto k_value = TRY_OR_DISCARD(object->get(k)); // ii. Let selected be ! ToBoolean(? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »)). auto selected = TRY_OR_DISCARD(vm.call(callback_function.as_function(), this_arg, k_value, Value(k), object)).to_boolean(); @@ -259,9 +253,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::for_each) // c. If kPresent is true, then if (k_present) { // i. Let kValue be ? Get(O, Pk). - auto k_value = object->get(property_name); - if (vm.exception()) - return {}; + auto k_value = TRY_OR_DISCARD(object->get(property_name)); // ii. Perform ? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »). (void)vm.call(callback_function.as_function(), this_arg, k_value, Value(k), object); @@ -315,9 +307,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::map) // c. If kPresent is true, then if (k_present) { // i. Let kValue be ? Get(O, Pk). - auto k_value = object->get(property_name); - if (vm.exception()) - return {}; + auto k_value = TRY_OR_DISCARD(object->get(property_name)); // ii. Let mappedValue be ? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »). auto mapped_value = TRY_OR_DISCARD(vm.call(callback_function.as_function(), this_arg, k_value, Value(k), object)); @@ -383,9 +373,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::unshift) if (vm.exception()) return {}; if (from_present) { - auto from_value = this_object->get(from); - if (vm.exception()) - return {}; + auto from_value = TRY_OR_DISCARD(this_object->get(from)); this_object->set(to, from_value, Object::ShouldThrowExceptions::Yes); if (vm.exception()) return {}; @@ -421,9 +409,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::pop) return js_undefined(); } auto index = length - 1; - auto element = this_object->get(index); - if (vm.exception()) - return {}; + auto element = TRY_OR_DISCARD(this_object->get(index)); this_object->delete_property_or_throw(index); if (vm.exception()) return {}; @@ -446,10 +432,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::shift) return {}; return js_undefined(); } - auto first = this_object->get(0); - if (vm.exception()) - return {}; - + auto first = TRY_OR_DISCARD(this_object->get(0)); for (size_t k = 1; k < length; ++k) { size_t from = k; size_t to = k - 1; @@ -457,9 +440,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::shift) if (vm.exception()) return {}; if (from_present) { - auto from_value = this_object->get(from); - if (vm.exception()) - return {}; + auto from_value = TRY_OR_DISCARD(this_object->get(from)); this_object->set(to, from_value, Object::ShouldThrowExceptions::Yes); if (vm.exception()) return {}; @@ -486,9 +467,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_string) auto* this_object = vm.this_value(global_object).to_object(global_object); if (!this_object) return {}; - auto join_function = this_object->get(vm.names.join); - if (vm.exception()) - return {}; + auto join_function = TRY_OR_DISCARD(this_object->get(vm.names.join)); if (!join_function.is_function()) return ObjectPrototype::to_string(vm, global_object); return TRY_OR_DISCARD(vm.call(join_function.as_function(), this_object)); @@ -515,9 +494,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_locale_string) for (size_t i = 0; i < length; ++i) { if (i > 0) builder.append(separator); - auto value = this_object->get(i); - if (vm.exception()) - return {}; + auto value = TRY_OR_DISCARD(this_object->get(i)); if (value.is_nullish()) continue; auto locale_string_result = TRY_OR_DISCARD(value.invoke(global_object, vm.names.toLocaleString)); @@ -557,9 +534,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::join) for (size_t i = 0; i < length; ++i) { if (i > 0) builder.append(separator); - auto value = this_object->get(i); - if (vm.exception()) - return {}; + auto value = TRY_OR_DISCARD(this_object->get(i)); if (value.is_nullish()) continue; auto string = value.to_string(global_object); @@ -593,10 +568,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::concat) if (vm.exception()) return false; - auto spreadable = object->get(*vm.well_known_symbol_is_concat_spreadable()); - if (vm.exception()) - return false; - + auto spreadable = TRY_OR_DISCARD(object->get(*vm.well_known_symbol_is_concat_spreadable())); if (!spreadable.is_undefined()) return spreadable.to_boolean(); @@ -625,9 +597,10 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::concat) if (vm.exception()) return; if (k_exists) { - auto k_value = obj.get(k); - if (vm.exception()) + auto k_value_or_error = obj.get(k); + if (k_value_or_error.is_error()) return; + auto k_value = k_value_or_error.release_value(); new_array->create_data_property_or_throw(n, k_value); if (vm.exception()) return; @@ -720,10 +693,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::slice) return {}; if (present) { - auto value = this_object->get(k); - if (vm.exception()) - return {}; - + auto value = TRY_OR_DISCARD(this_object->get(k)); new_array->create_data_property_or_throw(index, value); if (vm.exception()) return {}; @@ -801,9 +771,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::index_of) // b. If kPresent is true, then if (k_present) { // i. Let elementK be ? Get(O, ! ToString(𝔽(k))). - auto element_k = object->get(property_name); - if (vm.exception()) - return {}; + auto element_k = TRY_OR_DISCARD(object->get(property_name)); // ii. Let same be IsStrictlyEqual(searchElement, elementK). auto same = is_strictly_equal(search_element, element_k); @@ -875,9 +843,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reduce) // iii. If kPresent is true, then if (k_present) { // 1. Set accumulator to ? Get(O, Pk). - accumulator = object->get(property_name); - if (vm.exception()) - return {}; + accumulator = TRY_OR_DISCARD(object->get(property_name)); } // iv. Set k to k + 1. @@ -901,9 +867,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reduce) // c. If kPresent is true, then if (k_present) { // i. Let kValue be ? Get(O, Pk). - auto k_value = object->get(property_name); - if (vm.exception()) - return {}; + auto k_value = TRY_OR_DISCARD(object->get(property_name)); // ii. Set accumulator to ? Call(callbackfn, undefined, « accumulator, kValue, 𝔽(k), O »). accumulator = TRY_OR_DISCARD(vm.call(callback_function.as_function(), js_undefined(), accumulator, k_value, Value(k), object)); @@ -971,9 +935,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reduce_right) // iii. If kPresent is true, then if (k_present) { // 1. Set accumulator to ? Get(O, Pk). - accumulator = object->get(property_name); - if (vm.exception()) - return {}; + accumulator = TRY_OR_DISCARD(object->get(property_name)); } // iv. Set k to k - 1. @@ -999,9 +961,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reduce_right) // c. If kPresent is true, then if (k_present) { // i. Let kValue be ? Get(O, Pk). - auto k_value = object->get(property_name); - if (vm.exception()) - return {}; + auto k_value = TRY_OR_DISCARD(object->get(property_name)); // ii. Set accumulator to ? Call(callbackfn, undefined, « accumulator, kValue, 𝔽(k), O »). accumulator = TRY_OR_DISCARD(vm.call(callback_function.as_function(), js_undefined(), accumulator, k_value, Value((size_t)k), object)); @@ -1030,21 +990,15 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reverse) if (vm.exception()) return {}; Value lower_value; - if (lower_exists) { - lower_value = this_object->get(lower); - if (vm.exception()) - return {}; - } + if (lower_exists) + lower_value = TRY_OR_DISCARD(this_object->get(lower)); auto upper_exists = this_object->has_property(upper); if (vm.exception()) return {}; Value upper_value; - if (upper_exists) { - upper_value = this_object->get(upper); - if (vm.exception()) - return {}; - } + if (upper_exists) + upper_value = TRY_OR_DISCARD(this_object->get(upper)); if (lower_exists && upper_exists) { this_object->set(lower, upper_value, Object::ShouldThrowExceptions::Yes); @@ -1204,10 +1158,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::sort) return {}; if (k_present) { - auto k_value = object->get(k); - if (vm.exception()) - return {}; - + auto k_value = TRY_OR_DISCARD(object->get(k)); items.append(k_value); } } @@ -1297,9 +1248,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::last_index_of) // b. If kPresent is true, then if (k_present) { // i. Let elementK be ? Get(O, ! ToString(𝔽(k))). - auto element_k = object->get(property_name); - if (vm.exception()) - return {}; + auto element_k = TRY_OR_DISCARD(object->get(property_name)); // ii. Let same be IsStrictlyEqual(searchElement, elementK). auto same = is_strictly_equal(search_element, element_k); @@ -1343,9 +1292,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::includes) } auto value_to_find = vm.argument(0); for (u64 i = from_index; i < length; ++i) { - auto element = this_object->get(i); - if (vm.exception()) - return {}; + auto element = TRY_OR_DISCARD(this_object->get(i)); if (same_value_zero(element, value_to_find)) return Value(true); } @@ -1379,9 +1326,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::find) auto property_name = PropertyName { k }; // b. Let kValue be ? Get(O, Pk). - auto k_value = object->get(property_name); - if (vm.exception()) - return {}; + auto k_value = TRY_OR_DISCARD(object->get(property_name)); // c. Let testResult be ! ToBoolean(? Call(predicate, thisArg, « kValue, 𝔽(k), O »)). auto test_result = TRY_OR_DISCARD(vm.call(predicate.as_function(), this_arg, k_value, Value(k), object)).to_boolean(); @@ -1424,9 +1369,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::find_index) auto property_name = PropertyName { k }; // b. Let kValue be ? Get(O, Pk). - auto k_value = object->get(property_name); - if (vm.exception()) - return {}; + auto k_value = TRY_OR_DISCARD(object->get(property_name)); // c. Let testResult be ! ToBoolean(? Call(predicate, thisArg, « kValue, 𝔽(k), O »)). auto test_result = TRY_OR_DISCARD(vm.call(predicate.as_function(), this_arg, k_value, Value(k), object)).to_boolean(); @@ -1469,9 +1412,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::find_last) auto property_name = PropertyName { k }; // b. Let kValue be ? Get(O, Pk). - auto k_value = object->get(property_name); - if (vm.exception()) - return {}; + auto k_value = TRY_OR_DISCARD(object->get(property_name)); // c. Let testResult be ! ToBoolean(? Call(predicate, thisArg, « kValue, 𝔽(k), O »)). auto test_result = TRY_OR_DISCARD(vm.call(predicate.as_function(), this_arg, k_value, Value((double)k), object)).to_boolean(); @@ -1514,9 +1455,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::find_last_index) auto property_name = PropertyName { k }; // b. Let kValue be ? Get(O, Pk). - auto k_value = object->get(property_name); - if (vm.exception()) - return {}; + auto k_value = TRY_OR_DISCARD(object->get(property_name)); // c. Let testResult be ! ToBoolean(? Call(predicate, thisArg, « kValue, 𝔽(k), O »)). auto test_result = TRY_OR_DISCARD(vm.call(predicate.as_function(), this_arg, k_value, Value((double)k), object)).to_boolean(); @@ -1566,9 +1505,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::some) // c. If kPresent is true, then if (k_present) { // i. Let kValue be ? Get(O, Pk). - auto k_value = object->get(property_name); - if (vm.exception()) - return {}; + auto k_value = TRY_OR_DISCARD(object->get(property_name)); // ii. Let testResult be ! ToBoolean(? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »)). auto test_result = TRY_OR_DISCARD(vm.call(callback_function.as_function(), this_arg, k_value, Value(k), object)).to_boolean(); @@ -1619,9 +1556,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::every) // c. If kPresent is true, then if (k_present) { // i. Let kValue be ? Get(O, Pk). - auto k_value = object->get(property_name); - if (vm.exception()) - return {}; + auto k_value = TRY_OR_DISCARD(object->get(property_name)); // ii. Let testResult be ! ToBoolean(? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »)). auto test_result = TRY_OR_DISCARD(vm.call(callback_function.as_function(), this_arg, k_value, Value(k), object)).to_boolean(); @@ -1693,9 +1628,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::splice) return {}; if (from_present) { - auto from_value = this_object->get(from); - if (vm.exception()) - return {}; + auto from_value = TRY_OR_DISCARD(this_object->get(from)); removed_elements->create_data_property_or_throw(i, from_value); if (vm.exception()) @@ -1717,10 +1650,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::splice) return {}; if (from_present) { - auto from_value = this_object->get(from); - if (vm.exception()) - return {}; - + auto from_value = TRY_OR_DISCARD(this_object->get(from)); this_object->set(to, from_value, Object::ShouldThrowExceptions::Yes); } else { this_object->delete_property_or_throw(to); @@ -1744,9 +1674,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::splice) auto to = i + insert_count - 1; if (from_present) { - auto from_value = this_object->get(from_index); - if (vm.exception()) - return {}; + auto from_value = TRY_OR_DISCARD(this_object->get(from_index)); this_object->set(to, from_value, Object::ShouldThrowExceptions::Yes); } else { this_object->delete_property_or_throw(to); @@ -1862,9 +1790,7 @@ static size_t flatten_into_array(GlobalObject& global_object, Object& new_array, if (!value_exists) continue; - auto value = array.get(j); - if (vm.exception()) - return {}; + auto value = TRY_OR_DISCARD(array.get(j)); if (mapper_func) value = TRY_OR_DISCARD(vm.call(*mapper_func, this_arg, value, Value(j), &array)); @@ -2019,9 +1945,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::copy_within) return {}; if (from_present) { - auto from_value = this_object->get(from_i); - if (vm.exception()) - return {}; + auto from_value = TRY_OR_DISCARD(this_object->get(from_i)); this_object->set(to_i, from_value, Object::ShouldThrowExceptions::Yes); if (vm.exception()) return {}; @@ -2060,7 +1984,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::at) } if (index.has_overflow() || index.value() >= length) return js_undefined(); - return this_object->get(index.value()); + return TRY_OR_DISCARD(this_object->get(index.value())); } } diff --git a/Userland/Libraries/LibJS/Runtime/DatePrototype.cpp b/Userland/Libraries/LibJS/Runtime/DatePrototype.cpp index 18ef237146..0357997900 100644 --- a/Userland/Libraries/LibJS/Runtime/DatePrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/DatePrototype.cpp @@ -85,7 +85,7 @@ void DatePrototype::initialize(GlobalObject& global_object) // B.2.4.3 Date.prototype.toGMTString ( ), https://tc39.es/ecma262/#sec-date.prototype.togmtstring // The function object that is the initial value of Date.prototype.toGMTString // is the same function object that is the initial value of Date.prototype.toUTCString. - define_direct_property(vm.names.toGMTString, get(vm.names.toUTCString), attr); + define_direct_property(vm.names.toGMTString, get_without_side_effects(vm.names.toUTCString), attr); } DatePrototype::~DatePrototype() diff --git a/Userland/Libraries/LibJS/Runtime/Error.cpp b/Userland/Libraries/LibJS/Runtime/Error.cpp index 3124ef88d2..2555868641 100644 --- a/Userland/Libraries/LibJS/Runtime/Error.cpp +++ b/Userland/Libraries/LibJS/Runtime/Error.cpp @@ -43,9 +43,7 @@ ThrowCompletionOr<void> Error::install_error_cause(Value options) return throw_completion(exception->value()); if (has_property) { // a. Let cause be ? Get(options, "cause"). - auto cause = options.as_object().get(vm.names.cause); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto cause = TRY(options.as_object().get(vm.names.cause)); // b. Perform ! CreateNonEnumerableDataPropertyOrThrow(O, "cause", cause). create_non_enumerable_data_property_or_throw(vm.names.cause, cause); diff --git a/Userland/Libraries/LibJS/Runtime/ErrorPrototype.cpp b/Userland/Libraries/LibJS/Runtime/ErrorPrototype.cpp index 094457bcc4..fc4af4f8b4 100644 --- a/Userland/Libraries/LibJS/Runtime/ErrorPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/ErrorPrototype.cpp @@ -40,9 +40,7 @@ JS_DEFINE_NATIVE_FUNCTION(ErrorPrototype::to_string) auto& this_object = this_value.as_object(); String name = "Error"; - auto name_property = this_object.get(vm.names.name); - if (vm.exception()) - return {}; + auto name_property = TRY_OR_DISCARD(this_object.get(vm.names.name)); if (!name_property.is_undefined()) { name = name_property.to_string(global_object); if (vm.exception()) @@ -50,9 +48,7 @@ JS_DEFINE_NATIVE_FUNCTION(ErrorPrototype::to_string) } String message = ""; - auto message_property = this_object.get(vm.names.message); - if (vm.exception()) - return {}; + auto message_property = TRY_OR_DISCARD(this_object.get(vm.names.message)); if (!message_property.is_undefined()) { message = message_property.to_string(global_object); if (vm.exception()) diff --git a/Userland/Libraries/LibJS/Runtime/FunctionObject.cpp b/Userland/Libraries/LibJS/Runtime/FunctionObject.cpp index 13ffd1b303..b4aaa45f27 100644 --- a/Userland/Libraries/LibJS/Runtime/FunctionObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/FunctionObject.cpp @@ -40,16 +40,12 @@ BoundFunction* FunctionObject::bind(Value bound_this_value, Vector<Value> argume }(); i32 computed_length = 0; - auto length_property = get(vm.names.length); - if (vm.exception()) - return nullptr; + auto length_property = TRY_OR_DISCARD(get(vm.names.length)); if (length_property.is_number()) computed_length = max(0, length_property.as_i32() - static_cast<i32>(arguments.size())); Object* constructor_prototype = nullptr; - auto prototype_property = target_function.get(vm.names.prototype); - if (vm.exception()) - return nullptr; + auto prototype_property = TRY_OR_DISCARD(target_function.get(vm.names.prototype)); if (prototype_property.is_object()) constructor_prototype = &prototype_property.as_object(); diff --git a/Userland/Libraries/LibJS/Runtime/GeneratorObject.cpp b/Userland/Libraries/LibJS/Runtime/GeneratorObject.cpp index 0a0c0e3358..645e40116c 100644 --- a/Userland/Libraries/LibJS/Runtime/GeneratorObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/GeneratorObject.cpp @@ -16,11 +16,12 @@ namespace JS { GeneratorObject* GeneratorObject::create(GlobalObject& global_object, Value initial_value, ECMAScriptFunctionObject* generating_function, Environment* generating_scope, Bytecode::RegisterWindow frame) { // This is "g1.prototype" in figure-2 (https://tc39.es/ecma262/img/figure-2.png) - auto generating_function_proto_property = generating_function->get(global_object.vm().names.prototype).to_object(global_object); - if (!generating_function_proto_property) + auto generating_function_prototype = TRY_OR_DISCARD(generating_function->get(global_object.vm().names.prototype)); + auto* generating_function_prototype_object = generating_function_prototype.to_object(global_object); + if (!generating_function_prototype_object) return {}; - auto object = global_object.heap().allocate<GeneratorObject>(global_object, global_object, *generating_function_proto_property); + auto object = global_object.heap().allocate<GeneratorObject>(global_object, global_object, *generating_function_prototype_object); object->m_generating_function = generating_function; object->m_environment = generating_scope; object->m_frame = move(frame); @@ -54,15 +55,15 @@ Value GeneratorObject::next_impl(VM& vm, GlobalObject& global_object, Optional<V auto bytecode_interpreter = Bytecode::Interpreter::current(); VERIFY(bytecode_interpreter); - auto generated_value = [](Value value) { + auto generated_value = [](Value value) -> Value { if (value.is_object()) - return value.as_object().get("result"); + return TRY_OR_DISCARD(value.as_object().get("result")); return value.is_empty() ? js_undefined() : value; }; auto generated_continuation = [&](Value value) -> Bytecode::BasicBlock const* { if (value.is_object()) - return reinterpret_cast<Bytecode::BasicBlock const*>(static_cast<u64>(value.as_object().get("continuation").to_double(global_object))); + return reinterpret_cast<Bytecode::BasicBlock const*>(static_cast<u64>(TRY_OR_DISCARD(value.as_object().get("continuation")).to_double(global_object))); return nullptr; }; diff --git a/Userland/Libraries/LibJS/Runtime/Intl/AbstractOperations.cpp b/Userland/Libraries/LibJS/Runtime/Intl/AbstractOperations.cpp index 06f42df342..42bce8cc4c 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/AbstractOperations.cpp +++ b/Userland/Libraries/LibJS/Runtime/Intl/AbstractOperations.cpp @@ -214,10 +214,7 @@ ThrowCompletionOr<Vector<String>> canonicalize_locale_list(GlobalObject& global_ } // 5. Let len be ? ToLength(? Get(O, "length")). - auto length_value = object->get(vm.names.length); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); - auto length = length_value.to_length(global_object); + auto length = TRY(object->get(vm.names.length)).to_length(global_object); if (auto* exception = vm.exception()) return throw_completion(exception->value()); @@ -235,9 +232,7 @@ ThrowCompletionOr<Vector<String>> canonicalize_locale_list(GlobalObject& global_ // c. If kPresent is true, then if (key_present) { // i. Let kValue be ? Get(O, Pk). - auto key_value = object->get(property_key); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto key_value = TRY(object->get(property_key)); // ii. If Type(kValue) is not String or Object, throw a TypeError exception. if (!key_value.is_string() && !key_value.is_object()) @@ -619,10 +614,9 @@ ThrowCompletionOr<Value> get_option(GlobalObject& global_object, Object const& o auto& vm = global_object.vm(); // 1. Assert: Type(options) is Object. + // 2. Let value be ? Get(options, property). - auto value = options.get(property); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto value = TRY(options.get(property)); // 3. If value is undefined, return fallback. if (value.is_undefined()) { @@ -685,13 +679,10 @@ ThrowCompletionOr<Optional<int>> default_number_option(GlobalObject& global_obje // 9.2.15 GetNumberOption ( options, property, minimum, maximum, fallback ), https://tc39.es/ecma402/#sec-getnumberoption ThrowCompletionOr<Optional<int>> get_number_option(GlobalObject& global_object, Object const& options, PropertyName const& property, int minimum, int maximum, Optional<int> fallback) { - auto& vm = global_object.vm(); - // 1. Assert: Type(options) is Object. + // 2. Let value be ? Get(options, property). - auto value = options.get(property); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto value = TRY(options.get(property)); // 3. Return ? DefaultNumberOption(value, minimum, maximum, fallback). return default_number_option(global_object, value, minimum, maximum, move(fallback)); diff --git a/Userland/Libraries/LibJS/Runtime/Intl/NumberFormat.cpp b/Userland/Libraries/LibJS/Runtime/Intl/NumberFormat.cpp index f01d6c8365..b9e2b0a03b 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/NumberFormat.cpp +++ b/Userland/Libraries/LibJS/Runtime/Intl/NumberFormat.cpp @@ -252,24 +252,16 @@ ThrowCompletionOr<void> set_number_format_digit_options(GlobalObject& global_obj auto min_integer_digits = TRY(get_number_option(global_object, options, vm.names.minimumIntegerDigits, 1, 21, 1)); // 6. Let mnfd be ? Get(options, "minimumFractionDigits"). - auto min_fraction_digits = options.get(vm.names.minimumFractionDigits); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto min_fraction_digits = TRY(options.get(vm.names.minimumFractionDigits)); // 7. Let mxfd be ? Get(options, "maximumFractionDigits"). - auto max_fraction_digits = options.get(vm.names.maximumFractionDigits); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto max_fraction_digits = TRY(options.get(vm.names.maximumFractionDigits)); // 8. Let mnsd be ? Get(options, "minimumSignificantDigits"). - auto min_significant_digits = options.get(vm.names.minimumSignificantDigits); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto min_significant_digits = TRY(options.get(vm.names.minimumSignificantDigits)); // 9. Let mxsd be ? Get(options, "maximumSignificantDigits"). - auto max_significant_digits = options.get(vm.names.maximumSignificantDigits); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto max_significant_digits = TRY(options.get(vm.names.maximumSignificantDigits)); // 10. Set intlObj.[[MinimumIntegerDigits]] to mnid. intl_object.set_min_integer_digits(*min_integer_digits); diff --git a/Userland/Libraries/LibJS/Runtime/IteratorOperations.cpp b/Userland/Libraries/LibJS/Runtime/IteratorOperations.cpp index c86b70e8c2..e72c94966c 100644 --- a/Userland/Libraries/LibJS/Runtime/IteratorOperations.cpp +++ b/Userland/Libraries/LibJS/Runtime/IteratorOperations.cpp @@ -21,9 +21,7 @@ Object* get_iterator(GlobalObject& global_object, Value value, IteratorHint hint auto object = value.to_object(global_object); if (!object) return {}; - method = object->get(*vm.well_known_symbol_iterator()); - if (vm.exception()) - return {}; + method = TRY_OR_DISCARD(object->get(*vm.well_known_symbol_iterator())); } if (!method.is_function()) { vm.throw_exception<TypeError>(global_object, ErrorType::NotIterable, value.to_string_without_side_effects()); @@ -40,12 +38,11 @@ Object* get_iterator(GlobalObject& global_object, Value value, IteratorHint hint // 7.4.2 IteratorNext ( iteratorRecord [ , value ] ), https://tc39.es/ecma262/#sec-iteratornext Object* iterator_next(Object& iterator, Value value) { + // FIXME: Implement using iterator records, not ordinary objects auto& vm = iterator.vm(); auto& global_object = iterator.global_object(); - auto next_method = iterator.get(vm.names.next); - if (vm.exception()) - return {}; + auto next_method = TRY_OR_DISCARD(iterator.get(vm.names.next)); if (!next_method.is_function()) { vm.throw_exception<TypeError>(global_object, ErrorType::IterableNextNotAFunction); @@ -70,20 +67,18 @@ Object* iterator_next(Object& iterator, Value value) bool iterator_complete(GlobalObject& global_object, Object& iterator_result) { auto& vm = global_object.vm(); - auto done = iterator_result.get(vm.names.done); - if (vm.exception()) - return {}; - return done.to_boolean(); + + // 1. Return ! ToBoolean(? Get(iterResult, "done")). + return TRY_OR_DISCARD(iterator_result.get(vm.names.done)).to_boolean(); } // 7.4.4 IteratorValue ( iterResult ), https://tc39.es/ecma262/#sec-iteratorvalue Value iterator_value(GlobalObject& global_object, Object& iterator_result) { auto& vm = global_object.vm(); - auto value = iterator_result.get(vm.names.value); - if (vm.exception()) - return {}; - return value; + + // 1. Return ? Get(iterResult, "value"). + return TRY_OR_DISCARD(iterator_result.get(vm.names.value)); } // 7.4.5 IteratorStep ( iteratorRecord ), https://tc39.es/ecma262/#sec-iteratorstep @@ -186,18 +181,18 @@ void get_iterator_values(GlobalObject& global_object, Value value, Function<Iter if (!next_object) return; - auto done_property = next_object->get(vm.names.done); - if (vm.exception()) + auto done_property_or_error = next_object->get(vm.names.done); + if (done_property_or_error.is_error()) return; - if (!done_property.is_empty() && done_property.to_boolean()) + if (done_property_or_error.release_value().to_boolean()) return; - auto next_value = next_object->get(vm.names.value); - if (vm.exception()) + auto next_value_or_error = next_object->get(vm.names.value); + if (next_value_or_error.is_error()) return; - auto result = callback(next_value); + auto result = callback(next_value_or_error.release_value()); if (result == IterationDecision::Break) { if (close_on_abrupt == CloseOnAbrupt::Yes) iterator_close(*iterator); diff --git a/Userland/Libraries/LibJS/Runtime/JSONObject.cpp b/Userland/Libraries/LibJS/Runtime/JSONObject.cpp index 00dc58493a..41e26403b6 100644 --- a/Userland/Libraries/LibJS/Runtime/JSONObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/JSONObject.cpp @@ -60,9 +60,7 @@ String JSONObject::stringify_impl(GlobalObject& global_object, Value value, Valu auto replacer_length = TRY_OR_DISCARD(length_of_array_like(global_object, replacer_object)); Vector<String> list; for (size_t i = 0; i < replacer_length; ++i) { - auto replacer_value = replacer_object.get(i); - if (vm.exception()) - return {}; + auto replacer_value = TRY_OR_DISCARD(replacer_object.get(i)); String item; if (replacer_value.is_string()) { item = replacer_value.as_string().string(); @@ -142,16 +140,12 @@ JS_DEFINE_NATIVE_FUNCTION(JSONObject::stringify) String JSONObject::serialize_json_property(GlobalObject& global_object, StringifyState& state, const PropertyName& key, Object* holder) { auto& vm = global_object.vm(); - auto value = holder->get(key); - if (vm.exception()) - return {}; + auto value = TRY_OR_DISCARD(holder->get(key)); if (value.is_object() || value.is_bigint()) { auto* value_object = value.to_object(global_object); if (vm.exception()) return {}; - auto to_json = value_object->get(vm.names.toJSON); - if (vm.exception()) - return {}; + auto to_json = TRY_OR_DISCARD(value_object->get(vm.names.toJSON)); if (to_json.is_function()) value = TRY_OR_DISCARD(vm.call(to_json.as_function(), value, js_string(vm, key.to_string()))); } @@ -465,9 +459,7 @@ Array* JSONObject::parse_json_array(GlobalObject& global_object, const JsonArray Value JSONObject::internalize_json_property(GlobalObject& global_object, Object* holder, PropertyName const& name, FunctionObject& reviver) { auto& vm = global_object.vm(); - auto value = holder->get(name); - if (vm.exception()) - return {}; + auto value = TRY_OR_DISCARD(holder->get(name)); if (value.is_object()) { auto is_array = TRY_OR_DISCARD(value.is_array(global_object)); diff --git a/Userland/Libraries/LibJS/Runtime/MapConstructor.cpp b/Userland/Libraries/LibJS/Runtime/MapConstructor.cpp index 36dc4dbbe0..912ab36c48 100644 --- a/Userland/Libraries/LibJS/Runtime/MapConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/MapConstructor.cpp @@ -54,9 +54,7 @@ Value MapConstructor::construct(FunctionObject& new_target) if (vm.argument(0).is_nullish()) return map; - auto adder = map->get(vm.names.set); - if (vm.exception()) - return {}; + auto adder = TRY_OR_DISCARD(map->get(vm.names.set)); if (!adder.is_function()) { vm.throw_exception<TypeError>(global_object, ErrorType::NotAFunction, "'set' property of Map"); return {}; @@ -68,12 +66,14 @@ Value MapConstructor::construct(FunctionObject& new_target) vm.throw_exception<TypeError>(global_object, ErrorType::NotAnObject, String::formatted("Iterator value {}", iterator_value.to_string_without_side_effects())); return IterationDecision::Break; } - auto key = iterator_value.as_object().get(0); - if (vm.exception()) + auto key_or_error = iterator_value.as_object().get(0); + if (key_or_error.is_error()) return IterationDecision::Break; - auto value = iterator_value.as_object().get(1); - if (vm.exception()) + auto key = key_or_error.release_value(); + auto value_or_error = iterator_value.as_object().get(1); + if (value_or_error.is_error()) return IterationDecision::Break; + auto value = value_or_error.release_value(); (void)vm.call(adder.as_function(), Value(map), key, value); return vm.exception() ? IterationDecision::Break : IterationDecision::Continue; }); diff --git a/Userland/Libraries/LibJS/Runtime/MapPrototype.cpp b/Userland/Libraries/LibJS/Runtime/MapPrototype.cpp index 1b91b5e750..ad520f1925 100644 --- a/Userland/Libraries/LibJS/Runtime/MapPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/MapPrototype.cpp @@ -34,7 +34,7 @@ void MapPrototype::initialize(GlobalObject& global_object) define_native_accessor(vm.names.size, size_getter, {}, Attribute::Configurable); - define_direct_property(*vm.well_known_symbol_iterator(), Object::get(vm.names.entries), attr); + define_direct_property(*vm.well_known_symbol_iterator(), get_without_side_effects(vm.names.entries), attr); define_direct_property(*vm.well_known_symbol_to_string_tag(), js_string(global_object.heap(), vm.names.Map.as_string()), Attribute::Configurable); } diff --git a/Userland/Libraries/LibJS/Runtime/NumberConstructor.cpp b/Userland/Libraries/LibJS/Runtime/NumberConstructor.cpp index 8665680c05..817c7ca758 100644 --- a/Userland/Libraries/LibJS/Runtime/NumberConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/NumberConstructor.cpp @@ -41,8 +41,8 @@ void NumberConstructor::initialize(GlobalObject& global_object) define_native_function(vm.names.isInteger, is_integer, 1, attr); define_native_function(vm.names.isNaN, is_nan, 1, attr); define_native_function(vm.names.isSafeInteger, is_safe_integer, 1, attr); - define_direct_property(vm.names.parseInt, global_object.get(vm.names.parseInt), attr); - define_direct_property(vm.names.parseFloat, global_object.get(vm.names.parseFloat), attr); + define_direct_property(vm.names.parseInt, global_object.get_without_side_effects(vm.names.parseInt), attr); + define_direct_property(vm.names.parseFloat, global_object.get_without_side_effects(vm.names.parseFloat), attr); define_direct_property(vm.names.EPSILON, Value(EPSILON_VALUE), 0); define_direct_property(vm.names.MAX_VALUE, Value(NumericLimits<double>::max()), 0); define_direct_property(vm.names.MIN_VALUE, Value(NumericLimits<double>::min()), 0); diff --git a/Userland/Libraries/LibJS/Runtime/Object.cpp b/Userland/Libraries/LibJS/Runtime/Object.cpp index 873aea3079..de6d70d8c3 100644 --- a/Userland/Libraries/LibJS/Runtime/Object.cpp +++ b/Userland/Libraries/LibJS/Runtime/Object.cpp @@ -77,7 +77,7 @@ ThrowCompletionOr<bool> Object::is_extensible() const // 7.3 Operations on Objects, https://tc39.es/ecma262/#sec-operations-on-objects // 7.3.2 Get ( O, P ), https://tc39.es/ecma262/#sec-get-o-p -Value Object::get(PropertyName const& property_name) const +ThrowCompletionOr<Value> Object::get(PropertyName const& property_name) const { // 1. Assert: Type(O) is Object. @@ -85,7 +85,7 @@ Value Object::get(PropertyName const& property_name) const VERIFY(property_name.is_valid()); // 3. Return ? O.[[Get]](P, O). - return TRY_OR_DISCARD(internal_get(property_name, this)); + return TRY(internal_get(property_name, this)); } // 7.3.3 GetV ( V, P ) is defined as Value::get(). @@ -401,7 +401,6 @@ MarkedValueList Object::enumerable_own_property_names(PropertyKind kind) const // NOTE: This has been flattened for readability, so some `else` branches in the // spec text have been replaced with `continue`s in the loop below. - auto& vm = this->vm(); auto& global_object = this->global_object(); // 1. Assert: Type(O) is Object. @@ -438,9 +437,10 @@ MarkedValueList Object::enumerable_own_property_names(PropertyKind kind) const // 2. Else, // a. Let value be ? Get(O, key). - auto value = get(property_name); - if (vm.exception()) + auto value_or_error = get(property_name); + if (value_or_error.is_error()) return MarkedValueList { heap() }; + auto value = value_or_error.release_value(); // b. If kind is value, append value to properties. if (kind == PropertyKind::Value) { @@ -481,9 +481,7 @@ ThrowCompletionOr<Object*> Object::copy_data_properties(Value source, HashTable< auto desc = TRY(from_object->internal_get_own_property(next_key)); if (desc.has_value() && desc->attributes().is_enumerable()) { - auto prop_value = from_object->get(next_key); - if (auto* thrown_exception = vm().exception()) - return JS::throw_completion(thrown_exception->value()); + auto prop_value = TRY(from_object->get(next_key)); create_data_property_or_throw(next_key, prop_value); if (auto* thrown_exception = vm().exception()) return JS::throw_completion(thrown_exception->value()); @@ -1096,9 +1094,7 @@ Object* Object::define_properties(Value properties) // b. If propDesc is not undefined and propDesc.[[Enumerable]] is true, then if (property_descriptor.has_value() && *property_descriptor->enumerable) { // i. Let descObj be ? Get(props, nextKey). - auto descriptor_object = props->get(property_name); - if (vm.exception()) - return {}; + auto descriptor_object = TRY_OR_DISCARD(props->get(property_name)); // ii. Let desc be ? ToPropertyDescriptor(descObj). auto descriptor = to_property_descriptor(global_object, descriptor_object); @@ -1159,9 +1155,7 @@ ThrowCompletionOr<Value> Object::ordinary_to_primitive(Value::PreferredType pref // 3. For each element name of methodNames, do for (auto& method_name : method_names) { // a. Let method be ? Get(O, name). - auto method = get(method_name); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto method = TRY(get(method_name)); // b. If IsCallable(method) is true, then if (method.is_function()) { diff --git a/Userland/Libraries/LibJS/Runtime/Object.h b/Userland/Libraries/LibJS/Runtime/Object.h index 4a58db187d..8cea918a24 100644 --- a/Userland/Libraries/LibJS/Runtime/Object.h +++ b/Userland/Libraries/LibJS/Runtime/Object.h @@ -75,7 +75,7 @@ public: // 7.3 Operations on Objects, https://tc39.es/ecma262/#sec-operations-on-objects - Value get(PropertyName const&) const; + ThrowCompletionOr<Value> get(PropertyName const&) const; bool set(PropertyName const&, Value, ShouldThrowExceptions); bool create_data_property(PropertyName const&, Value); bool create_method_property(PropertyName const&, Value); diff --git a/Userland/Libraries/LibJS/Runtime/ObjectConstructor.cpp b/Userland/Libraries/LibJS/Runtime/ObjectConstructor.cpp index 95ed61ff4f..3ff5bbff11 100644 --- a/Userland/Libraries/LibJS/Runtime/ObjectConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/ObjectConstructor.cpp @@ -245,12 +245,14 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::from_entries) vm.throw_exception<TypeError>(global_object, ErrorType::NotAnObject, String::formatted("Iterator value {}", iterator_value.to_string_without_side_effects())); return IterationDecision::Break; } - auto key = iterator_value.as_object().get(0); - if (vm.exception()) + auto key_or_error = iterator_value.as_object().get(0); + if (key_or_error.is_error()) return IterationDecision::Break; - auto value = iterator_value.as_object().get(1); - if (vm.exception()) + auto key = key_or_error.release_value(); + auto value_or_error = iterator_value.as_object().get(1); + if (value_or_error.is_error()) return IterationDecision::Break; + auto value = value_or_error.release_value(); auto property_key = key.to_property_key(global_object); if (vm.exception()) return IterationDecision::Break; @@ -484,9 +486,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::assign) continue; // a. Let propValue be ? Get(from, nextKey). - auto prop_value = from->get(property_name); - if (vm.exception()) - return {}; + auto prop_value = TRY_OR_DISCARD(from->get(property_name)); // b. Perform ? Set(to, nextKey, propValue, true). to->set(property_name, prop_value, Object::ShouldThrowExceptions::Yes); diff --git a/Userland/Libraries/LibJS/Runtime/ObjectEnvironment.cpp b/Userland/Libraries/LibJS/Runtime/ObjectEnvironment.cpp index f597d8bcb2..371850c7e2 100644 --- a/Userland/Libraries/LibJS/Runtime/ObjectEnvironment.cpp +++ b/Userland/Libraries/LibJS/Runtime/ObjectEnvironment.cpp @@ -35,13 +35,9 @@ bool ObjectEnvironment::has_binding(FlyString const& name) const return false; if (!m_with_environment) return true; - auto unscopables = m_binding_object.get(*vm.well_known_symbol_unscopables()); - if (vm.exception()) - return {}; + auto unscopables = TRY_OR_DISCARD(m_binding_object.get(*vm.well_known_symbol_unscopables())); if (unscopables.is_object()) { - auto blocked = unscopables.as_object().get(name); - if (vm.exception()) - return {}; + auto blocked = TRY_OR_DISCARD(unscopables.as_object().get(name)); if (blocked.to_boolean()) return false; } @@ -110,7 +106,7 @@ Value ObjectEnvironment::get_binding_value(GlobalObject& global_object, FlyStrin global_object.vm().throw_exception<ReferenceError>(global_object, ErrorType::UnknownIdentifier, name); return {}; } - return m_binding_object.get(name); + return TRY_OR_DISCARD(m_binding_object.get(name)); } // 9.1.1.2.7 DeleteBinding ( N ), https://tc39.es/ecma262/#sec-object-environment-records-deletebinding-n diff --git a/Userland/Libraries/LibJS/Runtime/ObjectPrototype.cpp b/Userland/Libraries/LibJS/Runtime/ObjectPrototype.cpp index 7361d6bdb2..4b1a628398 100644 --- a/Userland/Libraries/LibJS/Runtime/ObjectPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/ObjectPrototype.cpp @@ -124,9 +124,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::to_string) builtin_tag = "Object"; // 15. Let tag be ? Get(O, @@toStringTag). - auto to_string_tag = object->get(*vm.well_known_symbol_to_string_tag()); - if (vm.exception()) - return {}; + auto to_string_tag = TRY_OR_DISCARD(object->get(*vm.well_known_symbol_to_string_tag())); // Optimization: Instead of creating another PrimitiveString from builtin_tag, we separate tag and to_string_tag and add an additional branch to step 16. String tag; diff --git a/Userland/Libraries/LibJS/Runtime/Promise.cpp b/Userland/Libraries/LibJS/Runtime/Promise.cpp index f9d93b97f7..8a00d6954f 100644 --- a/Userland/Libraries/LibJS/Runtime/Promise.cpp +++ b/Userland/Libraries/LibJS/Runtime/Promise.cpp @@ -23,9 +23,7 @@ Object* promise_resolve(GlobalObject& global_object, Object& constructor, Value { auto& vm = global_object.vm(); if (value.is_object() && is<Promise>(value.as_object())) { - auto value_constructor = value.as_object().get(vm.names.constructor); - if (vm.exception()) - return nullptr; + auto value_constructor = TRY_OR_DISCARD(value.as_object().get(vm.names.constructor)); if (same_value(value_constructor, &constructor)) return &static_cast<Promise&>(value.as_object()); } @@ -72,14 +70,14 @@ Promise::ResolvingFunctions Promise::create_resolving_functions() dbgln_if(PROMISE_DEBUG, "[Promise @ {} / PromiseResolvingFunction]: Resolution is not an object, fulfilling with {}", &promise, resolution); return promise.fulfill(resolution); } - auto then_action = resolution.as_object().get(vm.names.then); - if (vm.exception()) { + auto then = resolution.as_object().get(vm.names.then); + if (then.is_throw_completion()) { dbgln_if(PROMISE_DEBUG, "[Promise @ {} / PromiseResolvingFunction]: Exception while getting 'then' property, rejecting with error", &promise); - auto error = vm.exception()->value(); vm.clear_exception(); vm.stop_unwind(); - return promise.reject(error); + return promise.reject(then.throw_completion().value()); } + auto then_action = then.release_value(); if (!then_action.is_function()) { dbgln_if(PROMISE_DEBUG, "[Promise @ {} / PromiseResolvingFunction]: Then action is not a function, fulfilling with {}", &promise, resolution); return promise.fulfill(resolution); diff --git a/Userland/Libraries/LibJS/Runtime/PropertyDescriptor.cpp b/Userland/Libraries/LibJS/Runtime/PropertyDescriptor.cpp index dfdaeae9cc..71a304166a 100644 --- a/Userland/Libraries/LibJS/Runtime/PropertyDescriptor.cpp +++ b/Userland/Libraries/LibJS/Runtime/PropertyDescriptor.cpp @@ -88,45 +88,35 @@ PropertyDescriptor to_property_descriptor(GlobalObject& global_object, Value arg if (vm.exception()) return {}; if (has_enumerable) { - auto enumerable = object.get(vm.names.enumerable); - if (vm.exception()) - return {}; + auto enumerable = TRY_OR_DISCARD(object.get(vm.names.enumerable)); descriptor.enumerable = enumerable.to_boolean(); } auto has_configurable = object.has_property(vm.names.configurable); if (vm.exception()) return {}; if (has_configurable) { - auto configurable = object.get(vm.names.configurable); - if (vm.exception()) - return {}; + auto configurable = TRY_OR_DISCARD(object.get(vm.names.configurable)); descriptor.configurable = configurable.to_boolean(); } auto has_value = object.has_property(vm.names.value); if (vm.exception()) return {}; if (has_value) { - auto value = object.get(vm.names.value); - if (vm.exception()) - return {}; + auto value = TRY_OR_DISCARD(object.get(vm.names.value)); descriptor.value = value; } auto has_writable = object.has_property(vm.names.writable); if (vm.exception()) return {}; if (has_writable) { - auto writable = object.get(vm.names.writable); - if (vm.exception()) - return {}; + auto writable = TRY_OR_DISCARD(object.get(vm.names.writable)); descriptor.writable = writable.to_boolean(); } auto has_get = object.has_property(vm.names.get); if (vm.exception()) return {}; if (has_get) { - auto getter = object.get(vm.names.get); - if (vm.exception()) - return {}; + auto getter = TRY_OR_DISCARD(object.get(vm.names.get)); if (!getter.is_function() && !getter.is_undefined()) { vm.throw_exception<TypeError>(global_object, ErrorType::AccessorBadField, "get"); return {}; @@ -137,9 +127,7 @@ PropertyDescriptor to_property_descriptor(GlobalObject& global_object, Value arg if (vm.exception()) return {}; if (has_set) { - auto setter = object.get(vm.names.set); - if (vm.exception()) - return {}; + auto setter = TRY_OR_DISCARD(object.get(vm.names.set)); if (!setter.is_function() && !setter.is_undefined()) { vm.throw_exception<TypeError>(global_object, ErrorType::AccessorBadField, "set"); return {}; diff --git a/Userland/Libraries/LibJS/Runtime/Reference.cpp b/Userland/Libraries/LibJS/Runtime/Reference.cpp index da6cccab20..fe5526158c 100644 --- a/Userland/Libraries/LibJS/Runtime/Reference.cpp +++ b/Userland/Libraries/LibJS/Runtime/Reference.cpp @@ -72,7 +72,7 @@ Value Reference::get_value(GlobalObject& global_object) const auto* base_obj = m_base_value.to_object(global_object); if (!base_obj) return {}; - return base_obj->get(m_name); + return TRY_OR_DISCARD(base_obj->get(m_name)); } VERIFY(m_base_type == BaseType::Environment); diff --git a/Userland/Libraries/LibJS/Runtime/RegExpConstructor.cpp b/Userland/Libraries/LibJS/Runtime/RegExpConstructor.cpp index 97b01f7988..8a56572ff5 100644 --- a/Userland/Libraries/LibJS/Runtime/RegExpConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/RegExpConstructor.cpp @@ -45,10 +45,7 @@ Value RegExpConstructor::call() bool pattern_is_regexp = TRY_OR_DISCARD(pattern.is_regexp(global_object)); if (pattern_is_regexp && flags.is_undefined()) { - auto pattern_constructor = pattern.as_object().get(vm.names.constructor); - if (vm.exception()) - return {}; - + auto pattern_constructor = TRY_OR_DISCARD(pattern.as_object().get(vm.names.constructor)); if (same_value(this, pattern_constructor)) return pattern; } @@ -79,14 +76,10 @@ Value RegExpConstructor::construct(FunctionObject&) else flags_value = flags; } else if (pattern_is_regexp) { - pattern_value = pattern.as_object().get(vm.names.source); - if (vm.exception()) - return {}; + pattern_value = TRY_OR_DISCARD(pattern.as_object().get(vm.names.source)); if (flags.is_undefined()) { - flags_value = pattern.as_object().get(vm.names.flags); - if (vm.exception()) - return {}; + flags_value = TRY_OR_DISCARD(pattern.as_object().get(vm.names.flags)); } else { flags_value = flags; } diff --git a/Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp b/Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp index 340dfc492e..830ff0d436 100644 --- a/Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp @@ -78,19 +78,19 @@ size_t advance_string_index(Utf16View const& string, size_t index, bool unicode) return index + code_point.code_unit_count; } -static void increment_last_index(GlobalObject& global_object, Object& regexp_object, Utf16View const& string, bool unicode) +static ThrowCompletionOr<void> increment_last_index(GlobalObject& global_object, Object& regexp_object, Utf16View const& string, bool unicode) { auto& vm = global_object.vm(); - auto last_index_value = regexp_object.get(vm.names.lastIndex); - if (vm.exception()) - return; - auto last_index = last_index_value.to_length(global_object); - if (vm.exception()) - return; + auto last_index = TRY(regexp_object.get(vm.names.lastIndex)).to_length(global_object); + if (auto* exception = vm.exception()) + return throw_completion(exception->value()); last_index = advance_string_index(string, last_index, unicode); regexp_object.set(vm.names.lastIndex, Value(last_index), Object::ShouldThrowExceptions::Yes); + if (auto* exception = vm.exception()) + return throw_completion(exception->value()); + return {}; } // 1.1.2.1 Match Records, https://tc39.es/proposal-regexp-match-indices/#sec-match-records @@ -172,10 +172,7 @@ static Value regexp_builtin_exec(GlobalObject& global_object, RegExpObject& rege // FIXME: This should try using internal slots [[RegExpMatcher]], [[OriginalFlags]], etc. auto& vm = global_object.vm(); - auto last_index_value = regexp_object.get(vm.names.lastIndex); - if (vm.exception()) - return {}; - auto last_index = last_index_value.to_length(global_object); + auto last_index = TRY_OR_DISCARD(regexp_object.get(vm.names.lastIndex)).to_length(global_object); if (vm.exception()) return {}; @@ -287,10 +284,7 @@ Value regexp_exec(GlobalObject& global_object, Object& regexp_object, Utf16Strin { auto& vm = global_object.vm(); - auto exec = regexp_object.get(vm.names.exec); - if (vm.exception()) - return {}; - + auto exec = TRY_OR_DISCARD(regexp_object.get(vm.names.exec)); if (exec.is_function()) { auto result = TRY_OR_DISCARD(vm.call(exec.as_function(), ®exp_object, js_string(vm, move(string)))); @@ -344,11 +338,9 @@ JS_DEFINE_NATIVE_GETTER(RegExpPrototype::flags) StringBuilder builder(8); -#define __JS_ENUMERATE(flagName, flag_name, flag_char) \ - auto flag_##flag_name = regexp_object->get(vm.names.flagName); \ - if (vm.exception()) \ - return {}; \ - if (flag_##flag_name.to_boolean()) \ +#define __JS_ENUMERATE(flagName, flag_name, flag_char) \ + auto flag_##flag_name = TRY_OR_DISCARD(regexp_object->get(vm.names.flagName)); \ + if (flag_##flag_name.to_boolean()) \ builder.append(#flag_char); JS_ENUMERATE_REGEXP_FLAGS #undef __JS_ENUMERATE @@ -412,16 +404,12 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::to_string) if (!regexp_object) return {}; - auto source_attr = regexp_object->get(vm.names.source); - if (vm.exception()) - return {}; + auto source_attr = TRY_OR_DISCARD(regexp_object->get(vm.names.source)); auto pattern = source_attr.to_string(global_object); if (vm.exception()) return {}; - auto flags_attr = regexp_object->get(vm.names.flags); - if (vm.exception()) - return {}; + auto flags_attr = TRY_OR_DISCARD(regexp_object->get(vm.names.flags)); auto flags = flags_attr.to_string(global_object); if (vm.exception()) return {}; @@ -440,10 +428,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_match) if (vm.exception()) return {}; - auto global_value = regexp_object->get(vm.names.global); - if (vm.exception()) - return {}; - bool global = global_value.to_boolean(); + bool global = TRY_OR_DISCARD(regexp_object->get(vm.names.global)).to_boolean(); if (!global) { auto result = regexp_exec(global_object, *regexp_object, move(string)); @@ -460,10 +445,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_match) if (vm.exception()) return {}; - auto unicode_value = regexp_object->get(vm.names.unicode); - if (vm.exception()) - return {}; - bool unicode = unicode_value.to_boolean(); + bool unicode = TRY_OR_DISCARD(regexp_object->get(vm.names.unicode)).to_boolean(); size_t n = 0; @@ -481,9 +463,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_match) auto* result_object = result.to_object(global_object); if (!result_object) return {}; - auto match_object = result_object->get(0); - if (vm.exception()) - return {}; + auto match_object = TRY_OR_DISCARD(result_object->get(0)); auto match_str = match_object.to_string(global_object); if (vm.exception()) return {}; @@ -492,11 +472,8 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_match) if (vm.exception()) return {}; - if (match_str.is_empty()) { - increment_last_index(global_object, *regexp_object, string.view(), unicode); - if (vm.exception()) - return {}; - } + if (match_str.is_empty()) + TRY_OR_DISCARD(increment_last_index(global_object, *regexp_object, string.view(), unicode)); ++n; } @@ -515,10 +492,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_match_all) auto* constructor = TRY_OR_DISCARD(species_constructor(global_object, *regexp_object, *global_object.regexp_constructor())); - auto flags_value = regexp_object->get(vm.names.flags); - if (vm.exception()) - return {}; - auto flags = flags_value.to_string(global_object); + auto flags = TRY_OR_DISCARD(regexp_object->get(vm.names.flags)).to_string(global_object); if (vm.exception()) return {}; @@ -535,10 +509,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_match_all) if (!matcher) return {}; - auto last_index_value = regexp_object->get(vm.names.lastIndex); - if (vm.exception()) - return {}; - auto last_index = last_index_value.to_length(global_object); + auto last_index = TRY_OR_DISCARD(regexp_object->get(vm.names.lastIndex)).to_length(global_object); if (vm.exception()) return {}; @@ -573,18 +544,11 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_replace) return {}; } - auto global_value = regexp_object->get(vm.names.global); - if (vm.exception()) - return {}; - - bool global = global_value.to_boolean(); + bool global = TRY_OR_DISCARD(regexp_object->get(vm.names.global)).to_boolean(); bool unicode = false; if (global) { - auto unicode_value = regexp_object->get(vm.names.unicode); - if (vm.exception()) - return {}; - unicode = unicode_value.to_boolean(); + unicode = TRY_OR_DISCARD(regexp_object->get(vm.names.unicode)).to_boolean(); regexp_object->set(vm.names.lastIndex, Value(0), Object::ShouldThrowExceptions::Yes); if (vm.exception()) @@ -608,18 +572,13 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_replace) if (!global) break; - auto match_object = result_object->get(0); - if (vm.exception()) - return {}; + auto match_object = TRY_OR_DISCARD(result_object->get(0)); String match_str = match_object.to_string(global_object); if (vm.exception()) return {}; - if (match_str.is_empty()) { - increment_last_index(global_object, *regexp_object, string_view, unicode); - if (vm.exception()) - return {}; - } + if (match_str.is_empty()) + TRY_OR_DISCARD(increment_last_index(global_object, *regexp_object, string_view, unicode)); } StringBuilder accumulated_result; @@ -630,18 +589,13 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_replace) size_t result_length = TRY_OR_DISCARD(length_of_array_like(global_object, result)); size_t n_captures = result_length == 0 ? 0 : result_length - 1; - auto matched_value = result.get(0); - if (vm.exception()) - return {}; + auto matched_value = TRY_OR_DISCARD(result.get(0)); auto matched = matched_value.to_utf16_string(global_object); if (vm.exception()) return {}; auto matched_length = matched.length_in_code_units(); - auto position_value = result.get(vm.names.index); - if (vm.exception()) - return {}; - + auto position_value = TRY_OR_DISCARD(result.get(vm.names.index)); double position = position_value.to_integer_or_infinity(global_object); if (vm.exception()) return {}; @@ -650,10 +604,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_replace) MarkedValueList captures(vm.heap()); for (size_t n = 1; n <= n_captures; ++n) { - auto capture = result.get(n); - if (vm.exception()) - return {}; - + auto capture = TRY_OR_DISCARD(result.get(n)); if (!capture.is_undefined()) { auto capture_string = capture.to_string(global_object); if (vm.exception()) @@ -667,9 +618,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_replace) captures.append(move(capture)); } - auto named_captures = result.get(vm.names.groups); - if (vm.exception()) - return {}; + auto named_captures = TRY_OR_DISCARD(result.get(vm.names.groups)); String replacement; @@ -728,9 +677,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_search) if (vm.exception()) return {}; - auto previous_last_index = regexp_object->get(vm.names.lastIndex); - if (vm.exception()) - return {}; + auto previous_last_index = TRY_OR_DISCARD(regexp_object->get(vm.names.lastIndex)); if (!same_value(previous_last_index, Value(0))) { regexp_object->set(vm.names.lastIndex, Value(0), Object::ShouldThrowExceptions::Yes); if (vm.exception()) @@ -741,9 +688,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_search) if (vm.exception()) return {}; - auto current_last_index = regexp_object->get(vm.names.lastIndex); - if (vm.exception()) - return {}; + auto current_last_index = TRY_OR_DISCARD(regexp_object->get(vm.names.lastIndex)); if (!same_value(current_last_index, previous_last_index)) { regexp_object->set(vm.names.lastIndex, previous_last_index, Object::ShouldThrowExceptions::Yes); if (vm.exception()) @@ -757,11 +702,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_search) if (!result_object) return {}; - auto index = result_object->get(vm.names.index); - if (vm.exception()) - return {}; - - return index; + return TRY_OR_DISCARD(result_object->get(vm.names.index)); } // 22.2.5.13 RegExp.prototype [ @@split ] ( string, limit ), https://tc39.es/ecma262/#sec-regexp.prototype-@@split @@ -778,10 +719,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_split) auto* constructor = TRY_OR_DISCARD(species_constructor(global_object, *regexp_object, *global_object.regexp_constructor())); - auto flags_object = regexp_object->get(vm.names.flags); - if (vm.exception()) - return {}; - auto flags = flags_object.to_string(global_object); + auto flags = TRY_OR_DISCARD(regexp_object->get(vm.names.flags)).to_string(global_object); if (vm.exception()) return {}; @@ -836,10 +774,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_split) continue; } - auto last_index_value = splitter->get(vm.names.lastIndex); - if (vm.exception()) - return {}; - auto last_index = last_index_value.to_length(global_object); // 'e' in the spec. + auto last_index = TRY_OR_DISCARD(splitter->get(vm.names.lastIndex)).to_length(global_object); // 'e' in the spec. if (vm.exception()) return {}; last_index = min(last_index, string_view.length_in_code_units()); @@ -865,10 +800,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_split) --number_of_captures; for (size_t i = 1; i <= number_of_captures; ++i) { - auto next_capture = result_object->get(i); - if (vm.exception()) - return {}; - + auto next_capture = TRY_OR_DISCARD(result_object->get(i)); array->create_data_property_or_throw(array_length, next_capture); if (++array_length == limit) return array; diff --git a/Userland/Libraries/LibJS/Runtime/RegExpStringIteratorPrototype.cpp b/Userland/Libraries/LibJS/Runtime/RegExpStringIteratorPrototype.cpp index 5d9c99af88..3dad758536 100644 --- a/Userland/Libraries/LibJS/Runtime/RegExpStringIteratorPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/RegExpStringIteratorPrototype.cpp @@ -57,18 +57,13 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpStringIteratorPrototype::next) auto* match_object = match.to_object(global_object); if (!match_object) return {}; - auto match_string_value = match_object->get(0); - if (vm.exception()) - return {}; + auto match_string_value = TRY_OR_DISCARD(match_object->get(0)); auto match_string = match_string_value.to_string(global_object); if (vm.exception()) return {}; if (match_string.is_empty()) { - auto last_index_value = iterator->regexp_object().get(vm.names.lastIndex); - if (vm.exception()) - return {}; - auto last_index = last_index_value.to_length(global_object); + auto last_index = TRY_OR_DISCARD(iterator->regexp_object().get(vm.names.lastIndex)).to_length(global_object); if (vm.exception()) return {}; diff --git a/Userland/Libraries/LibJS/Runtime/SetConstructor.cpp b/Userland/Libraries/LibJS/Runtime/SetConstructor.cpp index b6eca1b55c..cb17c57aa3 100644 --- a/Userland/Libraries/LibJS/Runtime/SetConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/SetConstructor.cpp @@ -54,9 +54,7 @@ Value SetConstructor::construct(FunctionObject& new_target) if (vm.argument(0).is_nullish()) return set; - auto adder = set->get(vm.names.add); - if (vm.exception()) - return {}; + auto adder = TRY_OR_DISCARD(set->get(vm.names.add)); if (!adder.is_function()) { vm.throw_exception<TypeError>(global_object, ErrorType::NotAFunction, "'add' property of Set"); return {}; diff --git a/Userland/Libraries/LibJS/Runtime/SetPrototype.cpp b/Userland/Libraries/LibJS/Runtime/SetPrototype.cpp index 7f68f48ee0..51d0cac479 100644 --- a/Userland/Libraries/LibJS/Runtime/SetPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/SetPrototype.cpp @@ -31,10 +31,10 @@ void SetPrototype::initialize(GlobalObject& global_object) define_native_function(vm.names.values, values, 0, attr); define_native_accessor(vm.names.size, size_getter, {}, Attribute::Configurable); - define_direct_property(vm.names.keys, get(vm.names.values), attr); + define_direct_property(vm.names.keys, get_without_side_effects(vm.names.values), attr); // 24.2.3.11 Set.prototype [ @@iterator ] ( ), https://tc39.es/ecma262/#sec-set.prototype-@@iterator - define_direct_property(*vm.well_known_symbol_iterator(), get(vm.names.values), attr); + define_direct_property(*vm.well_known_symbol_iterator(), get_without_side_effects(vm.names.values), attr); // 24.2.3.12 Set.prototype [ @@toStringTag ], https://tc39.es/ecma262/#sec-set.prototype-@@tostringtag define_direct_property(*vm.well_known_symbol_to_string_tag(), js_string(vm, vm.names.Set.as_string()), Attribute::Configurable); diff --git a/Userland/Libraries/LibJS/Runtime/StringConstructor.cpp b/Userland/Libraries/LibJS/Runtime/StringConstructor.cpp index 2689d6f3d3..7396373d87 100644 --- a/Userland/Libraries/LibJS/Runtime/StringConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/StringConstructor.cpp @@ -78,11 +78,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringConstructor::raw) if (vm.exception()) return {}; - auto raw_value = cooked->get(vm.names.raw); - if (vm.exception()) - return {}; - - auto* raw = raw_value.to_object(global_object); + auto* raw = TRY_OR_DISCARD(cooked->get(vm.names.raw)).to_object(global_object); if (vm.exception()) return {}; @@ -98,10 +94,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringConstructor::raw) StringBuilder builder; for (size_t i = 0; i < literal_segments; ++i) { auto next_key = String::number(i); - auto next_segment_value = raw->get(next_key); - if (vm.exception()) - return {}; - auto next_segment = next_segment_value.to_string(global_object); + auto next_segment = TRY_OR_DISCARD(raw->get(next_key)).to_string(global_object); if (vm.exception()) return {}; diff --git a/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp b/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp index 77b6bf9003..ec39baf1cd 100644 --- a/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp @@ -880,9 +880,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::match_all) if (!regexp.is_nullish()) { auto is_regexp = TRY_OR_DISCARD(regexp.is_regexp(global_object)); if (is_regexp) { - auto flags = regexp.as_object().get("flags"); - if (vm.exception()) - return {}; + auto flags = TRY_OR_DISCARD(regexp.as_object().get("flags")); auto flags_object = TRY_OR_DISCARD(require_object_coercible(global_object, flags)); auto flags_string = flags_object.to_string(global_object); if (vm.exception()) @@ -970,9 +968,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::replace_all) bool is_regexp = TRY_OR_DISCARD(search_value.is_regexp(global_object)); if (is_regexp) { - auto flags = search_value.as_object().get(vm.names.flags); - if (vm.exception()) - return {}; + auto flags = TRY_OR_DISCARD(search_value.as_object().get(vm.names.flags)); auto flags_object = TRY_OR_DISCARD(require_object_coercible(global_object, flags)); auto flags_string = flags_object.to_string(global_object); if (vm.exception()) diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/AbstractOperations.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/AbstractOperations.cpp index 4cb9c744c5..83f02c89ad 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/AbstractOperations.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/AbstractOperations.cpp @@ -113,9 +113,7 @@ ThrowCompletionOr<Value> get_option(GlobalObject& global_object, Object const& o // 2. Assert: Each element of types is Boolean, String, or Number. // 3. Let value be ? Get(options, property). - auto value = options.get(property); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto value = TRY(options.get(property)); // 4. If value is undefined, return fallback. if (value.is_undefined()) @@ -1051,9 +1049,7 @@ ThrowCompletionOr<Object*> prepare_temporal_fields(GlobalObject& global_object, // 3. For each value property of fieldNames, do for (auto& property : field_names) { // a. Let value be ? Get(fields, property). - auto value = fields.get(property); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto value = TRY(fields.get(property)); // b. If value is undefined, then if (value.is_undefined()) { diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/Calendar.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/Calendar.cpp index 1d060ae77a..d02c00a07d 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/Calendar.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/Calendar.cpp @@ -332,9 +332,7 @@ ThrowCompletionOr<Object*> to_temporal_calendar(GlobalObject& global_object, Val return &temporal_calendar_like_object; // c. Set temporalCalendarLike to ? Get(temporalCalendarLike, "calendar"). - temporal_calendar_like = temporal_calendar_like_object.get(vm.names.calendar); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + temporal_calendar_like = TRY(temporal_calendar_like_object.get(vm.names.calendar)); // d. If Type(temporalCalendarLike) is Object and ? HasProperty(temporalCalendarLike, "calendar") is false, return temporalCalendarLike. if (temporal_calendar_like.is_object()) { @@ -394,9 +392,7 @@ ThrowCompletionOr<Object*> get_temporal_calendar_with_iso_default(GlobalObject& return &static_cast<ZonedDateTime&>(item).calendar(); // 2. Let calendar be ? Get(item, "calendar"). - auto calendar = item.get(vm.names.calendar); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto calendar = TRY(item.get(vm.names.calendar)); // 3. Return ? ToTemporalCalendarWithISODefault(calendar). return to_temporal_calendar_with_iso_default(global_object, calendar); @@ -690,14 +686,10 @@ ThrowCompletionOr<double> resolve_iso_month(GlobalObject& global_object, Object auto& vm = global_object.vm(); // 1. Let month be ? Get(fields, "month"). - auto month = fields.get(vm.names.month); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto month = TRY(fields.get(vm.names.month)); // 2. Let monthCode be ? Get(fields, "monthCode"). - auto month_code = fields.get(vm.names.monthCode); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto month_code = TRY(fields.get(vm.names.monthCode)); // 3. If monthCode is undefined, then if (month_code.is_undefined()) { @@ -760,9 +752,7 @@ ThrowCompletionOr<ISODate> iso_date_from_fields(GlobalObject& global_object, Obj auto* prepared_fields = TRY(prepare_temporal_fields(global_object, fields, { "day", "month", "monthCode", "year" }, {})); // 4. Let year be ? Get(fields, "year"). - auto year = prepared_fields->get(vm.names.year); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto year = TRY(prepared_fields->get(vm.names.year)); // 5. If year is undefined, throw a TypeError exception. if (year.is_undefined()) @@ -772,9 +762,7 @@ ThrowCompletionOr<ISODate> iso_date_from_fields(GlobalObject& global_object, Obj auto month = TRY(resolve_iso_month(global_object, *prepared_fields)); // 7. Let day be ? Get(fields, "day"). - auto day = prepared_fields->get(vm.names.day); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto day = TRY(prepared_fields->get(vm.names.day)); // 8. If day is undefined, throw a TypeError exception. if (day.is_undefined()) @@ -798,9 +786,7 @@ ThrowCompletionOr<ISOYearMonth> iso_year_month_from_fields(GlobalObject& global_ auto* prepared_fields = TRY(prepare_temporal_fields(global_object, fields, { "month"sv, "monthCode"sv, "year"sv }, {})); // 4. Let year be ? Get(fields, "year"). - auto year = prepared_fields->get(vm.names.year); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto year = TRY(prepared_fields->get(vm.names.year)); // 5. If year is undefined, throw a TypeError exception. if (year.is_undefined()) @@ -830,19 +816,13 @@ ThrowCompletionOr<ISOMonthDay> iso_month_day_from_fields(GlobalObject& global_ob auto* prepared_fields = TRY(prepare_temporal_fields(global_object, fields, { "day"sv, "month"sv, "monthCode"sv, "year"sv }, {})); // 4. Let month be ? Get(fields, "month"). - auto month_value = prepared_fields->get(vm.names.month); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto month_value = TRY(prepared_fields->get(vm.names.month)); // 5. Let monthCode be ? Get(fields, "monthCode"). - auto month_code = prepared_fields->get(vm.names.monthCode); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto month_code = TRY(prepared_fields->get(vm.names.monthCode)); // 6. Let year be ? Get(fields, "year"). - auto year = prepared_fields->get(vm.names.year); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto year = TRY(prepared_fields->get(vm.names.year)); // 7. If month is not undefined, and monthCode and year are both undefined, then if (!month_value.is_undefined() && month_code.is_undefined() && year.is_undefined()) { @@ -854,9 +834,7 @@ ThrowCompletionOr<ISOMonthDay> iso_month_day_from_fields(GlobalObject& global_ob auto month = TRY(resolve_iso_month(global_object, *prepared_fields)); // 9. Let day be ? Get(fields, "day"). - auto day = prepared_fields->get(vm.names.day); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto day = TRY(prepared_fields->get(vm.names.day)); // 10. If day is undefined, throw a TypeError exception. if (day.is_undefined()) @@ -974,9 +952,7 @@ ThrowCompletionOr<Object*> default_merge_fields(GlobalObject& global_object, Obj auto property_name = PropertyName::from_value(global_object, next_key); // i. Let propValue be ? Get(fields, nextKey). - auto prop_value = fields.get(property_name); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto prop_value = TRY(fields.get(property_name)); // ii. If propValue is not undefined, then if (!prop_value.is_undefined()) { @@ -999,9 +975,7 @@ ThrowCompletionOr<Object*> default_merge_fields(GlobalObject& global_object, Obj auto property_name = PropertyName::from_value(global_object, next_key); // a. Let propValue be ? Get(additionalFields, nextKey). - auto prop_value = additional_fields.get(property_name); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto prop_value = TRY(additional_fields.get(property_name)); // b. If propValue is not undefined, then if (!prop_value.is_undefined()) { @@ -1016,9 +990,7 @@ ThrowCompletionOr<Object*> default_merge_fields(GlobalObject& global_object, Obj // 6. If newKeys does not contain either "month" or "monthCode", then if (!new_keys_contains_month_or_month_code_property) { // a. Let month be ? Get(fields, "month"). - auto month = fields.get(vm.names.month); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto month = TRY(fields.get(vm.names.month)); // b. If month is not undefined, then if (!month.is_undefined()) { @@ -1027,9 +999,7 @@ ThrowCompletionOr<Object*> default_merge_fields(GlobalObject& global_object, Obj } // c. Let monthCode be ? Get(fields, "monthCode"). - auto month_code = fields.get(vm.names.monthCode); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto month_code = TRY(fields.get(vm.names.monthCode)); // d. If monthCode is not undefined, then if (!month_code.is_undefined()) { diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/Duration.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/Duration.cpp index f045bad40e..695de3e7cb 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/Duration.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/Duration.cpp @@ -89,9 +89,7 @@ ThrowCompletionOr<TemporalDuration> to_temporal_duration_record(GlobalObject& gl // a. Let prop be the Property value of the current row. // b. Let val be ? Get(temporalDurationLike, prop). - auto value = temporal_duration_like.get(property); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto value = TRY(temporal_duration_like.get(property)); // c. If val is undefined, then if (value.is_undefined()) { @@ -194,9 +192,7 @@ ThrowCompletionOr<PartialDuration> to_partial_duration(GlobalObject& global_obje // a. Let property be the Property value of the current row. // b. Let value be ? Get(temporalDurationLike, property). - auto value = temporal_duration_like.as_object().get(property); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto value = TRY(temporal_duration_like.as_object().get(property)); // c. If value is not undefined, then if (!value.is_undefined()) { diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/InstantPrototype.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/InstantPrototype.cpp index d1007bba05..5761636a73 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/InstantPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/InstantPrototype.cpp @@ -373,9 +373,7 @@ JS_DEFINE_NATIVE_FUNCTION(InstantPrototype::to_string) auto* options = TRY_OR_DISCARD(get_options_object(global_object, vm.argument(0))); // 4. Let timeZone be ? Get(options, "timeZone"). - auto time_zone = options->get(vm.names.timeZone); - if (vm.exception()) - return {}; + auto time_zone = TRY_OR_DISCARD(options->get(vm.names.timeZone)); // 5. If timeZone is not undefined, then if (!time_zone.is_undefined()) { @@ -455,9 +453,7 @@ JS_DEFINE_NATIVE_FUNCTION(InstantPrototype::to_zoned_date_time) } // 4. Let calendarLike be ? Get(item, "calendar"). - auto calendar_like = item.as_object().get(vm.names.calendar); - if (vm.exception()) - return {}; + auto calendar_like = TRY_OR_DISCARD(item.as_object().get(vm.names.calendar)); // 5. If calendarLike is undefined, then if (calendar_like.is_undefined()) { @@ -470,9 +466,7 @@ JS_DEFINE_NATIVE_FUNCTION(InstantPrototype::to_zoned_date_time) auto* calendar = TRY_OR_DISCARD(to_temporal_calendar(global_object, calendar_like)); // 7. Let temporalTimeZoneLike be ? Get(item, "timeZone"). - auto temporal_time_zone_like = item.as_object().get(vm.names.timeZone); - if (vm.exception()) - return {}; + auto temporal_time_zone_like = TRY_OR_DISCARD(item.as_object().get(vm.names.timeZone)); // 8. If temporalTimeZoneLike is undefined, then if (temporal_time_zone_like.is_undefined()) { @@ -502,9 +496,7 @@ JS_DEFINE_NATIVE_FUNCTION(InstantPrototype::to_zoned_date_time_iso) // 3. If Type(item) is Object, then if (item.is_object()) { // a. Let timeZoneProperty be ? Get(item, "timeZone"). - auto time_zone_property = item.as_object().get(vm.names.timeZone); - if (vm.exception()) - return {}; + auto time_zone_property = TRY_OR_DISCARD(item.as_object().get(vm.names.timeZone)); // b. If timeZoneProperty is not undefined, then if (!time_zone_property.is_undefined()) { diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/PlainMonthDay.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/PlainMonthDay.cpp index fc6a7fb3ad..a70b448571 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/PlainMonthDay.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/PlainMonthDay.cpp @@ -81,9 +81,7 @@ ThrowCompletionOr<PlainMonthDay*> to_temporal_month_day(GlobalObject& global_obj calendar_absent = false; } else { // i. Let calendar be ? Get(item, "calendar"). - auto calendar_value = item_object.get(vm.names.calendar); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto calendar_value = TRY(item_object.get(vm.names.calendar)); // ii. If calendar is undefined, then // 1. Let calendarAbsent be true. @@ -102,19 +100,13 @@ ThrowCompletionOr<PlainMonthDay*> to_temporal_month_day(GlobalObject& global_obj auto* fields = TRY(prepare_temporal_fields(global_object, item_object, field_names, {})); // f. Let month be ? Get(fields, "month"). - auto month = fields->get(vm.names.month); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto month = TRY(fields->get(vm.names.month)); // g. Let monthCode be ? Get(fields, "monthCode"). - auto month_code = fields->get(vm.names.monthCode); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto month_code = TRY(fields->get(vm.names.monthCode)); // h. Let year be ? Get(fields, "year"). - auto year = fields->get(vm.names.year); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto year = TRY(fields->get(vm.names.year)); // i. If calendarAbsent is true, and month is not undefined, and monthCode is undefined and year is undefined, then if (calendar_absent && !month.is_undefined() && month_code.is_undefined() && year.is_undefined()) { diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/PlainTime.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/PlainTime.cpp index ab4d69853f..f146b5adf1 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/PlainTime.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/PlainTime.cpp @@ -140,9 +140,7 @@ ThrowCompletionOr<PartialUnregulatedTemporalTime> to_partial_time(GlobalObject& // a. Let property be the Property value of the current row. // b. Let value be ? Get(temporalTimeLike, property). - auto value = temporal_time_like.get(property); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto value = TRY(temporal_time_like.get(property)); // c. If value is not undefined, then if (!value.is_undefined()) { @@ -367,9 +365,7 @@ ThrowCompletionOr<UnregulatedTemporalTime> to_temporal_time_record(GlobalObject& // a. Let property be the Property value of the current row. // b. Let value be ? Get(temporalTimeLike, property). - auto value = temporal_time_like.get(property); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto value = TRY(temporal_time_like.get(property)); // c. If value is undefined, then if (value.is_undefined()) { diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/PlainTimePrototype.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/PlainTimePrototype.cpp index c04661b6c7..4f36f3c1f0 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/PlainTimePrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/PlainTimePrototype.cpp @@ -163,9 +163,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainTimePrototype::with) TRY_OR_DISCARD(reject_temporal_calendar_type(global_object, temporal_time_like)); // 5. Let calendarProperty be ? Get(temporalTimeLike, "calendar"). - auto calendar_property = temporal_time_like.get(vm.names.calendar); - if (vm.exception()) - return {}; + auto calendar_property = TRY_OR_DISCARD(temporal_time_like.get(vm.names.calendar)); // 6. If calendarProperty is not undefined, then if (!calendar_property.is_undefined()) { @@ -175,9 +173,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainTimePrototype::with) } // 7. Let timeZoneProperty be ? Get(temporalTimeLike, "timeZone"). - auto time_zone_property = temporal_time_like.get(vm.names.timeZone); - if (vm.exception()) - return {}; + auto time_zone_property = TRY_OR_DISCARD(temporal_time_like.get(vm.names.timeZone)); // 8. If timeZoneProperty is not undefined, then if (!time_zone_property.is_undefined()) { diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp index 8e6109736e..fab2b95374 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp @@ -333,9 +333,7 @@ ThrowCompletionOr<Object*> to_temporal_time_zone(GlobalObject& global_object, Va return &temporal_time_zone_like.as_object(); // c. Set temporalTimeZoneLike to ? Get(temporalTimeZoneLike, "timeZone"). - temporal_time_zone_like = temporal_time_zone_like.as_object().get(vm.names.timeZone); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + temporal_time_zone_like = TRY(temporal_time_zone_like.as_object().get(vm.names.timeZone)); // d. If Type(temporalTimeZoneLike) is Object and ? HasProperty(temporalTimeZoneLike, "timeZone") is false, return temporalTimeZoneLike. if (temporal_time_zone_like.is_object()) { diff --git a/Userland/Libraries/LibJS/Runtime/TypedArray.cpp b/Userland/Libraries/LibJS/Runtime/TypedArray.cpp index 7efde510bc..397441479a 100644 --- a/Userland/Libraries/LibJS/Runtime/TypedArray.cpp +++ b/Userland/Libraries/LibJS/Runtime/TypedArray.cpp @@ -192,9 +192,10 @@ static void initialize_typed_array_from_array_like(GlobalObject& global_object, typed_array.set_array_length(length); for (size_t k = 0; k < length; k++) { - auto value = array_like.get(k); - if (vm.exception()) + auto value_or_error = array_like.get(k); + if (value_or_error.is_error()) return; + auto value = value_or_error.release_value(); typed_array.set(k, value, Object::ShouldThrowExceptions::Yes); if (vm.exception()) return; diff --git a/Userland/Libraries/LibJS/Runtime/TypedArrayConstructor.cpp b/Userland/Libraries/LibJS/Runtime/TypedArrayConstructor.cpp index c39425548b..d34763479d 100644 --- a/Userland/Libraries/LibJS/Runtime/TypedArrayConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/TypedArrayConstructor.cpp @@ -114,9 +114,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayConstructor::from) return {}; for (size_t k = 0; k < length; ++k) { - auto k_value = array_like->get(k); - if (vm.exception()) - return {}; + auto k_value = TRY_OR_DISCARD(array_like->get(k)); Value mapped_value; if (map_fn) mapped_value = TRY_OR_DISCARD(vm.call(*map_fn, this_arg, k_value, Value(k))); diff --git a/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp b/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp index 58ec5e847f..a20b503352 100644 --- a/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp @@ -118,9 +118,10 @@ static void for_each_item(VM& vm, GlobalObject& global_object, const String& nam auto this_value = vm.argument(1); for (size_t i = 0; i < initial_length; ++i) { - auto value = typed_array->get(i); - if (vm.exception()) + auto value_or_error = typed_array->get(i); + if (value_or_error.is_error()) return; + auto value = value_or_error.release_value(); auto callback_result_or_error = vm.call(*callback_function, this_value, value, Value((i32)i), typed_array); if (callback_result_or_error.is_error()) @@ -147,9 +148,10 @@ static void for_each_item_from_last(VM& vm, GlobalObject& global_object, const S auto this_value = vm.argument(1); for (ssize_t i = (ssize_t)initial_length - 1; i >= 0; --i) { - auto value = typed_array->get(i); - if (vm.exception()) + auto value_or_error = typed_array->get(i); + if (value_or_error.is_error()) return; + auto value = value_or_error.release_value(); auto callback_result_or_error = vm.call(*callback_function, this_value, value, Value((i32)i), typed_array); if (callback_result_or_error.is_error()) @@ -225,7 +227,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::at) } if (index.has_overflow() || index.value() >= length) return js_undefined(); - return typed_array->get(index.value()); + return TRY_OR_DISCARD(typed_array->get(index.value())); } // 23.2.3.7 %TypedArray%.prototype.every ( callbackfn [ , thisArg ] ), https://tc39.es/ecma262/#sec-%typedarray%.prototype.every @@ -404,7 +406,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::includes) auto search_element = vm.argument(0); for (; k < length; ++k) { - auto element_k = typed_array->get(k); + auto element_k = MUST(typed_array->get(k)); if (same_value_zero(search_element, element_k)) return Value(true); @@ -449,7 +451,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::index_of) for (; k < length; ++k) { auto k_present = typed_array->has_property(k); if (k_present) { - auto element_k = typed_array->get(k); + auto element_k = MUST(typed_array->get(k)); if (is_strictly_equal(search_element, element_k)) return Value(k); @@ -497,7 +499,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::last_index_of) for (; k >= 0; --k) { auto k_present = typed_array->has_property(k); if (k_present) { - auto element_k = typed_array->get(k); + auto element_k = MUST(typed_array->get(k)); if (is_strictly_equal(search_element, element_k)) return Value(k); @@ -530,12 +532,12 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::reduce) if (vm.argument_count() > 1) { accumulator = vm.argument(1); } else { - accumulator = typed_array->get(k); + accumulator = MUST(typed_array->get(k)); ++k; } for (; k < length; ++k) { - auto k_value = typed_array->get(k); + auto k_value = MUST(typed_array->get(k)); accumulator = TRY_OR_DISCARD(vm.call(*callback_function, js_undefined(), accumulator, k_value, Value(k), typed_array)); } @@ -566,12 +568,12 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::reduce_right) if (vm.argument_count() > 1) { accumulator = vm.argument(1); } else { - accumulator = typed_array->get(k); + accumulator = MUST(typed_array->get(k)); --k; } for (; k >= 0; --k) { - auto k_value = typed_array->get(k); + auto k_value = MUST(typed_array->get(k)); accumulator = TRY_OR_DISCARD(vm.call(*callback_function, js_undefined(), accumulator, k_value, Value(k), typed_array)); } @@ -611,9 +613,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::join) for (size_t i = 0; i < length; ++i) { if (i > 0) builder.append(separator); - auto value = typed_array->get(i); - if (vm.exception()) - return {}; + auto value = TRY_OR_DISCARD(typed_array->get(i)); if (value.is_nullish()) continue; auto string = value.to_string(global_object); @@ -842,9 +842,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::set) auto limit = checked_limit.value(); auto k = 0; while (target_byte_index < limit) { - auto value = src->get(k); - if (vm.exception()) - return {}; + auto value = TRY_OR_DISCARD(src->get(k)); if (typed_array->content_type() == TypedArrayBase::ContentType::BigInt) value = value.to_bigint(global_object); else @@ -919,7 +917,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::slice) if (typed_array->element_name() != new_array->element_name()) { for (i32 n = 0; k < final; ++k, ++n) { - auto k_value = typed_array->get(k); + auto k_value = MUST(typed_array->get(k)); new_array->set(n, k_value, Object::ShouldThrowExceptions::Yes); } } else { @@ -1072,10 +1070,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::sort) return {}; if (k_present) { - auto k_value = typed_array->get(k); - if (vm.exception()) - return {}; - + auto k_value = TRY_OR_DISCARD(typed_array->get(k)); items.append(k_value); } } @@ -1178,11 +1173,11 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::reverse) // b. Let upperP be ! ToString(𝔽(upper)). // d. Let lowerValue be ! Get(O, lowerP). - auto lower_value = typed_array->get(lower); + auto lower_value = MUST(typed_array->get(lower)); // c. Let lowerP be ! ToString(𝔽(lower)). // e. Let upperValue be ! Get(O, upperP). - auto upper_value = typed_array->get(upper); + auto upper_value = MUST(typed_array->get(upper)); // f. Perform ! Set(O, lowerP, upperValue, true). typed_array->set(lower, upper_value, Object::ShouldThrowExceptions::Yes); @@ -1406,7 +1401,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::filter) for (size_t i = 0; i < initial_length; ++i) { // a. Let Pk be ! ToString(𝔽(k)). // b. Let kValue be ! Get(O, Pk). - auto value = typed_array->get(i); + auto value = MUST(typed_array->get(i)); // c. Let selected be ! ToBoolean(? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »)). auto callback_result = TRY_OR_DISCARD(vm.call(*callback_function, this_value, value, Value((i32)i), typed_array)).to_boolean(); @@ -1477,7 +1472,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::map) for (size_t i = 0; i < initial_length; ++i) { // a. Let Pk be ! ToString(𝔽(k)). // b. Let kValue be ! Get(O, Pk). - auto value = typed_array->get(i); + auto value = MUST(typed_array->get(i)); // c. Let mappedValue be ? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »). auto mapped_value = TRY_OR_DISCARD(vm.call(*callback_function, this_value, value, Value((i32)i), typed_array)); @@ -1507,9 +1502,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::to_locale_string) for (u32 k = 0; k < length; ++k) { if (k > 0) builder.append(','); // NOTE: Until we implement ECMA-402 (Intl) this is implementation specific. - auto value = typed_array->get(k); - if (vm.exception()) - return {}; + auto value = TRY_OR_DISCARD(typed_array->get(k)); if (value.is_nullish()) continue; auto locale_string_result = TRY_OR_DISCARD(value.invoke(global_object, vm.names.toLocaleString)); diff --git a/Userland/Libraries/LibJS/Runtime/VM.cpp b/Userland/Libraries/LibJS/Runtime/VM.cpp index 52d1472e78..b96f4fb77d 100644 --- a/Userland/Libraries/LibJS/Runtime/VM.cpp +++ b/Userland/Libraries/LibJS/Runtime/VM.cpp @@ -282,10 +282,7 @@ ThrowCompletionOr<void> VM::property_binding_initialization(BindingPattern const if (auto* thrown_exception = exception()) return JS::throw_completion(thrown_exception->value()); - auto value_to_assign = object->get(name); - if (auto* thrown_exception = exception()) - return JS::throw_completion(thrown_exception->value()); - + auto value_to_assign = TRY(object->get(name)); if (property.initializer && value_to_assign.is_undefined()) { value_to_assign = TRY(named_evaluation_if_anonymous_function(global_object, *property.initializer, identifier.string())); } @@ -312,10 +309,7 @@ ThrowCompletionOr<void> VM::property_binding_initialization(BindingPattern const if (auto* thrown_exception = exception()) return JS::throw_completion(thrown_exception->value()); - auto value_to_assign = object->get(name); - if (auto* thrown_exception = exception()) - return JS::throw_completion(thrown_exception->value()); - + auto value_to_assign = TRY(object->get(name)); if (property.initializer && value_to_assign.is_undefined()) { if (auto* identifier_ptr = property.alias.get_pointer<NonnullRefPtr<Identifier>>()) value_to_assign = TRY(named_evaluation_if_anonymous_function(global_object, *property.initializer, (*identifier_ptr)->string())); @@ -378,19 +372,13 @@ ThrowCompletionOr<void> VM::iterator_binding_initialization(BindingPattern const return JS::throw_completion(exception()->value()); } - auto done_property = next_object->get(names.done); - if (auto* thrown_exception = exception()) - return JS::throw_completion(thrown_exception->value()); - + auto done_property = TRY(next_object->get(names.done)); if (done_property.to_boolean()) { iterator_done = true; break; } - auto next_value = next_object->get(names.value); - if (auto* thrown_exception = exception()) - return JS::throw_completion(thrown_exception->value()); - + auto next_value = TRY(next_object->get(names.value)); array->indexed_properties().append(next_value); } value = array; @@ -403,19 +391,17 @@ ThrowCompletionOr<void> VM::iterator_binding_initialization(BindingPattern const return JS::throw_completion(exception()->value()); } - auto done_property = next_object->get(names.done); - if (auto* thrown_exception = exception()) - return JS::throw_completion(thrown_exception->value()); - + auto done_property = TRY(next_object->get(names.done)); if (done_property.to_boolean()) { iterator_done = true; value = js_undefined(); } else { - value = next_object->get(names.value); - if (auto* thrown_exception = exception()) { + auto value_or_error = next_object->get(names.value); + if (value_or_error.is_throw_completion()) { iterator_done = true; - return JS::throw_completion(thrown_exception->value()); + return JS::throw_completion(value_or_error.release_error().value()); } + value = value_or_error.release_value(); } } else { value = js_undefined(); @@ -574,9 +560,7 @@ Value VM::construct(FunctionObject& function, FunctionObject& new_target, Option && result.is_object()) { verify_cast<FunctionEnvironment>(constructor_environment)->replace_this_binding(result); - auto prototype = new_target.get(names.prototype); - if (exception()) - return {}; + auto prototype = TRY_OR_DISCARD(new_target.get(names.prototype)); if (prototype.is_object()) TRY_OR_DISCARD(result.as_object().internal_set_prototype_of(&prototype.as_object())); return result; diff --git a/Userland/Libraries/LibJS/Runtime/Value.cpp b/Userland/Libraries/LibJS/Runtime/Value.cpp index 17c5a32475..967f44a3f6 100644 --- a/Userland/Libraries/LibJS/Runtime/Value.cpp +++ b/Userland/Libraries/LibJS/Runtime/Value.cpp @@ -256,9 +256,7 @@ ThrowCompletionOr<bool> Value::is_regexp(GlobalObject& global_object) const return false; auto& vm = global_object.vm(); - auto matcher = as_object().get(*vm.well_known_symbol_match()); - if (vm.exception()) - return false; + auto matcher = TRY(as_object().get(*vm.well_known_symbol_match())); if (!matcher.is_undefined()) return matcher.to_boolean(); @@ -1325,10 +1323,7 @@ Value ordinary_has_instance(GlobalObject& global_object, Value lhs, Value rhs) return Value(false); Object* lhs_object = &lhs.as_object(); - auto rhs_prototype = rhs_function.get(vm.names.prototype); - if (vm.exception()) - return {}; - + auto rhs_prototype = TRY_OR_DISCARD(rhs_function.get(vm.names.prototype)); if (!rhs_prototype.is_object()) { vm.throw_exception<TypeError>(global_object, ErrorType::InstanceOfOperatorBadPrototype, rhs.to_string_without_side_effects()); return {}; diff --git a/Userland/Libraries/LibJS/Runtime/WeakMapConstructor.cpp b/Userland/Libraries/LibJS/Runtime/WeakMapConstructor.cpp index 23655100e7..5f844af019 100644 --- a/Userland/Libraries/LibJS/Runtime/WeakMapConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/WeakMapConstructor.cpp @@ -52,9 +52,7 @@ Value WeakMapConstructor::construct(FunctionObject& new_target) if (vm.argument(0).is_nullish()) return weak_map; - auto adder = weak_map->get(vm.names.set); - if (vm.exception()) - return {}; + auto adder = TRY_OR_DISCARD(weak_map->get(vm.names.set)); if (!adder.is_function()) { vm.throw_exception<TypeError>(global_object, ErrorType::NotAFunction, "'set' property of WeakMap"); return {}; @@ -66,12 +64,14 @@ Value WeakMapConstructor::construct(FunctionObject& new_target) vm.throw_exception<TypeError>(global_object, ErrorType::NotAnObject, String::formatted("Iterator value {}", iterator_value.to_string_without_side_effects())); return IterationDecision::Break; } - auto key = iterator_value.as_object().get(0); - if (vm.exception()) + auto key_or_error = iterator_value.as_object().get(0); + if (key_or_error.is_error()) return IterationDecision::Break; - auto value = iterator_value.as_object().get(1); - if (vm.exception()) + auto key = key_or_error.release_value(); + auto value_or_error = iterator_value.as_object().get(1); + if (value_or_error.is_error()) return IterationDecision::Break; + auto value = value_or_error.release_value(); auto result = vm.call(adder.as_function(), Value(weak_map), key, value); return result.is_error() ? IterationDecision::Break : IterationDecision::Continue; }); diff --git a/Userland/Libraries/LibJS/Runtime/WeakSetConstructor.cpp b/Userland/Libraries/LibJS/Runtime/WeakSetConstructor.cpp index d095528abc..2a5ae66689 100644 --- a/Userland/Libraries/LibJS/Runtime/WeakSetConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/WeakSetConstructor.cpp @@ -54,9 +54,7 @@ Value WeakSetConstructor::construct(FunctionObject& new_target) if (vm.argument(0).is_nullish()) return weak_set; - auto adder = weak_set->get(vm.names.add); - if (vm.exception()) - return {}; + auto adder = TRY_OR_DISCARD(weak_set->get(vm.names.add)); if (!adder.is_function()) { vm.throw_exception<TypeError>(global_object, ErrorType::NotAFunction, "'add' property of WeakSet"); return {}; diff --git a/Userland/Libraries/LibTest/JavaScriptTestRunner.h b/Userland/Libraries/LibTest/JavaScriptTestRunner.h index da826093d2..d7cb06a558 100644 --- a/Userland/Libraries/LibTest/JavaScriptTestRunner.h +++ b/Userland/Libraries/LibTest/JavaScriptTestRunner.h @@ -239,8 +239,7 @@ inline AK::Result<NonnullRefPtr<JS::SourceTextModule>, ParserError> parse_module inline Optional<JsonValue> get_test_results(JS::Interpreter& interpreter) { - auto results = interpreter.global_object().get("__TestResults__"); - VERIFY(!results.is_empty()); + auto results = MUST(interpreter.global_object().get("__TestResults__")); auto json_string = JS::JSONObject::stringify_impl(interpreter.global_object(), results, JS::js_undefined(), JS::js_undefined()); auto json = JsonValue::from_string(json_string); @@ -388,12 +387,11 @@ inline JSFileResult TestRunner::run_file_test(const String& test_path) JSFileResult file_result { test_path.substring(m_test_root.length() + 1, test_path.length() - m_test_root.length() - 1) }; // Collect logged messages - auto user_output = interpreter->global_object().get("__UserOutput__"); - VERIFY(!user_output.is_empty()); + auto user_output = MUST(interpreter->global_object().get("__UserOutput__")); auto& arr = user_output.as_array(); for (auto& entry : arr.indexed_properties()) { - auto message = arr.get(entry.index()); + auto message = MUST(arr.get(entry.index())); file_result.logged_messages.append(message.to_string_without_side_effects()); } diff --git a/Userland/Libraries/LibWeb/Bindings/NavigatorObject.cpp b/Userland/Libraries/LibWeb/Bindings/NavigatorObject.cpp index 3b83bd69d2..057dd0000c 100644 --- a/Userland/Libraries/LibWeb/Bindings/NavigatorObject.cpp +++ b/Userland/Libraries/LibWeb/Bindings/NavigatorObject.cpp @@ -28,7 +28,7 @@ void NavigatorObject::initialize(JS::GlobalObject& global_object) define_direct_property("appCodeName", js_string(heap, "Mozilla"), attr); define_direct_property("appName", js_string(heap, "Netscape"), attr); define_direct_property("appVersion", js_string(heap, "4.0"), attr); - define_direct_property("language", languages->get(0), attr); + define_direct_property("language", languages->get_without_side_effects(0), attr); define_direct_property("languages", languages, attr); define_direct_property("platform", js_string(heap, "SerenityOS"), attr); define_direct_property("product", js_string(heap, "Gecko"), attr); diff --git a/Userland/Libraries/LibWeb/Bindings/WindowObject.cpp b/Userland/Libraries/LibWeb/Bindings/WindowObject.cpp index b5264d8352..241b7f3320 100644 --- a/Userland/Libraries/LibWeb/Bindings/WindowObject.cpp +++ b/Userland/Libraries/LibWeb/Bindings/WindowObject.cpp @@ -609,21 +609,15 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::scroll) if (vm.exception()) return {}; - auto left = options->get("left"); - if (vm.exception()) - return {}; + auto left = TRY_OR_DISCARD(options->get("left")); if (!left.is_undefined()) x_value = left; - auto top = options->get("top"); - if (vm.exception()) - return {}; + auto top = TRY_OR_DISCARD(options->get("top")); if (!top.is_undefined()) y_value = top; - auto behavior_string_value = options->get("behavior"); - if (vm.exception()) - return {}; + auto behavior_string_value = TRY_OR_DISCARD(options->get("behavior")); if (!behavior_string_value.is_undefined()) behavior_string = behavior_string_value.to_string(global_object); if (vm.exception()) @@ -684,16 +678,12 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::scroll_by) options->set("behavior", JS::js_string(vm, "auto"), ShouldThrowExceptions::No); } - auto left_value = options->get("left"); - if (vm.exception()) - return {}; + auto left_value = TRY_OR_DISCARD(options->get("left")); auto left = left_value.to_double(global_object); if (vm.exception()) return {}; - auto top_value = options->get("top"); - if (vm.exception()) - return {}; + auto top_value = TRY_OR_DISCARD(options->get("top")); auto top = top_value.to_double(global_object); if (vm.exception()) return {}; @@ -705,9 +695,7 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::scroll_by) left = left + current_scroll_position.x(); top = top + current_scroll_position.y(); - auto behavior_string_value = options->get("behavior"); - if (vm.exception()) - return {}; + auto behavior_string_value = TRY_OR_DISCARD(options->get("behavior")); auto behavior_string = behavior_string_value.is_undefined() ? "auto" : behavior_string_value.to_string(global_object); if (vm.exception()) return {}; diff --git a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyMemoryConstructor.cpp b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyMemoryConstructor.cpp index deb27bd3bf..703bbd47b4 100644 --- a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyMemoryConstructor.cpp +++ b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyMemoryConstructor.cpp @@ -36,8 +36,8 @@ JS::Value WebAssemblyMemoryConstructor::construct(FunctionObject&) if (vm.exception()) return {}; - auto initial_value = descriptor->get_without_side_effects("initial"); - auto maximum_value = descriptor->get_without_side_effects("maximum"); + auto initial_value = TRY_OR_DISCARD(descriptor->get("initial")); + auto maximum_value = TRY_OR_DISCARD(descriptor->get("maximum")); if (initial_value.is_empty()) { vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "Number"); diff --git a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyObject.cpp b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyObject.cpp index e95333b82c..bc12fc8277 100644 --- a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyObject.cpp +++ b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyObject.cpp @@ -164,16 +164,18 @@ Result<size_t, JS::Value> WebAssemblyObject::instantiate_module(Wasm::Module con dbgln("Trying to resolve stuff because import object was specified"); for (const Wasm::Linker::Name& import_name : linker.unresolved_imports()) { dbgln("Trying to resolve {}::{}", import_name.module, import_name.name); - auto value = import_object->get(import_name.module); - if (vm.exception()) + auto value_or_error = import_object->get(import_name.module); + if (value_or_error.is_error()) break; + auto value = value_or_error.release_value(); auto object = value.to_object(global_object); if (vm.exception()) break; - auto import_ = object->get(import_name.name); - if (vm.exception()) + auto import_or_error = object->get(import_name.name); + if (import_or_error.is_error()) break; + auto import_ = import_or_error.release_value(); import_name.type.visit( [&](Wasm::TypeIndex index) { dbgln("Trying to resolve a function {}::{}, type index {}", import_name.module, import_name.name, index.value()); diff --git a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyTableConstructor.cpp b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyTableConstructor.cpp index 480d2dea51..cfe8b67d05 100644 --- a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyTableConstructor.cpp +++ b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyTableConstructor.cpp @@ -38,9 +38,7 @@ JS::Value WebAssemblyTableConstructor::construct(FunctionObject&) if (vm.exception()) return {}; - auto element_value = descriptor->get("element"); - if (vm.exception()) - return {}; + auto element_value = TRY_OR_DISCARD(descriptor->get("element")); if (!element_value.is_string()) { vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::InvalidHint, element_value.to_string_without_side_effects()); return {}; @@ -58,12 +56,8 @@ JS::Value WebAssemblyTableConstructor::construct(FunctionObject&) return {}; } - auto initial_value = descriptor->get("initial"); - if (vm.exception()) - return {}; - auto maximum_value = descriptor->get("maximum"); - if (vm.exception()) - return {}; + auto initial_value = TRY_OR_DISCARD(descriptor->get("initial")); + auto maximum_value = TRY_OR_DISCARD(descriptor->get("maximum")); auto initial = initial_value.to_u32(global_object); if (vm.exception()) @@ -82,12 +76,9 @@ JS::Value WebAssemblyTableConstructor::construct(FunctionObject&) return {}; } - auto value_value = descriptor->get("value"); - if (vm.exception()) - return {}; - + auto value_value = TRY_OR_DISCARD(descriptor->get("value")); auto reference_value = [&]() -> Optional<Wasm::Value> { - if (value_value.is_empty() || value_value.is_undefined()) + if (value_value.is_undefined()) return Wasm::Value(*reference_type, 0ull); return to_webassembly_value(value_value, *reference_type, global_object); diff --git a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyTablePrototype.cpp b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyTablePrototype.cpp index 614c132228..a88d800a35 100644 --- a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyTablePrototype.cpp +++ b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyTablePrototype.cpp @@ -38,7 +38,7 @@ JS_DEFINE_NATIVE_FUNCTION(WebAssemblyTablePrototype::grow) auto initial_size = table->elements().size(); auto value_value = vm.argument(1); auto reference_value = [&]() -> Optional<Wasm::Value> { - if (value_value.is_empty() || value_value.is_undefined()) + if (value_value.is_undefined()) return Wasm::Value(table->type().element_type(), 0ull); return to_webassembly_value(value_value, table->type().element_type(), global_object); @@ -111,7 +111,7 @@ JS_DEFINE_NATIVE_FUNCTION(WebAssemblyTablePrototype::set) auto value_value = vm.argument(1); auto reference_value = [&]() -> Optional<Wasm::Value> { - if (value_value.is_empty() || value_value.is_undefined()) + if (value_value.is_undefined()) return Wasm::Value(table->type().element_type(), 0ull); return to_webassembly_value(value_value, table->type().element_type(), global_object); diff --git a/Userland/Utilities/js.cpp b/Userland/Utilities/js.cpp index 9f4b900e85..2878f076a3 100644 --- a/Userland/Utilities/js.cpp +++ b/Userland/Utilities/js.cpp @@ -210,12 +210,13 @@ static void print_array(JS::Array& array, HashTable<JS::Object*>& seen_objects) bool first = true; for (auto it = array.indexed_properties().begin(false); it != array.indexed_properties().end(); ++it) { print_separator(first); - auto value = array.get(it.index()); + auto value_or_error = array.get(it.index()); // The V8 repl doesn't throw an exception here, and instead just // prints 'undefined'. We may choose to replicate that behavior in // the future, but for now lets just catch the error - if (vm->exception()) + if (value_or_error.is_error()) return; + auto value = value_or_error.release_value(); print_value(value, seen_objects); } if (!first) @@ -230,12 +231,13 @@ static void print_object(JS::Object& object, HashTable<JS::Object*>& seen_object for (auto& entry : object.indexed_properties()) { print_separator(first); out("\"\033[33;1m{}\033[0m\": ", entry.index()); - auto value = object.get(entry.index()); + auto value_or_error = object.get(entry.index()); // The V8 repl doesn't throw an exception here, and instead just // prints 'undefined'. We may choose to replicate that behavior in // the future, but for now lets just catch the error - if (vm->exception()) + if (value_or_error.is_error()) return; + auto value = value_or_error.release_value(); print_value(value, seen_objects); } for (auto& it : object.shape().property_table_ordered()) { @@ -286,7 +288,7 @@ static void print_regexp_object(JS::Object const& object, HashTable<JS::Object*> { auto& regexp_object = static_cast<JS::RegExpObject const&>(object); // Use RegExp.prototype.source rather than RegExpObject::pattern() so we get proper escaping - auto source = regexp_object.get("source").to_primitive_string(object.global_object())->string(); + auto source = regexp_object.get_without_side_effects("source").to_primitive_string(object.global_object())->string(); print_type("RegExp"); out(" \033[34;1m/{}/{}\033[0m", source, regexp_object.flags()); } |