From 4d8912a92b4378d34a06806b3126c8463bdbdcf5 Mon Sep 17 00:00:00 2001 From: Linus Groh Date: Tue, 12 Oct 2021 17:49:01 +0100 Subject: [PATCH] LibJS: Convert to_string() to ThrowCompletionOr Also update get_function_name() to use ThrowCompletionOr, but this is not a standard AO and should be refactored out of existence eventually. --- Meta/Lagom/Fuzzers/FuzzilliJs.cpp | 9 +-- .../LibWeb/WrapperGenerator.cpp | 32 +++++++---- Tests/LibJS/test-js.cpp | 4 +- Tests/LibWasm/test-wasm.cpp | 8 +-- Tests/LibWeb/test-web.cpp | 4 +- .../Spreadsheet/SpreadsheetModel.cpp | 2 +- Userland/Libraries/LibJS/AST.cpp | 12 ++-- .../LibJS/Runtime/AbstractOperations.cpp | 10 +--- .../Runtime/AggregateErrorConstructor.cpp | 4 +- .../LibJS/Runtime/ArrayPrototype.cpp | 15 ++--- .../LibJS/Runtime/DateConstructor.cpp | 4 +- .../LibJS/Runtime/ErrorConstructor.cpp | 8 +-- .../LibJS/Runtime/ErrorPrototype.cpp | 14 ++--- .../LibJS/Runtime/FunctionConstructor.cpp | 18 ++---- .../Libraries/LibJS/Runtime/GlobalObject.cpp | 32 +++-------- .../LibJS/Runtime/Intl/AbstractOperations.cpp | 4 +- .../Runtime/Intl/DisplayNamesPrototype.cpp | 4 +- .../LibJS/Runtime/Intl/LocaleConstructor.cpp | 6 +- .../Libraries/LibJS/Runtime/JSONObject.cpp | 15 ++--- .../LibJS/Runtime/NumberPrototype.cpp | 4 +- .../Libraries/LibJS/Runtime/PropertyName.h | 6 +- .../Libraries/LibJS/Runtime/RegExpObject.cpp | 9 +-- .../LibJS/Runtime/RegExpPrototype.cpp | 49 ++++------------ .../Runtime/RegExpStringIteratorPrototype.cpp | 5 +- .../LibJS/Runtime/StringConstructor.cpp | 9 +-- .../LibJS/Runtime/StringPrototype.cpp | 40 ++++--------- .../LibJS/Runtime/SymbolConstructor.cpp | 4 +- .../LibJS/Runtime/Temporal/Calendar.cpp | 30 +++------- .../Runtime/Temporal/CalendarConstructor.cpp | 4 +- .../Runtime/Temporal/CalendarPrototype.cpp | 4 +- .../LibJS/Runtime/Temporal/Duration.cpp | 10 +--- .../LibJS/Runtime/Temporal/Instant.cpp | 6 +- .../LibJS/Runtime/Temporal/PlainDate.cpp | 10 +--- .../LibJS/Runtime/Temporal/PlainDateTime.cpp | 10 +--- .../LibJS/Runtime/Temporal/PlainMonthDay.cpp | 6 +- .../LibJS/Runtime/Temporal/PlainTime.cpp | 8 +-- .../LibJS/Runtime/Temporal/PlainYearMonth.cpp | 10 +--- .../LibJS/Runtime/Temporal/TimeZone.cpp | 4 +- .../Runtime/Temporal/TimeZoneConstructor.cpp | 4 +- .../Runtime/Temporal/TimeZonePrototype.cpp | 4 +- .../LibJS/Runtime/TypedArrayPrototype.cpp | 15 ++--- Userland/Libraries/LibJS/Runtime/Value.cpp | 36 +++++------- Userland/Libraries/LibJS/Runtime/Value.h | 2 +- .../LibWeb/Bindings/CSSNamespace.cpp | 16 ++---- .../CSSStyleDeclarationWrapperCustom.cpp | 4 +- .../LibWeb/Bindings/LocationObject.cpp | 8 +-- .../LibWeb/Bindings/WindowObject.cpp | 56 +++++-------------- Userland/Utilities/js.cpp | 8 +-- 48 files changed, 171 insertions(+), 415 deletions(-) diff --git a/Meta/Lagom/Fuzzers/FuzzilliJs.cpp b/Meta/Lagom/Fuzzers/FuzzilliJs.cpp index 74754fb5c3..f66d95c028 100644 --- a/Meta/Lagom/Fuzzers/FuzzilliJs.cpp +++ b/Meta/Lagom/Fuzzers/FuzzilliJs.cpp @@ -141,10 +141,7 @@ JS_DEFINE_NATIVE_FUNCTION(TestRunnerGlobalObject::fuzzilli) if (!vm.argument_count()) return JS::js_undefined(); - auto operation = vm.argument(0).to_string(global_object); - if (vm.exception()) - return {}; - + auto operation = TRY_OR_DISCARD(vm.argument(0).to_string(global_object)); if (operation == "FUZZILLI_CRASH") { auto type = vm.argument(1).to_i32(global_object); if (vm.exception()) @@ -164,9 +161,7 @@ JS_DEFINE_NATIVE_FUNCTION(TestRunnerGlobalObject::fuzzilli) fzliout = stdout; } - auto string = vm.argument(1).to_string(global_object); - if (vm.exception()) - return {}; + auto string = TRY_OR_DISCARD(vm.argument(1).to_string(global_object)); fprintf(fzliout, "%s\n", string.characters()); fflush(fzliout); } diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator.cpp index c9e27c81b5..9260c1b5c3 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator.cpp @@ -906,19 +906,24 @@ static void generate_to_cpp(SourceGenerator& generator, ParameterType& parameter if (!optional) { if (!parameter.type.nullable) { scoped_generator.append(R"~~~( - auto @cpp_name@ = @js_name@@js_suffix@.is_null() && @legacy_null_to_empty_string@ - ? String::empty() - : @js_name@@js_suffix@.to_string(global_object); - if (vm.exception()) - @return_statement@ + String @cpp_name@; + if (@js_name@@js_suffix@.is_null() && @legacy_null_to_empty_string@) { + @cpp_name@ = String::empty(); + } else { + auto to_string_result = @js_name@@js_suffix@.to_string(global_object); + if (to_string_result.is_error()) + @return_statement@ + @cpp_name@ = to_string_result.release_value(); + } )~~~"); } else { scoped_generator.append(R"~~~( String @cpp_name@; if (!@js_name@@js_suffix@.is_nullish()) { - @cpp_name@ = @js_name@@js_suffix@.to_string(global_object); - if (vm.exception()) + auto to_string_result = @js_name@@js_suffix@.to_string(global_object); + if (to_string_result.is_error()) @return_statement@ + @cpp_name@ = to_string_result.release_value(); } )~~~"); } @@ -926,11 +931,14 @@ static void generate_to_cpp(SourceGenerator& generator, ParameterType& parameter scoped_generator.append(R"~~~( String @cpp_name@; if (!@js_name@@js_suffix@.is_undefined()) { - @cpp_name@ = @js_name@@js_suffix@.is_null() && @legacy_null_to_empty_string@ - ? String::empty() - : @js_name@@js_suffix@.to_string(global_object); - if (vm.exception()) - @return_statement@ + if (@js_name@@js_suffix@.is_null() && @legacy_null_to_empty_string@) { + @cpp_name@ = String::empty(); + } else { + auto to_string_result = @js_name@@js_suffix@.to_string(global_object); + if (to_string_result.is_error()) + @return_statement@ + @cpp_name@ = to_string_result.release_value(); + } })~~~"); if (optional_default_value.has_value() && (!parameter.type.nullable || optional_default_value.value() != "null")) { scoped_generator.append(R"~~~( else { diff --git a/Tests/LibJS/test-js.cpp b/Tests/LibJS/test-js.cpp index 6909de1617..de7b53156f 100644 --- a/Tests/LibJS/test-js.cpp +++ b/Tests/LibJS/test-js.cpp @@ -18,9 +18,7 @@ TESTJS_GLOBAL_FUNCTION(is_strict_mode, isStrictMode, 0) TESTJS_GLOBAL_FUNCTION(can_parse_source, canParseSource) { - auto source = vm.argument(0).to_string(global_object); - if (vm.exception()) - return {}; + auto source = TRY_OR_DISCARD(vm.argument(0).to_string(global_object)); auto parser = JS::Parser(JS::Lexer(source)); parser.parse_program(); return JS::Value(!parser.has_errors()); diff --git a/Tests/LibWasm/test-wasm.cpp b/Tests/LibWasm/test-wasm.cpp index 14ee45e604..8daf451312 100644 --- a/Tests/LibWasm/test-wasm.cpp +++ b/Tests/LibWasm/test-wasm.cpp @@ -13,9 +13,7 @@ TEST_ROOT("Userland/Libraries/LibWasm/Tests"); TESTJS_GLOBAL_FUNCTION(read_binary_wasm_file, readBinaryWasmFile) { - auto filename = vm.argument(0).to_string(global_object); - if (vm.exception()) - return {}; + auto filename = TRY_OR_DISCARD(vm.argument(0).to_string(global_object)); auto file = Core::File::open(filename, Core::OpenMode::ReadOnly); if (file.is_error()) { vm.throw_exception(global_object, file.error().string()); @@ -169,9 +167,7 @@ void WebAssemblyModule::initialize(JS::GlobalObject& global_object) JS_DEFINE_NATIVE_FUNCTION(WebAssemblyModule::get_export) { - auto name = vm.argument(0).to_string(global_object); - if (vm.exception()) - return {}; + auto name = TRY_OR_DISCARD(vm.argument(0).to_string(global_object)); auto this_value = vm.this_value(global_object); auto object = this_value.to_object(global_object); if (vm.exception()) diff --git a/Tests/LibWeb/test-web.cpp b/Tests/LibWeb/test-web.cpp index 531f009421..893adab262 100644 --- a/Tests/LibWeb/test-web.cpp +++ b/Tests/LibWeb/test-web.cpp @@ -40,9 +40,7 @@ TESTJS_MAIN_HOOK() TESTJS_GLOBAL_FUNCTION(load_local_page, loadLocalPage) { - auto name = vm.argument(0).to_string(global_object); - if (vm.exception()) - return {}; + auto name = TRY_OR_DISCARD(vm.argument(0).to_string(global_object)); // Clear the hooks before_initial_load_hooks.clear(); diff --git a/Userland/Applications/Spreadsheet/SpreadsheetModel.cpp b/Userland/Applications/Spreadsheet/SpreadsheetModel.cpp index 49e7e5bf04..986b992148 100644 --- a/Userland/Applications/Spreadsheet/SpreadsheetModel.cpp +++ b/Userland/Applications/Spreadsheet/SpreadsheetModel.cpp @@ -40,7 +40,7 @@ GUI::Variant SheetModel::data(const GUI::ModelIndex& index, GUI::ModelRole role) return builder.to_string(); } } - auto error = value.to_string(cell->sheet().global_object()); + auto error = value.to_string_without_side_effects(); // This is annoying, but whatever. cell->sheet().interpreter().vm().clear_exception(); diff --git a/Userland/Libraries/LibJS/AST.cpp b/Userland/Libraries/LibJS/AST.cpp index dc369506b0..52068f465c 100644 --- a/Userland/Libraries/LibJS/AST.cpp +++ b/Userland/Libraries/LibJS/AST.cpp @@ -73,7 +73,7 @@ static void update_function_name(Value value, FlyString const& name) static_cast(function).set_name(name); } -static String get_function_name(GlobalObject& global_object, Value value) +static ThrowCompletionOr get_function_name(GlobalObject& global_object, Value value) { if (value.is_symbol()) return String::formatted("[{}]", value.as_symbol().description()); @@ -1285,11 +1285,11 @@ ThrowCompletionOr ClassExpression::class_definition_evaluation(Interprete TRY(target.define_property_or_throw(property_key, { .value = method_value, .writable = true, .enumerable = false, .configurable = true })); break; case ClassMethod::Kind::Getter: - update_function_name(method_value, String::formatted("get {}", get_function_name(global_object, key))); + update_function_name(method_value, String::formatted("get {}", TRY(get_function_name(global_object, key)))); TRY(target.define_property_or_throw(property_key, { .get = &method_function, .enumerable = true, .configurable = true })); break; case ClassMethod::Kind::Setter: - update_function_name(method_value, String::formatted("set {}", get_function_name(global_object, key))); + update_function_name(method_value, String::formatted("set {}", TRY(get_function_name(global_object, key)))); TRY(target.define_property_or_throw(property_key, { .set = &method_function, .enumerable = true, .configurable = true })); break; default: @@ -2346,7 +2346,7 @@ Value ObjectExpression::execute(Interpreter& interpreter, GlobalObject& global_o if (value.is_function() && property.is_method()) static_cast(value.as_function()).set_home_object(object); - String name = get_function_name(global_object, key); + auto name = TRY_OR_DISCARD(get_function_name(global_object, key)); if (property.type() == ObjectProperty::Type::Getter) { name = String::formatted("get {}", name); } else if (property.type() == ObjectProperty::Type::Setter) { @@ -2640,9 +2640,7 @@ Value TemplateLiteral::execute(Interpreter& interpreter, GlobalObject& global_ob auto expr = expression.execute(interpreter, global_object); if (interpreter.exception()) return {}; - auto string = expr.to_string(global_object); - if (interpreter.exception()) - return {}; + auto string = TRY_OR_DISCARD(expr.to_string(global_object)); string_builder.append(string); } diff --git a/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp b/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp index 958786197c..0ae5327b40 100644 --- a/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp +++ b/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp @@ -929,10 +929,7 @@ ThrowCompletionOr get_substitution(GlobalObject& global_object, Utf16Vie auto& value = captures[*capture_position - 1]; if (!value.is_undefined()) { - auto value_string = value.to_string(global_object); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); - + auto value_string = TRY(value.to_string(global_object)); result.append(value_string); } @@ -960,10 +957,7 @@ ThrowCompletionOr get_substitution(GlobalObject& global_object, Utf16Vie auto capture = TRY(named_captures.as_object().get(group_name)); if (!capture.is_undefined()) { - auto capture_string = capture.to_string(global_object); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); - + auto capture_string = TRY(capture.to_string(global_object)); result.append(capture_string); } diff --git a/Userland/Libraries/LibJS/Runtime/AggregateErrorConstructor.cpp b/Userland/Libraries/LibJS/Runtime/AggregateErrorConstructor.cpp index 3e5e917137..511e9d798a 100644 --- a/Userland/Libraries/LibJS/Runtime/AggregateErrorConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/AggregateErrorConstructor.cpp @@ -45,9 +45,7 @@ Value AggregateErrorConstructor::construct(FunctionObject& new_target) auto* aggregate_error = TRY_OR_DISCARD(ordinary_create_from_constructor(global_object, new_target, &GlobalObject::aggregate_error_prototype)); if (!vm.argument(1).is_undefined()) { - auto message = vm.argument(1).to_string(global_object); - if (vm.exception()) - return {}; + auto message = TRY_OR_DISCARD(vm.argument(1).to_string(global_object)); MUST(aggregate_error->create_non_enumerable_data_property_or_throw(vm.names.message, js_string(vm, message))); } diff --git a/Userland/Libraries/LibJS/Runtime/ArrayPrototype.cpp b/Userland/Libraries/LibJS/Runtime/ArrayPrototype.cpp index 91458162c4..69750f46d5 100644 --- a/Userland/Libraries/LibJS/Runtime/ArrayPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/ArrayPrototype.cpp @@ -457,9 +457,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_locale_string) if (value.is_nullish()) continue; auto locale_string_result = TRY_OR_DISCARD(value.invoke(global_object, vm.names.toLocaleString)); - auto string = locale_string_result.to_string(global_object); - if (vm.exception()) - return {}; + auto string = TRY_OR_DISCARD(locale_string_result.to_string(global_object)); builder.append(string); } return js_string(vm, builder.to_string()); @@ -484,11 +482,8 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::join) auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *this_object)); String separator = ","; - if (!vm.argument(0).is_undefined()) { - separator = vm.argument(0).to_string(global_object); - if (vm.exception()) - return {}; - } + if (!vm.argument(0).is_undefined()) + separator = TRY_OR_DISCARD(vm.argument(0).to_string(global_object)); StringBuilder builder; for (size_t i = 0; i < length; ++i) { if (i > 0) @@ -496,9 +491,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::join) auto value = TRY_OR_DISCARD(this_object->get(i)); if (value.is_nullish()) continue; - auto string = value.to_string(global_object); - if (vm.exception()) - return {}; + auto string = TRY_OR_DISCARD(value.to_string(global_object)); builder.append(string); } diff --git a/Userland/Libraries/LibJS/Runtime/DateConstructor.cpp b/Userland/Libraries/LibJS/Runtime/DateConstructor.cpp index a5a52a99ad..b6ccf94d0d 100644 --- a/Userland/Libraries/LibJS/Runtime/DateConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/DateConstructor.cpp @@ -319,9 +319,7 @@ JS_DEFINE_NATIVE_FUNCTION(DateConstructor::parse) if (!vm.argument_count()) return js_nan(); - auto date_string = vm.argument(0).to_string(global_object); - if (vm.exception()) - return {}; + auto date_string = TRY_OR_DISCARD(vm.argument(0).to_string(global_object)); return parse_date_string(date_string); } diff --git a/Userland/Libraries/LibJS/Runtime/ErrorConstructor.cpp b/Userland/Libraries/LibJS/Runtime/ErrorConstructor.cpp index c108374734..1f0ed8a418 100644 --- a/Userland/Libraries/LibJS/Runtime/ErrorConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/ErrorConstructor.cpp @@ -42,9 +42,7 @@ Value ErrorConstructor::construct(FunctionObject& new_target) auto* error = TRY_OR_DISCARD(ordinary_create_from_constructor(global_object, new_target, &GlobalObject::error_prototype)); if (!vm.argument(0).is_undefined()) { - auto message = vm.argument(0).to_string(global_object); - if (vm.exception()) - return {}; + auto message = TRY_OR_DISCARD(vm.argument(0).to_string(global_object)); MUST(error->create_non_enumerable_data_property_or_throw(vm.names.message, js_string(vm, message))); } @@ -89,9 +87,7 @@ Value ErrorConstructor::construct(FunctionObject& new_target) global_object, new_target, &GlobalObject::snake_name##_prototype)); \ \ if (!vm.argument(0).is_undefined()) { \ - auto message = vm.argument(0).to_string(global_object); \ - if (vm.exception()) \ - return {}; \ + auto message = TRY_OR_DISCARD(vm.argument(0).to_string(global_object)); \ MUST(error->create_non_enumerable_data_property_or_throw(vm.names.message, js_string(vm, message))); \ } \ \ diff --git a/Userland/Libraries/LibJS/Runtime/ErrorPrototype.cpp b/Userland/Libraries/LibJS/Runtime/ErrorPrototype.cpp index fc4af4f8b4..57aa578b61 100644 --- a/Userland/Libraries/LibJS/Runtime/ErrorPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/ErrorPrototype.cpp @@ -41,19 +41,13 @@ JS_DEFINE_NATIVE_FUNCTION(ErrorPrototype::to_string) String name = "Error"; 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()) - return {}; - } + if (!name_property.is_undefined()) + name = TRY_OR_DISCARD(name_property.to_string(global_object)); String message = ""; 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()) - return {}; - } + if (!message_property.is_undefined()) + message = TRY_OR_DISCARD(message_property.to_string(global_object)); if (name.is_empty()) return js_string(vm, message); diff --git a/Userland/Libraries/LibJS/Runtime/FunctionConstructor.cpp b/Userland/Libraries/LibJS/Runtime/FunctionConstructor.cpp index b916a2e13c..9a343d3529 100644 --- a/Userland/Libraries/LibJS/Runtime/FunctionConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/FunctionConstructor.cpp @@ -41,24 +41,16 @@ RefPtr FunctionConstructor::create_dynamic_function_node(Glo auto& vm = global_object.vm(); String parameters_source = ""; String body_source = ""; - if (vm.argument_count() == 1) { - body_source = vm.argument(0).to_string(global_object); - if (vm.exception()) - return {}; - } + if (vm.argument_count() == 1) + body_source = TRY_OR_DISCARD(vm.argument(0).to_string(global_object)); if (vm.argument_count() > 1) { Vector parameters; - for (size_t i = 0; i < vm.argument_count() - 1; ++i) { - parameters.append(vm.argument(i).to_string(global_object)); - if (vm.exception()) - return {}; - } + for (size_t i = 0; i < vm.argument_count() - 1; ++i) + parameters.append(TRY_OR_DISCARD(vm.argument(i).to_string(global_object))); StringBuilder parameters_builder; parameters_builder.join(',', parameters); parameters_source = parameters_builder.build(); - body_source = vm.argument(vm.argument_count() - 1).to_string(global_object); - if (vm.exception()) - return {}; + body_source = TRY_OR_DISCARD(vm.argument(vm.argument_count() - 1).to_string(global_object)); } auto is_generator = kind == FunctionKind::Generator; auto source = String::formatted("function{} anonymous({}\n) {{\n{}\n}}", is_generator ? "*" : "", parameters_source, body_source); diff --git a/Userland/Libraries/LibJS/Runtime/GlobalObject.cpp b/Userland/Libraries/LibJS/Runtime/GlobalObject.cpp index 2a2b7791d7..6a95a69de3 100644 --- a/Userland/Libraries/LibJS/Runtime/GlobalObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/GlobalObject.cpp @@ -347,9 +347,7 @@ JS_DEFINE_NATIVE_FUNCTION(GlobalObject::parse_float) { if (vm.argument(0).is_number()) return vm.argument(0); - auto input_string = vm.argument(0).to_string(global_object); - if (vm.exception()) - return {}; + auto input_string = TRY_OR_DISCARD(vm.argument(0).to_string(global_object)); auto trimmed_string = input_string.trim_whitespace(TrimMode::Left); for (size_t length = trimmed_string.length(); length > 0; --length) { // This can't throw, so no exception check is fine. @@ -363,9 +361,7 @@ JS_DEFINE_NATIVE_FUNCTION(GlobalObject::parse_float) // 19.2.5 parseInt ( string, radix ), https://tc39.es/ecma262/#sec-parseint-string-radix JS_DEFINE_NATIVE_FUNCTION(GlobalObject::parse_int) { - auto input_string = vm.argument(0).to_string(global_object); - if (vm.exception()) - return {}; + auto input_string = TRY_OR_DISCARD(vm.argument(0).to_string(global_object)); // FIXME: There's a bunch of unnecessary string copying here. double sign = 1; @@ -500,9 +496,7 @@ static String decode(JS::GlobalObject& global_object, const String& string, Stri // 19.2.6.4 encodeURI ( uri ), https://tc39.es/ecma262/#sec-encodeuri-uri JS_DEFINE_NATIVE_FUNCTION(GlobalObject::encode_uri) { - auto uri_string = vm.argument(0).to_string(global_object); - if (vm.exception()) - return {}; + auto uri_string = TRY_OR_DISCARD(vm.argument(0).to_string(global_object)); auto encoded = encode(global_object, uri_string, ";/?:@&=+$,abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.!~*'()#"sv); if (vm.exception()) return {}; @@ -512,9 +506,7 @@ JS_DEFINE_NATIVE_FUNCTION(GlobalObject::encode_uri) // 19.2.6.2 decodeURI ( encodedURI ), https://tc39.es/ecma262/#sec-decodeuri-encodeduri JS_DEFINE_NATIVE_FUNCTION(GlobalObject::decode_uri) { - auto uri_string = vm.argument(0).to_string(global_object); - if (vm.exception()) - return {}; + auto uri_string = TRY_OR_DISCARD(vm.argument(0).to_string(global_object)); auto decoded = decode(global_object, uri_string, ";/?:@&=+$,#"sv); if (vm.exception()) return {}; @@ -524,9 +516,7 @@ JS_DEFINE_NATIVE_FUNCTION(GlobalObject::decode_uri) // 19.2.6.5 encodeURIComponent ( uriComponent ), https://tc39.es/ecma262/#sec-encodeuricomponent-uricomponent JS_DEFINE_NATIVE_FUNCTION(GlobalObject::encode_uri_component) { - auto uri_string = vm.argument(0).to_string(global_object); - if (vm.exception()) - return {}; + auto uri_string = TRY_OR_DISCARD(vm.argument(0).to_string(global_object)); auto encoded = encode(global_object, uri_string, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.!~*'()"sv); if (vm.exception()) return {}; @@ -536,9 +526,7 @@ JS_DEFINE_NATIVE_FUNCTION(GlobalObject::encode_uri_component) // 19.2.6.3 decodeURIComponent ( encodedURIComponent ), https://tc39.es/ecma262/#sec-decodeuricomponent-encodeduricomponent JS_DEFINE_NATIVE_FUNCTION(GlobalObject::decode_uri_component) { - auto uri_string = vm.argument(0).to_string(global_object); - if (vm.exception()) - return {}; + auto uri_string = TRY_OR_DISCARD(vm.argument(0).to_string(global_object)); auto decoded = decode(global_object, uri_string, ""sv); if (vm.exception()) return {}; @@ -548,9 +536,7 @@ JS_DEFINE_NATIVE_FUNCTION(GlobalObject::decode_uri_component) // B.2.1.1 escape ( string ), https://tc39.es/ecma262/#sec-escape-string JS_DEFINE_NATIVE_FUNCTION(GlobalObject::escape) { - auto string = vm.argument(0).to_string(global_object); - if (vm.exception()) - return {}; + auto string = TRY_OR_DISCARD(vm.argument(0).to_string(global_object)); StringBuilder escaped; for (auto code_point : Utf8View(string)) { if (code_point < 256) { @@ -568,9 +554,7 @@ JS_DEFINE_NATIVE_FUNCTION(GlobalObject::escape) // B.2.1.2 unescape ( string ), https://tc39.es/ecma262/#sec-unescape-string JS_DEFINE_NATIVE_FUNCTION(GlobalObject::unescape) { - auto string = vm.argument(0).to_string(global_object); - if (vm.exception()) - return {}; + auto string = TRY_OR_DISCARD(vm.argument(0).to_string(global_object)); ssize_t length = string.length(); StringBuilder unescaped(length); for (auto k = 0; k < length; ++k) { diff --git a/Userland/Libraries/LibJS/Runtime/Intl/AbstractOperations.cpp b/Userland/Libraries/LibJS/Runtime/Intl/AbstractOperations.cpp index 2561c7e0fd..3343b78271 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/AbstractOperations.cpp +++ b/Userland/Libraries/LibJS/Runtime/Intl/AbstractOperations.cpp @@ -246,9 +246,7 @@ ThrowCompletionOr> canonicalize_locale_list(GlobalObject& global_ // iv. Else, else { // 1. Let tag be ? ToString(kValue). - tag = key_value.to_string(global_object); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + tag = TRY(key_value.to_string(global_object)); } // v. If IsStructurallyValidLanguageTag(tag) is false, throw a RangeError exception. diff --git a/Userland/Libraries/LibJS/Runtime/Intl/DisplayNamesPrototype.cpp b/Userland/Libraries/LibJS/Runtime/Intl/DisplayNamesPrototype.cpp index 5fd699a33e..907574edfb 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/DisplayNamesPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/Intl/DisplayNamesPrototype.cpp @@ -44,9 +44,7 @@ JS_DEFINE_NATIVE_FUNCTION(DisplayNamesPrototype::of) return {}; // 3. Let code be ? ToString(code). - auto code_string = code.to_string(global_object); - if (vm.exception()) - return {}; + auto code_string = TRY_OR_DISCARD(code.to_string(global_object)); code = js_string(vm, move(code_string)); // 4. Let code be ? CanonicalCodeForDisplayNames(displayNames.[[Type]], code). diff --git a/Userland/Libraries/LibJS/Runtime/Intl/LocaleConstructor.cpp b/Userland/Libraries/LibJS/Runtime/Intl/LocaleConstructor.cpp index e6e1ae778b..b93a0ff94c 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/LocaleConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/Intl/LocaleConstructor.cpp @@ -292,9 +292,7 @@ Value LocaleConstructor::construct(FunctionObject& new_target) // 9. Else, else { // a. Let tag be ? ToString(tag). - tag = tag_value.to_string(global_object); - if (vm.exception()) - return {}; + tag = TRY_OR_DISCARD(tag_value.to_string(global_object)); } // 10. Set options to ? CoerceOptionsToObject(options). @@ -343,7 +341,7 @@ Value LocaleConstructor::construct(FunctionObject& new_target) // 24. If kn is not undefined, set kn to ! ToString(kn). // 25. Set opt.[[kn]] to kn. if (!kn.is_undefined()) - opt.kn = kn.to_string(global_object); + opt.kn = TRY_OR_DISCARD(kn.to_string(global_object)); // 26. Let numberingSystem be ? GetOption(options, "numberingSystem", "string", undefined, undefined). // 27. If numberingSystem is not undefined, then diff --git a/Userland/Libraries/LibJS/Runtime/JSONObject.cpp b/Userland/Libraries/LibJS/Runtime/JSONObject.cpp index dd55f0bb71..25700a74f2 100644 --- a/Userland/Libraries/LibJS/Runtime/JSONObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/JSONObject.cpp @@ -65,14 +65,11 @@ String JSONObject::stringify_impl(GlobalObject& global_object, Value value, Valu if (replacer_value.is_string()) { item = replacer_value.as_string().string(); } else if (replacer_value.is_number()) { - item = replacer_value.to_string(global_object); + item = MUST(replacer_value.to_string(global_object)); } else if (replacer_value.is_object()) { auto& value_object = replacer_value.as_object(); - if (is(value_object) || is(value_object)) { - item = replacer_value.to_string(global_object); - if (vm.exception()) - return {}; - } + if (is(value_object) || is(value_object)) + item = TRY_OR_DISCARD(replacer_value.to_string(global_object)); } if (!item.is_null() && !list.contains_slow(item)) { list.append(item); @@ -178,7 +175,7 @@ String JSONObject::serialize_json_property(GlobalObject& global_object, Stringif return quote_json_string(value.as_string().string()); if (value.is_number()) { if (value.is_finite_number()) - return value.to_string(global_object); + return MUST(value.to_string(global_object)); return "null"; } if (value.is_bigint()) { @@ -392,9 +389,7 @@ String JSONObject::quote_json_string(String string) // 25.5.1 JSON.parse ( text [ , reviver ] ), https://tc39.es/ecma262/#sec-json.parse JS_DEFINE_NATIVE_FUNCTION(JSONObject::parse) { - auto string = vm.argument(0).to_string(global_object); - if (vm.exception()) - return {}; + auto string = TRY_OR_DISCARD(vm.argument(0).to_string(global_object)); auto reviver = vm.argument(1); auto json = JsonValue::from_string(string); diff --git a/Userland/Libraries/LibJS/Runtime/NumberPrototype.cpp b/Userland/Libraries/LibJS/Runtime/NumberPrototype.cpp index 031dd768c0..57309411ba 100644 --- a/Userland/Libraries/LibJS/Runtime/NumberPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/NumberPrototype.cpp @@ -78,11 +78,11 @@ JS_DEFINE_NATIVE_FUNCTION(NumberPrototype::to_fixed) } if (!number_value.is_finite_number()) - return js_string(vm, number_value.to_string(global_object)); + return js_string(vm, TRY_OR_DISCARD(number_value.to_string(global_object))); auto number = number_value.as_double(); if (fabs(number) >= 1e+21) - return js_string(vm, number_value.to_string(global_object)); + return js_string(vm, MUST(number_value.to_string(global_object))); return js_string(vm, String::formatted("{:0.{1}}", number, static_cast(fraction_digits))); } diff --git a/Userland/Libraries/LibJS/Runtime/PropertyName.h b/Userland/Libraries/LibJS/Runtime/PropertyName.h index c777fc3a3d..2bbb606033 100644 --- a/Userland/Libraries/LibJS/Runtime/PropertyName.h +++ b/Userland/Libraries/LibJS/Runtime/PropertyName.h @@ -7,6 +7,7 @@ #pragma once #include +#include #include namespace JS { @@ -33,10 +34,7 @@ public: return value.as_symbol(); if (value.is_integral_number() && value.as_double() >= 0 && value.as_double() < NumericLimits::max()) return value.as_u32(); - auto string = value.to_string(global_object); - if (string.is_null()) - return {}; - return string; + return TRY_OR_DISCARD(value.to_string(global_object)); } PropertyName() { } diff --git a/Userland/Libraries/LibJS/Runtime/RegExpObject.cpp b/Userland/Libraries/LibJS/Runtime/RegExpObject.cpp index 4352ef518c..60a798e5ee 100644 --- a/Userland/Libraries/LibJS/Runtime/RegExpObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/RegExpObject.cpp @@ -148,9 +148,7 @@ RegExpObject* RegExpObject::regexp_initialize(GlobalObject& global_object, Value if (flags.is_undefined()) { f = String::empty(); } else { - f = flags.to_string(global_object); - if (vm.exception()) - return {}; + f = TRY_OR_DISCARD(flags.to_string(global_object)); } String original_pattern; @@ -160,10 +158,7 @@ RegExpObject* RegExpObject::regexp_initialize(GlobalObject& global_object, Value original_pattern = String::empty(); parsed_pattern = String::empty(); } else { - original_pattern = pattern.to_string(global_object); - if (vm.exception()) - return {}; - + original_pattern = TRY_OR_DISCARD(pattern.to_string(global_object)); bool unicode = f.find('u').has_value(); parsed_pattern = parse_regex_pattern(original_pattern, unicode); } diff --git a/Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp b/Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp index 8a0bf65fdb..ec4fd53561 100644 --- a/Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp @@ -377,14 +377,10 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::to_string) 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 pattern = TRY_OR_DISCARD(source_attr.to_string(global_object)); auto flags_attr = TRY_OR_DISCARD(regexp_object->get(vm.names.flags)); - auto flags = flags_attr.to_string(global_object); - if (vm.exception()) - return {}; + auto flags = TRY_OR_DISCARD(flags_attr.to_string(global_object)); return js_string(vm, String::formatted("/{}/{}", pattern, flags)); } @@ -434,9 +430,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_match) if (!result_object) return {}; auto match_object = TRY_OR_DISCARD(result_object->get(0)); - auto match_str = match_object.to_string(global_object); - if (vm.exception()) - return {}; + auto match_str = TRY_OR_DISCARD(match_object.to_string(global_object)); TRY_OR_DISCARD(array->create_data_property_or_throw(n, js_string(vm, match_str))); @@ -460,9 +454,8 @@ 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 = TRY_OR_DISCARD(regexp_object->get(vm.names.flags)).to_string(global_object); - if (vm.exception()) - return {}; + auto flags_value = TRY_OR_DISCARD(regexp_object->get(vm.names.flags)); + auto flags = TRY_OR_DISCARD(flags_value.to_string(global_object)); bool global = flags.find('g').has_value(); bool unicode = flags.find('u').has_value(); @@ -501,13 +494,8 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_replace) auto string_view = string.view(); if (!replace_value.is_function()) { - auto replace_string = replace_value.to_string(global_object); - if (vm.exception()) - return {}; - + auto replace_string = TRY_OR_DISCARD(replace_value.to_string(global_object)); replace_value = js_string(vm, move(replace_string)); - if (vm.exception()) - return {}; } bool global = TRY_OR_DISCARD(regexp_object->get(vm.names.global)).to_boolean(); @@ -537,9 +525,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_replace) break; auto match_object = TRY_OR_DISCARD(result_object->get(0)); - String match_str = match_object.to_string(global_object); - if (vm.exception()) - return {}; + auto match_str = TRY_OR_DISCARD(match_object.to_string(global_object)); if (match_str.is_empty()) TRY_OR_DISCARD(increment_last_index(global_object, *regexp_object, string_view, unicode)); @@ -569,15 +555,8 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_replace) MarkedValueList captures(vm.heap()); for (size_t n = 1; n <= n_captures; ++n) { auto capture = TRY_OR_DISCARD(result.get(n)); - if (!capture.is_undefined()) { - auto capture_string = capture.to_string(global_object); - if (vm.exception()) - return {}; - - capture = Value(js_string(vm, capture_string)); - if (vm.exception()) - return {}; - } + if (!capture.is_undefined()) + capture = js_string(vm, TRY_OR_DISCARD(capture.to_string(global_object))); captures.append(move(capture)); } @@ -597,10 +576,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_replace) } auto replace_result = TRY_OR_DISCARD(vm.call(replace_value.as_function(), js_undefined(), move(replacer_args))); - - replacement = replace_result.to_string(global_object); - if (vm.exception()) - return {}; + replacement = TRY_OR_DISCARD(replace_result.to_string(global_object)); } else { auto named_captures_object = js_undefined(); if (!named_captures.is_undefined()) { @@ -677,9 +653,8 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_split) auto* constructor = TRY_OR_DISCARD(species_constructor(global_object, *regexp_object, *global_object.regexp_constructor())); - auto flags = TRY_OR_DISCARD(regexp_object->get(vm.names.flags)).to_string(global_object); - if (vm.exception()) - return {}; + auto flags_value = TRY_OR_DISCARD(regexp_object->get(vm.names.flags)); + auto flags = TRY_OR_DISCARD(flags_value.to_string(global_object)); bool unicode = flags.find('u').has_value(); auto new_flags = flags.find('y').has_value() ? move(flags) : String::formatted("{}y", flags); diff --git a/Userland/Libraries/LibJS/Runtime/RegExpStringIteratorPrototype.cpp b/Userland/Libraries/LibJS/Runtime/RegExpStringIteratorPrototype.cpp index 57d9b22adb..d4dbf0d783 100644 --- a/Userland/Libraries/LibJS/Runtime/RegExpStringIteratorPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/RegExpStringIteratorPrototype.cpp @@ -58,10 +58,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpStringIteratorPrototype::next) if (!match_object) 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 {}; - + auto match_string = TRY_OR_DISCARD(match_string_value.to_string(global_object)); if (match_string.is_empty()) { auto last_index = TRY_OR_DISCARD(iterator->regexp_object().get(vm.names.lastIndex)).to_length(global_object); if (vm.exception()) diff --git a/Userland/Libraries/LibJS/Runtime/StringConstructor.cpp b/Userland/Libraries/LibJS/Runtime/StringConstructor.cpp index 7396373d87..74d79441dc 100644 --- a/Userland/Libraries/LibJS/Runtime/StringConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/StringConstructor.cpp @@ -94,9 +94,8 @@ 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 = TRY_OR_DISCARD(raw->get(next_key)).to_string(global_object); - if (vm.exception()) - return {}; + auto next_segment_value = TRY_OR_DISCARD(raw->get(next_key)); + auto next_segment = TRY_OR_DISCARD(next_segment_value.to_string(global_object)); builder.append(next_segment); @@ -105,9 +104,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringConstructor::raw) if (i < number_of_substituions) { auto next = vm.argument(i + 1); - auto next_sub = next.to_string(global_object); - if (vm.exception()) - return {}; + auto next_sub = TRY_OR_DISCARD(next.to_string(global_object)); builder.append(next_sub); } } diff --git a/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp b/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp index 96fb18ce5d..a505eb0ade 100644 --- a/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp @@ -31,7 +31,7 @@ namespace JS { static Optional ak_string_from(VM& vm, GlobalObject& global_object) { auto this_value = TRY_OR_DISCARD(require_object_coercible(global_object, vm.this_value(global_object))); - return this_value.to_string(global_object); + return TRY_OR_DISCARD(this_value.to_string(global_object)); } static Utf16String utf16_string_from(VM& vm, GlobalObject& global_object) @@ -564,9 +564,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::concat) StringBuilder builder; builder.append(*string); for (size_t i = 0; i < vm.argument_count(); ++i) { - auto string_argument = vm.argument(i).to_string(global_object); - if (vm.exception()) - return {}; + auto string_argument = TRY_OR_DISCARD(vm.argument(i).to_string(global_object)); builder.append(string_argument); } return js_string(vm, builder.to_string()); @@ -846,9 +844,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::at) JS_DEFINE_NATIVE_FUNCTION(StringPrototype::symbol_iterator) { auto this_object = TRY_OR_DISCARD(require_object_coercible(global_object, vm.this_value(global_object))); - auto string = this_object.to_string(global_object); - if (vm.exception()) - return {}; + auto string = TRY_OR_DISCARD(this_object.to_string(global_object)); return StringIterator::create(global_object, string); } @@ -882,9 +878,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::match_all) if (is_regexp) { 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()) - return {}; + auto flags_string = TRY_OR_DISCARD(flags_object.to_string(global_object)); if (!flags_string.contains("g")) { vm.throw_exception(global_object, ErrorType::StringNonGlobalRegExp); return {}; @@ -941,10 +935,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::replace) if (replace_value.is_function()) { auto result = TRY_OR_DISCARD(vm.call(replace_value.as_function(), js_undefined(), js_string(vm, search_string), Value(position.value()), js_string(vm, string))); - - replacement = result.to_string(global_object); - if (vm.exception()) - return {}; + replacement = TRY_OR_DISCARD(result.to_string(global_object)); } else { replacement = TRY_OR_DISCARD(get_substitution(global_object, search_string.view(), string.view(), *position, {}, js_undefined(), replace_value)); } @@ -970,9 +961,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::replace_all) if (is_regexp) { 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()) - return {}; + auto flags_string = TRY_OR_DISCARD(flags_object.to_string(global_object)); if (!flags_string.contains("g")) { vm.throw_exception(global_object, ErrorType::StringNonGlobalRegExp); return {}; @@ -1021,10 +1010,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::replace_all) if (replace_value.is_function()) { auto result = TRY_OR_DISCARD(vm.call(replace_value.as_function(), js_undefined(), js_string(vm, search_string), Value(position), js_string(vm, string))); - - replacement = result.to_string(global_object); - if (vm.exception()) - return {}; + replacement = TRY_OR_DISCARD(result.to_string(global_object)); } else { replacement = TRY_OR_DISCARD(get_substitution(global_object, search_string.view(), string.view(), position, {}, js_undefined(), replace_value)); } @@ -1066,16 +1052,12 @@ static Value create_html(GlobalObject& global_object, Value string, const String { auto& vm = global_object.vm(); TRY_OR_DISCARD(require_object_coercible(global_object, string)); - auto str = string.to_string(global_object); - if (vm.exception()) - return {}; + auto str = TRY_OR_DISCARD(string.to_string(global_object)); StringBuilder builder; builder.append('<'); builder.append(tag); if (!attribute.is_empty()) { - auto value_string = value.to_string(global_object); - if (vm.exception()) - return {}; + auto value_string = TRY_OR_DISCARD(value.to_string(global_object)); builder.append(' '); builder.append(attribute); builder.append("=\""); @@ -1176,9 +1158,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::locale_compare) if (!string.has_value()) return {}; - auto that_string = vm.argument(0).to_string(global_object); - if (vm.exception()) - return {}; + auto that_string = TRY_OR_DISCARD(vm.argument(0).to_string(global_object)); // FIXME: Actually compare the string not just according to their bits. if (string == that_string) diff --git a/Userland/Libraries/LibJS/Runtime/SymbolConstructor.cpp b/Userland/Libraries/LibJS/Runtime/SymbolConstructor.cpp index bbb95cadd8..97061a704a 100644 --- a/Userland/Libraries/LibJS/Runtime/SymbolConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/SymbolConstructor.cpp @@ -44,7 +44,7 @@ Value SymbolConstructor::call() { if (vm().argument(0).is_undefined()) return js_symbol(heap(), {}, false); - return js_symbol(heap(), vm().argument(0).to_string(global_object()), false); + return js_symbol(heap(), TRY_OR_DISCARD(vm().argument(0).to_string(global_object())), false); } // 20.4.1.1 Symbol ( [ description ] ), https://tc39.es/ecma262/#sec-symbol-description @@ -57,7 +57,7 @@ Value SymbolConstructor::construct(FunctionObject&) // 20.4.2.2 Symbol.for ( key ), https://tc39.es/ecma262/#sec-symbol.for JS_DEFINE_NATIVE_FUNCTION(SymbolConstructor::for_) { - String description = vm.argument(0).to_string(global_object); + auto description = TRY_OR_DISCARD(vm.argument(0).to_string(global_object)); return global_object.vm().get_global_symbol(description); } diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/Calendar.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/Calendar.cpp index 17f1a05788..397d6bd6ab 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/Calendar.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/Calendar.cpp @@ -297,12 +297,8 @@ ThrowCompletionOr calendar_era(GlobalObject& global_object, Object& calen auto result = TRY(Value(&calendar).invoke(global_object, vm.names.era, &date_like)); // 3. If result is not undefined, set result to ? ToString(result). - if (!result.is_undefined()) { - auto result_string = result.to_string(global_object); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); - result = js_string(vm, move(result_string)); - } + if (!result.is_undefined()) + result = js_string(vm, TRY(result.to_string(global_object))); // 4. Return result. return result; @@ -362,9 +358,7 @@ ThrowCompletionOr to_temporal_calendar(GlobalObject& global_object, Val } // 2. Let identifier be ? ToString(temporalCalendarLike). - auto identifier = temporal_calendar_like.to_string(global_object); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto identifier = TRY(temporal_calendar_like.to_string(global_object)); // 3. If ! IsBuiltinCalendar(identifier) is false, then if (!is_builtin_calendar(identifier)) { @@ -510,21 +504,15 @@ String format_calendar_annotation(StringView id, StringView show_calendar) // 12.1.28 CalendarEquals ( one, two ), https://tc39.es/proposal-temporal/#sec-temporal-calendarequals ThrowCompletionOr calendar_equals(GlobalObject& global_object, Object& one, Object& two) { - auto& vm = global_object.vm(); - // 1. If one and two are the same Object value, return true. if (&one == &two) return true; // 2. Let calendarOne be ? ToString(one). - auto calendar_one = Value(&one).to_string(global_object); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto calendar_one = TRY(Value(&one).to_string(global_object)); // 3. Let calendarTwo be ? ToString(two). - auto calendar_two = Value(&two).to_string(global_object); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto calendar_two = TRY(Value(&two).to_string(global_object)); // 4. If calendarOne is calendarTwo, return true. if (calendar_one == calendar_two) @@ -543,14 +531,10 @@ ThrowCompletionOr consolidate_calendars(GlobalObject& global_object, Ob return &two; // 2. Let calendarOne be ? ToString(one). - auto calendar_one = Value(&one).to_string(global_object); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto calendar_one = TRY(Value(&one).to_string(global_object)); // 3. Let calendarTwo be ? ToString(two). - auto calendar_two = Value(&two).to_string(global_object); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto calendar_two = TRY(Value(&two).to_string(global_object)); // 4. If calendarOne is calendarTwo, return two. if (calendar_one == calendar_two) diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/CalendarConstructor.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/CalendarConstructor.cpp index 4a7cd62dfc..de4e7af2e5 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/CalendarConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/CalendarConstructor.cpp @@ -49,9 +49,7 @@ Value CalendarConstructor::construct(FunctionObject& new_target) auto& global_object = this->global_object(); // 2. Set id to ? ToString(id). - auto identifier = vm.argument(0).to_string(global_object); - if (vm.exception()) - return {}; + auto identifier = TRY_OR_DISCARD(vm.argument(0).to_string(global_object)); // 3. If ! IsBuiltinCalendar(id) is false, then if (!is_builtin_calendar(identifier)) { diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/CalendarPrototype.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/CalendarPrototype.cpp index 204162e55f..3e7268dbd0 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/CalendarPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/CalendarPrototype.cpp @@ -69,7 +69,7 @@ JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::id_getter) auto calendar = vm.this_value(global_object); // 2. Return ? ToString(calendar). - return js_string(vm, calendar.to_string(global_object)); + return js_string(vm, TRY_OR_DISCARD(calendar.to_string(global_object))); } // 12.4.4 Temporal.Calendar.prototype.dateFromFields ( fields [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal.calendar.prototype.datefromfields @@ -637,7 +637,7 @@ JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::to_json) auto calendar = vm.this_value(global_object); // 2. Return ? ToString(calendar). - return js_string(vm, calendar.to_string(global_object)); + return js_string(vm, TRY_OR_DISCARD(calendar.to_string(global_object))); } // 15.6.2.6 Temporal.Calendar.prototype.era ( temporalDateLike ), https://tc39.es/proposal-temporal/#sec-temporal.calendar.prototype.era diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/Duration.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/Duration.cpp index 695de3e7cb..174ff9ffc8 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/Duration.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/Duration.cpp @@ -34,8 +34,6 @@ Duration::Duration(double years, double months, double weeks, double days, doubl // 7.5.1 ToTemporalDuration ( item ), https://tc39.es/proposal-temporal/#sec-temporal-totemporalduration ThrowCompletionOr to_temporal_duration(GlobalObject& global_object, Value item) { - auto& vm = global_object.vm(); - TemporalDuration result; // 1. If Type(item) is Object, then @@ -51,9 +49,7 @@ ThrowCompletionOr to_temporal_duration(GlobalObject& global_object, V // 2. Else, else { // a. Let string be ? ToString(item). - auto string = item.to_string(global_object); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto string = TRY(item.to_string(global_object)); // b. Let result be ? ParseTemporalDurationString(string). result = TRY(parse_temporal_duration_string(global_object, string)); @@ -451,9 +447,7 @@ ThrowCompletionOr to_limited_temporal_duration(GlobalObject& g // 1. If Type(temporalDurationLike) is not Object, then if (!temporal_duration_like.is_object()) { // a. Let str be ? ToString(temporalDurationLike). - auto str = temporal_duration_like.to_string(global_object); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto str = TRY(temporal_duration_like.to_string(global_object)); // b. Let duration be ? ParseTemporalDurationString(str). duration = TRY(parse_temporal_duration_string(global_object, str)); diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/Instant.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/Instant.cpp index 22f00ea867..0969ee721c 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/Instant.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/Instant.cpp @@ -72,8 +72,6 @@ ThrowCompletionOr create_temporal_instant(GlobalObject& global_object, // 8.5.3 ToTemporalInstant ( item ), https://tc39.es/proposal-temporal/#sec-temporal-totemporalinstant ThrowCompletionOr to_temporal_instant(GlobalObject& global_object, Value item) { - auto& vm = global_object.vm(); - // 1. If Type(item) is Object, then if (item.is_object()) { // a. If item has an [[InitializedTemporalInstant]] internal slot, then @@ -92,9 +90,7 @@ ThrowCompletionOr to_temporal_instant(GlobalObject& global_object, Val } // 2. Let string be ? ToString(item). - auto string = item.to_string(global_object); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto string = TRY(item.to_string(global_object)); // 3. Let epochNanoseconds be ? ParseTemporalInstant(string). auto* epoch_nanoseconds = TRY(parse_temporal_instant(global_object, string)); diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDate.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDate.cpp index 21aa82fe5e..1f64683657 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDate.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDate.cpp @@ -125,9 +125,7 @@ ThrowCompletionOr to_temporal_date(GlobalObject& global_object, Valu (void)TRY(to_temporal_overflow(global_object, *options)); // 5. Let string be ? ToString(item). - auto string = item.to_string(global_object); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto string = TRY(item.to_string(global_object)); // 6. Let result be ? ParseTemporalDateString(string). auto result = TRY(parse_temporal_date_string(global_object, string)); @@ -516,8 +514,6 @@ String pad_iso_year(i32 y) // 3.5.8 TemporalDateToString ( temporalDate, showCalendar ), https://tc39.es/proposal-temporal/#sec-temporal-temporaldatetostring ThrowCompletionOr temporal_date_to_string(GlobalObject& global_object, PlainDate& temporal_date, StringView show_calendar) { - auto& vm = global_object.vm(); - // 1. Assert: Type(temporalDate) is Object. // 2. Assert: temporalDate has an [[InitializedTemporalDate]] internal slot. @@ -531,9 +527,7 @@ ThrowCompletionOr temporal_date_to_string(GlobalObject& global_object, P auto day = String::formatted("{:02}", temporal_date.iso_day()); // 6. Let calendarID be ? ToString(temporalDate.[[Calendar]]). - auto calendar_id = Value(&temporal_date.calendar()).to_string(global_object); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto calendar_id = TRY(Value(&temporal_date.calendar()).to_string(global_object)); // 7. Let calendar be ! FormatCalendarAnnotation(calendarID, showCalendar). auto calendar = format_calendar_annotation(calendar_id, show_calendar); diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTime.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTime.cpp index 03fe6e3cc4..f1727af140 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTime.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTime.cpp @@ -187,9 +187,7 @@ ThrowCompletionOr to_temporal_date_time(GlobalObject& global_obj (void)TRY(to_temporal_overflow(global_object, *options)); // b. Let string be ? ToString(item). - auto string = item.to_string(global_object); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto string = TRY(item.to_string(global_object)); // c. Let result be ? ParseTemporalDateTimeString(string). result = TRY(parse_temporal_date_time_string(global_object, string)); @@ -273,8 +271,6 @@ ThrowCompletionOr create_temporal_date_time(GlobalObject& global // 5.5.7 TemporalDateTimeToString ( isoYear, isoMonth, isoDay, hour, minute, second, millisecond, microsecond, nanosecond, calendar, precision, showCalendar ), , https://tc39.es/proposal-temporal/#sec-temporal-temporaldatetimetostring ThrowCompletionOr temporal_date_time_to_string(GlobalObject& global_object, i32 iso_year, u8 iso_month, u8 iso_day, u8 hour, u8 minute, u8 second, u16 millisecond, u16 microsecond, u16 nanosecond, Value calendar, Variant const& precision, StringView show_calendar) { - auto& vm = global_object.vm(); - // 1. Assert: isoYear, isoMonth, isoDay, hour, minute, second, millisecond, microsecond, and nanosecond are integers. // 2. Let year be ! PadISOYear(isoYear). @@ -287,9 +283,7 @@ ThrowCompletionOr temporal_date_time_to_string(GlobalObject& global_obje auto seconds = format_seconds_string_part(second, millisecond, microsecond, nanosecond, precision); // 8. Let calendarID be ? ToString(calendar). - auto calendar_id = calendar.to_string(global_object); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto calendar_id = TRY(calendar.to_string(global_object)); // 9. Let calendarString be ! FormatCalendarAnnotation(calendarID, showCalendar). auto calendar_string = format_calendar_annotation(calendar_id, show_calendar); diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/PlainMonthDay.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/PlainMonthDay.cpp index 33c849763c..d677d1e752 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/PlainMonthDay.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/PlainMonthDay.cpp @@ -154,8 +154,6 @@ ThrowCompletionOr create_temporal_month_day(GlobalObject& global // 10.5.3 TemporalMonthDayToString ( monthDay, showCalendar ), https://tc39.es/proposal-temporal/#sec-temporal-temporalmonthdaytostring ThrowCompletionOr temporal_month_day_to_string(GlobalObject& global_object, PlainMonthDay& month_day, StringView show_calendar) { - auto& vm = global_object.vm(); - // 1. Assert: Type(monthDay) is Object. // 2. Assert: monthDay has an [[InitializedTemporalMonthDay]] internal slot. @@ -165,9 +163,7 @@ ThrowCompletionOr temporal_month_day_to_string(GlobalObject& global_obje auto result = String::formatted("{:02}-{:02}", month_day.iso_month(), month_day.iso_day()); // 6. Let calendarID be ? ToString(monthDay.[[Calendar]]). - auto calendar_id = Value(&month_day.calendar()).to_string(global_object); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto calendar_id = TRY(Value(&month_day.calendar()).to_string(global_object)); // 7. If calendarID is not "iso8601", then if (calendar_id != "iso8601"sv) { diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/PlainTime.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/PlainTime.cpp index 0b12c8bd59..a08638837d 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/PlainTime.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/PlainTime.cpp @@ -84,9 +84,7 @@ ThrowCompletionOr to_temporal_time(GlobalObject& global_object, Valu auto* calendar = TRY(get_temporal_calendar_with_iso_default(global_object, item_object)); // e. If ? ToString(calendar) is not "iso8601", then - auto calendar_identifier = Value(calendar).to_string(global_object); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto calendar_identifier = TRY(Value(calendar).to_string(global_object)); if (calendar_identifier != "iso8601"sv) { // i. Throw a RangeError exception. return vm.throw_completion(global_object, ErrorType::TemporalInvalidCalendarIdentifier, calendar_identifier); @@ -101,9 +99,7 @@ ThrowCompletionOr to_temporal_time(GlobalObject& global_object, Valu // 4. Else, else { // a. Let string be ? ToString(item). - auto string = item.to_string(global_object); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto string = TRY(item.to_string(global_object)); // b. Let result be ? ParseTemporalTimeString(string). result = TRY(parse_temporal_time_string(global_object, string)); diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/PlainYearMonth.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/PlainYearMonth.cpp index cd58b33d03..7996692ff8 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/PlainYearMonth.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/PlainYearMonth.cpp @@ -68,9 +68,7 @@ ThrowCompletionOr to_temporal_year_month(GlobalObject& global_o (void)TRY(to_temporal_overflow(global_object, *options)); // 5. Let string be ? ToString(item). - auto string = item.to_string(global_object); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto string = TRY(item.to_string(global_object)); // 6. Let result be ? ParseTemporalYearMonthString(string). auto result = TRY(parse_temporal_year_month_string(global_object, string)); @@ -236,8 +234,6 @@ ThrowCompletionOr create_temporal_year_month(GlobalObject& glob // 9.5.8 TemporalYearMonthToString ( yearMonth, showCalendar ), https://tc39.es/proposal-temporal/#sec-temporal-temporalyearmonthtostring ThrowCompletionOr temporal_year_month_to_string(GlobalObject& global_object, PlainYearMonth& year_month, StringView show_calendar) { - auto& vm = global_object.vm(); - // 1. Assert: Type(yearMonth) is Object. // 2. Assert: yearMonth has an [[InitializedTemporalYearMonth]] internal slot. @@ -247,9 +243,7 @@ ThrowCompletionOr temporal_year_month_to_string(GlobalObject& global_obj auto result = String::formatted("{}-{:02}", pad_iso_year(year_month.iso_year()), year_month.iso_month()); // 6. Let calendarID be ? ToString(yearMonth.[[Calendar]]). - auto calendar_id = Value(&year_month.calendar()).to_string(global_object); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto calendar_id = TRY(Value(&year_month.calendar()).to_string(global_object)); // 7. If calendarID is not "iso8601", then if (calendar_id != "iso8601") { diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp index 34e87ac539..c88f0ff05d 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp @@ -338,9 +338,7 @@ ThrowCompletionOr to_temporal_time_zone(GlobalObject& global_object, Va } // 2. Let identifier be ? ToString(temporalTimeZoneLike). - auto identifier = temporal_time_zone_like.to_string(global_object); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto identifier = TRY(temporal_time_zone_like.to_string(global_object)); // 3. Let result be ? ParseTemporalTimeZone(identifier). auto result = TRY(parse_temporal_time_zone(global_object, identifier)); diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/TimeZoneConstructor.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/TimeZoneConstructor.cpp index 0767be28fd..219397925d 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/TimeZoneConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/TimeZoneConstructor.cpp @@ -49,9 +49,7 @@ Value TimeZoneConstructor::construct(FunctionObject& new_target) auto& global_object = this->global_object(); // 2. Set identifier to ? ToString(identifier). - auto identifier = vm.argument(0).to_string(global_object); - if (vm.exception()) - return {}; + auto identifier = TRY_OR_DISCARD(vm.argument(0).to_string(global_object)); String canonical; diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/TimeZonePrototype.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/TimeZonePrototype.cpp index 6f22ef956f..c298ecbe06 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/TimeZonePrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/TimeZonePrototype.cpp @@ -45,7 +45,7 @@ JS_DEFINE_NATIVE_FUNCTION(TimeZonePrototype::id_getter) auto time_zone = vm.this_value(global_object); // 2. Return ? ToString(timeZone). - return js_string(vm, time_zone.to_string(global_object)); + return js_string(vm, TRY_OR_DISCARD(time_zone.to_string(global_object))); } // 11.4.4 Temporal.TimeZone.prototype.getOffsetNanosecondsFor ( instant ), https://tc39.es/proposal-temporal/#sec-temporal.timezone.prototype.getoffsetnanosecondsfor @@ -121,7 +121,7 @@ JS_DEFINE_NATIVE_FUNCTION(TimeZonePrototype::to_json) auto time_zone = vm.this_value(global_object); // 2. Return ? ToString(timeZone). - return js_string(vm, time_zone.to_string(global_object)); + return js_string(vm, TRY_OR_DISCARD(time_zone.to_string(global_object))); } } diff --git a/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp b/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp index f56da5285e..9710b26ff1 100644 --- a/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp @@ -594,11 +594,8 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::join) return {}; auto length = typed_array->array_length(); String separator = ","; - if (!vm.argument(0).is_undefined()) { - separator = vm.argument(0).to_string(global_object); - if (vm.exception()) - return {}; - } + if (!vm.argument(0).is_undefined()) + separator = TRY_OR_DISCARD(vm.argument(0).to_string(global_object)); StringBuilder builder; for (size_t i = 0; i < length; ++i) { @@ -607,9 +604,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::join) auto value = TRY_OR_DISCARD(typed_array->get(i)); if (value.is_nullish()) continue; - auto string = value.to_string(global_object); - if (vm.exception()) - return {}; + auto string = TRY_OR_DISCARD(value.to_string(global_object)); builder.append(string); } @@ -1487,9 +1482,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::to_locale_string) if (value.is_nullish()) continue; auto locale_string_result = TRY_OR_DISCARD(value.invoke(global_object, vm.names.toLocaleString)); - auto string = locale_string_result.to_string(global_object); - if (vm.exception()) - return {}; + auto string = TRY_OR_DISCARD(locale_string_result.to_string(global_object)); builder.append(string); } return js_string(vm, builder.to_string()); diff --git a/Userland/Libraries/LibJS/Runtime/Value.cpp b/Userland/Libraries/LibJS/Runtime/Value.cpp index ff85981e95..47c8bfc829 100644 --- a/Userland/Libraries/LibJS/Runtime/Value.cpp +++ b/Userland/Libraries/LibJS/Runtime/Value.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -326,22 +327,21 @@ PrimitiveString* Value::to_primitive_string(GlobalObject& global_object) { if (is_string()) return &as_string(); - auto string = to_string(global_object); - if (global_object.vm().exception()) - return nullptr; + auto string = TRY_OR_DISCARD(to_string(global_object)); return js_string(global_object.heap(), string); } // 7.1.17 ToString ( argument ), https://tc39.es/ecma262/#sec-tostring -String Value::to_string(GlobalObject& global_object) const +ThrowCompletionOr Value::to_string(GlobalObject& global_object) const { + auto& vm = global_object.vm(); switch (m_type) { case Type::Undefined: - return "undefined"; + return { "undefined"sv }; case Type::Null: - return "null"; + return { "null"sv }; case Type::Boolean: - return m_value.as_bool ? "true" : "false"; + return { m_value.as_bool ? "true"sv : "false"sv }; case Type::Int32: return String::number(m_value.as_i32); case Type::Double: @@ -349,14 +349,13 @@ String Value::to_string(GlobalObject& global_object) const case Type::String: return m_value.as_string->string(); case Type::Symbol: - global_object.vm().throw_exception(global_object, ErrorType::Convert, "symbol", "string"); - return {}; + return vm.throw_completion(global_object, ErrorType::Convert, "symbol", "string"); case Type::BigInt: return m_value.as_bigint->big_integer().to_base(10); case Type::Object: { auto primitive_value = to_primitive(global_object, PreferredType::String); - if (global_object.vm().exception()) - return {}; + if (auto* exception = vm.exception()) + return throw_completion(exception->value()); return primitive_value.to_string(global_object); } default: @@ -369,10 +368,7 @@ Utf16String Value::to_utf16_string(GlobalObject& global_object) const if (m_type == Type::String) return m_value.as_string->utf16_string(); - auto utf8_string = to_string(global_object); - if (global_object.vm().exception()) - return {}; - + auto utf8_string = TRY_OR_DISCARD(to_string(global_object)); return Utf16String(utf8_string); } @@ -596,7 +592,7 @@ StringOrSymbol Value::to_property_key(GlobalObject& global_object) const return {}; if (key.is_symbol()) return &key.as_symbol(); - return key.to_string(global_object); + return TRY_OR_DISCARD(key.to_string(global_object)); } i32 Value::to_i32_slow_case(GlobalObject& global_object) const @@ -1100,12 +1096,8 @@ Value add(GlobalObject& global_object, Value lhs, Value rhs) } } if (lhs_primitive.is_string() || rhs_primitive.is_string()) { - auto lhs_string = lhs_primitive.to_string(global_object); - if (vm.exception()) - return {}; - auto rhs_string = rhs_primitive.to_string(global_object); - if (vm.exception()) - return {}; + auto lhs_string = TRY_OR_DISCARD(lhs_primitive.to_string(global_object)); + auto rhs_string = TRY_OR_DISCARD(rhs_primitive.to_string(global_object)); StringBuilder builder(lhs_string.length() + rhs_string.length()); builder.append(lhs_string); builder.append(rhs_string); diff --git a/Userland/Libraries/LibJS/Runtime/Value.h b/Userland/Libraries/LibJS/Runtime/Value.h index 6e0757f3db..77556e96e5 100644 --- a/Userland/Libraries/LibJS/Runtime/Value.h +++ b/Userland/Libraries/LibJS/Runtime/Value.h @@ -303,7 +303,7 @@ public: u64 encoded() const { return m_value.encoded; } - String to_string(GlobalObject&) const; + ThrowCompletionOr to_string(GlobalObject&) const; Utf16String to_utf16_string(GlobalObject&) const; PrimitiveString* to_primitive_string(GlobalObject&); Value to_primitive(GlobalObject&, PreferredType preferred_type = PreferredType::Default) const; diff --git a/Userland/Libraries/LibWeb/Bindings/CSSNamespace.cpp b/Userland/Libraries/LibWeb/Bindings/CSSNamespace.cpp index 2ca4d6f42a..ec1e3cd395 100644 --- a/Userland/Libraries/LibWeb/Bindings/CSSNamespace.cpp +++ b/Userland/Libraries/LibWeb/Bindings/CSSNamespace.cpp @@ -38,9 +38,7 @@ JS_DEFINE_NATIVE_FUNCTION(CSSNamespace::escape) return {}; } - auto identifier = vm.argument(0).to_string(global_object); - if (vm.exception()) - return {}; + auto identifier = TRY_OR_DISCARD(vm.argument(0).to_string(global_object)); return JS::js_string(vm, Web::CSS::serialize_an_identifier(identifier)); } @@ -55,17 +53,13 @@ JS_DEFINE_NATIVE_FUNCTION(CSSNamespace::supports) if (vm.argument_count() >= 2) { // When the supports(property, value) method is invoked with two arguments property and value: - String property_name = vm.argument(0).to_string(global_object); - if (vm.exception()) - return {}; + auto property_name = TRY_OR_DISCARD(vm.argument(0).to_string(global_object)); // If property is an ASCII case-insensitive match for any defined CSS property that the UA supports, // and value successfully parses according to that property’s grammar, return true. auto property = CSS::property_id_from_string(property_name); if (property != CSS::PropertyID::Invalid) { - auto value_string = vm.argument(1).to_string(global_object); - if (vm.exception()) - return {}; + auto value_string = TRY_OR_DISCARD(vm.argument(1).to_string(global_object)); if (parse_css_value({}, value_string, property)) return JS::Value(true); } @@ -79,9 +73,7 @@ JS_DEFINE_NATIVE_FUNCTION(CSSNamespace::supports) return JS::Value(false); } else { // When the supports(conditionText) method is invoked with a single conditionText argument: - String supports_text = vm.argument(0).to_string(global_object); - if (vm.exception()) - return {}; + auto supports_text = TRY_OR_DISCARD(vm.argument(0).to_string(global_object)); // If conditionText, parsed and evaluated as a , would return true, return true. if (auto supports = parse_css_supports({}, supports_text); supports && supports->matches()) diff --git a/Userland/Libraries/LibWeb/Bindings/CSSStyleDeclarationWrapperCustom.cpp b/Userland/Libraries/LibWeb/Bindings/CSSStyleDeclarationWrapperCustom.cpp index ccdb1ab932..92ccd88c5b 100644 --- a/Userland/Libraries/LibWeb/Bindings/CSSStyleDeclarationWrapperCustom.cpp +++ b/Userland/Libraries/LibWeb/Bindings/CSSStyleDeclarationWrapperCustom.cpp @@ -48,9 +48,7 @@ JS::ThrowCompletionOr CSSStyleDeclarationWrapper::internal_set(JS::Propert if (property_id == CSS::PropertyID::Invalid) return Base::internal_set(name, value, receiver); - auto css_text = value.to_string(global_object()); - if (auto* exception = vm().exception()) - return JS::throw_completion(exception->value()); + auto css_text = TRY(value.to_string(global_object())); impl().set_property(property_id, css_text); return true; diff --git a/Userland/Libraries/LibWeb/Bindings/LocationObject.cpp b/Userland/Libraries/LibWeb/Bindings/LocationObject.cpp index f09f1778ce..f44f7f5bfd 100644 --- a/Userland/Libraries/LibWeb/Bindings/LocationObject.cpp +++ b/Userland/Libraries/LibWeb/Bindings/LocationObject.cpp @@ -53,9 +53,7 @@ JS_DEFINE_NATIVE_FUNCTION(LocationObject::href_getter) JS_DEFINE_NATIVE_FUNCTION(LocationObject::href_setter) { auto& window = static_cast(global_object); - auto new_href = vm.argument(0).to_string(global_object); - if (vm.exception()) - return {}; + auto new_href = TRY_OR_DISCARD(vm.argument(0).to_string(global_object)); auto href_url = window.impl().associated_document().parse_url(new_href); if (!href_url.is_valid()) { vm.throw_exception(global_object, String::formatted("Invalid URL '{}'", new_href)); @@ -133,9 +131,7 @@ JS_DEFINE_NATIVE_FUNCTION(LocationObject::reload) JS_DEFINE_NATIVE_FUNCTION(LocationObject::replace) { auto& window = static_cast(global_object); - auto url = vm.argument(0).to_string(global_object); - if (vm.exception()) - return {}; + auto url = TRY_OR_DISCARD(vm.argument(0).to_string(global_object)); // FIXME: This needs spec compliance work. window.impl().did_call_location_replace({}, move(url)); return JS::js_undefined(); diff --git a/Userland/Libraries/LibWeb/Bindings/WindowObject.cpp b/Userland/Libraries/LibWeb/Bindings/WindowObject.cpp index a3b391bfe6..08ab6e3f6f 100644 --- a/Userland/Libraries/LibWeb/Bindings/WindowObject.cpp +++ b/Userland/Libraries/LibWeb/Bindings/WindowObject.cpp @@ -190,11 +190,8 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::alert) if (!impl) return {}; String message = ""; - if (vm.argument_count()) { - message = vm.argument(0).to_string(global_object); - if (vm.exception()) - return {}; - } + if (vm.argument_count()) + message = TRY_OR_DISCARD(vm.argument(0).to_string(global_object)); impl->alert(message); return JS::js_undefined(); } @@ -205,11 +202,8 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::confirm) if (!impl) return {}; String message = ""; - if (!vm.argument(0).is_undefined()) { - message = vm.argument(0).to_string(global_object); - if (vm.exception()) - return {}; - } + if (!vm.argument(0).is_undefined()) + message = TRY_OR_DISCARD(vm.argument(0).to_string(global_object)); return JS::Value(impl->confirm(message)); } @@ -220,16 +214,10 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::prompt) return {}; String message = ""; String default_ = ""; - if (!vm.argument(0).is_undefined()) { - message = vm.argument(0).to_string(global_object); - if (vm.exception()) - return {}; - } - if (!vm.argument(1).is_undefined()) { - default_ = vm.argument(1).to_string(global_object); - if (vm.exception()) - return {}; - } + if (!vm.argument(0).is_undefined()) + message = TRY_OR_DISCARD(vm.argument(0).to_string(global_object)); + if (!vm.argument(1).is_undefined()) + default_ = TRY_OR_DISCARD(vm.argument(1).to_string(global_object)); auto response = impl->prompt(message, default_); if (response.is_null()) return JS::js_null(); @@ -252,9 +240,7 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::set_interval) if (vm.argument(0).is_function()) { callback = &vm.argument(0).as_function(); } else { - auto script_source = vm.argument(0).to_string(global_object); - if (vm.exception()) - return {}; + auto script_source = TRY_OR_DISCARD(vm.argument(0).to_string(global_object)); // FIXME: This needs more work once we have a environment settings object. // The spec wants us to use a task for the "run function or script string" part, // using a NativeFunction for the latter is a workaround so that we can reuse the @@ -293,9 +279,7 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::set_timeout) if (vm.argument(0).is_function()) { callback = &vm.argument(0).as_function(); } else { - auto script_source = vm.argument(0).to_string(global_object); - if (vm.exception()) - return {}; + auto script_source = TRY_OR_DISCARD(vm.argument(0).to_string(global_object)); // FIXME: This needs more work once we have a environment settings object. // The spec wants us to use a task for the "run function or script string" part, // using a NativeFunction for the latter is a workaround so that we can reuse the @@ -415,9 +399,7 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::atob) vm.throw_exception(global_object, JS::ErrorType::BadArgCountOne, "atob"); return {}; } - auto string = vm.argument(0).to_string(global_object); - if (vm.exception()) - return {}; + auto string = TRY_OR_DISCARD(vm.argument(0).to_string(global_object)); auto decoded = decode_base64(StringView(string)); // decode_base64() returns a byte string. LibJS uses UTF-8 for strings. Use Latin1Decoder to convert bytes 128-255 to UTF-8. @@ -435,9 +417,7 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::btoa) vm.throw_exception(global_object, JS::ErrorType::BadArgCountOne, "btoa"); return {}; } - auto string = vm.argument(0).to_string(global_object); - if (vm.exception()) - return {}; + auto string = TRY_OR_DISCARD(vm.argument(0).to_string(global_object)); Vector byte_string; byte_string.ensure_capacity(string.length()); @@ -593,9 +573,7 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::match_media) auto* impl = impl_from(vm, global_object); if (!impl) return {}; - auto media = vm.argument(0).to_string(global_object); - if (vm.exception()) - return {}; + auto media = TRY_OR_DISCARD(vm.argument(0).to_string(global_object)); return wrap(global_object, impl->match_media(move(media))); } @@ -660,9 +638,7 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::scroll) 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()) - return {}; + behavior_string = TRY_OR_DISCARD(behavior_string_value.to_string(global_object)); if (behavior_string != "smooth" && behavior_string != "auto") { vm.throw_exception(global_object, "Behavior is not one of 'smooth' or 'auto'"); return {}; @@ -737,9 +713,7 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::scroll_by) top = top + current_scroll_position.y(); 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 {}; + auto behavior_string = behavior_string_value.is_undefined() ? "auto" : TRY_OR_DISCARD(behavior_string_value.to_string(global_object)); if (behavior_string != "smooth" && behavior_string != "auto") { vm.throw_exception(global_object, "Behavior is not one of 'smooth' or 'auto'"); return {}; diff --git a/Userland/Utilities/js.cpp b/Userland/Utilities/js.cpp index f7bc449cfc..035e585870 100644 --- a/Userland/Utilities/js.cpp +++ b/Userland/Utilities/js.cpp @@ -890,9 +890,7 @@ static bool parse_and_run(JS::Interpreter& interpreter, StringView const& source static JS::Value load_file_impl(JS::VM& vm, JS::GlobalObject& global_object) { - auto filename = vm.argument(0).to_string(global_object); - if (vm.exception()) - return {}; + auto filename = TRY_OR_DISCARD(vm.argument(0).to_string(global_object)); auto file = Core::File::construct(filename); if (!file->open(Core::OpenMode::ReadOnly)) { vm.throw_exception(global_object, String::formatted("Failed to open '{}': {}", filename, file->error_string())); @@ -914,9 +912,7 @@ static JS::Value load_file_impl(JS::VM& vm, JS::GlobalObject& global_object) static JS::Value load_json_impl(JS::VM& vm, JS::GlobalObject& global_object) { - auto filename = vm.argument(0).to_string(global_object); - if (vm.exception()) - return {}; + auto filename = TRY_OR_DISCARD(vm.argument(0).to_string(global_object)); auto file = Core::File::construct(filename); if (!file->open(Core::OpenMode::ReadOnly)) { vm.throw_exception(global_object, String::formatted("Failed to open '{}': {}", filename, file->error_string()));