diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/ClassicScript.cpp b/Userland/Libraries/LibWeb/HTML/Scripting/ClassicScript.cpp index 0701593cc61..4b118c33b21 100644 --- a/Userland/Libraries/LibWeb/HTML/Scripting/ClassicScript.cpp +++ b/Userland/Libraries/LibWeb/HTML/Scripting/ClassicScript.cpp @@ -42,8 +42,9 @@ JS::NonnullGCPtr ClassicScript::create(DeprecatedString filename, // 8. Set script's muted errors to muted errors. script->m_muted_errors = muted_errors; - // FIXME: 9. Set script's parse error and error to rethrow to null. - // NOTE: Error to rethrow was set to null in the construction of ClassicScript. We do not have parse error as it would currently go unused. + // 9. Set script's parse error and error to rethrow to null. + script->set_parse_error(JS::js_null()); + script->set_error_to_rethrow(JS::js_null()); // 10. Let result be ParseScript(source, settings's Realm, script). auto parse_timer = Core::ElapsedTimer::start_new(); @@ -55,9 +56,9 @@ JS::NonnullGCPtr ClassicScript::create(DeprecatedString filename, auto& parse_error = result.error().first(); dbgln_if(HTML_SCRIPT_DEBUG, "ClassicScript: Failed to parse: {}", parse_error.to_deprecated_string()); - // FIXME: 1. Set script's parse error and its error to rethrow to result[0]. - // We do not have parse error as it would currently go unused. - script->m_error_to_rethrow = parse_error; + // 1. Set script's parse error and its error to rethrow to result[0]. + script->set_parse_error(JS::SyntaxError::create(environment_settings_object.realm(), parse_error.to_string().release_value_but_fixme_should_propagate_errors())); + script->set_error_to_rethrow(script->parse_error()); // 2. Return script. return script; @@ -73,8 +74,6 @@ JS::NonnullGCPtr ClassicScript::create(DeprecatedString filename, // https://html.spec.whatwg.org/multipage/webappapis.html#run-a-classic-script JS::Completion ClassicScript::run(RethrowErrors rethrow_errors, JS::GCPtr lexical_environment_override) { - auto& vm = settings_object().realm().vm(); - // 1. Let settings be the settings object of script. auto& settings = settings_object(); @@ -89,8 +88,8 @@ JS::Completion ClassicScript::run(RethrowErrors rethrow_errors, JS::GCPtr(TRY_OR_THROW_OOM(vm, m_error_to_rethrow.value().to_string())); + if (!error_to_rethrow().is_null()) { + evaluation_status = JS::Completion { JS::Completion::Type::Throw, error_to_rethrow(), {} }; } else { auto timer = Core::ElapsedTimer::start_new(); diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/ClassicScript.h b/Userland/Libraries/LibWeb/HTML/Scripting/ClassicScript.h index 3d602f1d668..d45800db021 100644 --- a/Userland/Libraries/LibWeb/HTML/Scripting/ClassicScript.h +++ b/Userland/Libraries/LibWeb/HTML/Scripting/ClassicScript.h @@ -43,7 +43,6 @@ private: JS::GCPtr m_script_record; MutedErrors m_muted_errors { MutedErrors::No }; - Optional m_error_to_rethrow; }; } diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/Fetching.cpp b/Userland/Libraries/LibWeb/HTML/Scripting/Fetching.cpp index d0c5fc068af..d12a6388e3b 100644 --- a/Userland/Libraries/LibWeb/HTML/Scripting/Fetching.cpp +++ b/Userland/Libraries/LibWeb/HTML/Scripting/Fetching.cpp @@ -619,9 +619,10 @@ void fetch_descendants_of_and_link_a_module_script(JavaScriptModuleScript& modul // 2. Perform record.Link(). auto linking_result = const_cast(record).link(result->vm()); - // TODO: If this throws an exception, set result's error to rethrow to that exception. - if (linking_result.is_error()) - TODO(); + // If this throws an exception, set result's error to rethrow to that exception. + if (linking_result.is_throw_completion()) { + result->set_error_to_rethrow(linking_result.release_error().value().value()); + } } else { // FIXME: 4. Otherwise, set result's error to rethrow to parse error. TODO(); diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/ModuleScript.cpp b/Userland/Libraries/LibWeb/HTML/Scripting/ModuleScript.cpp index 7a975a36194..b919ebc19e1 100644 --- a/Userland/Libraries/LibWeb/HTML/Scripting/ModuleScript.cpp +++ b/Userland/Libraries/LibWeb/HTML/Scripting/ModuleScript.cpp @@ -49,7 +49,8 @@ WebIDL::ExceptionOr> JavaScriptModuleScript::c // FIXME: 5. Set script's fetch options to options. // 6. Set script's parse error and error to rethrow to null. - // NOTE: Parse error and error to rethrow were set to null in the construction of Script. + script->set_parse_error(JS::js_null()); + script->set_error_to_rethrow(JS::js_null()); // 7. Let result be ParseModule(source, settings's Realm, script). auto result = JS::SourceTextModule::parse(source, settings_object.realm(), filename.view(), script); @@ -59,7 +60,8 @@ WebIDL::ExceptionOr> JavaScriptModuleScript::c auto& parse_error = result.error().first(); dbgln("JavaScriptModuleScript: Failed to parse: {}", parse_error.to_deprecated_string()); - // FIXME: 1. Set script's parse error to result[0]. + // 1. Set script's parse error to result[0]. + script->set_parse_error(JS::SyntaxError::create(settings_object.realm(), parse_error.to_string().release_value_but_fixme_should_propagate_errors())); // 2. Return script. return script; @@ -123,12 +125,16 @@ JS::Promise* JavaScriptModuleScript::run(PreventErrorReporting) // 4. Let evaluationPromise be null. JS::Promise* evaluation_promise = nullptr; - // FIXME: 5. If script's error to rethrow is not null, then set evaluationPromise to a promise rejected with script's error to rethrow. - + // 5. If script's error to rethrow is not null, then set evaluationPromise to a promise rejected with script's error to rethrow. + if (!error_to_rethrow().is_null()) { + evaluation_promise = JS::Promise::create(settings.realm()); + evaluation_promise->reject(error_to_rethrow()); + } // 6. Otherwise: - if (m_record) { + else { // 1. Let record be script's record. auto record = m_record; + VERIFY(record); auto interpreter = JS::Interpreter::create_with_existing_realm(settings.realm()); JS::VM::InterpreterExecutionScope scope(*interpreter); @@ -147,8 +153,6 @@ JS::Promise* JavaScriptModuleScript::run(PreventErrorReporting) } else { evaluation_promise = elevation_promise_or_error.value(); } - } else { - TODO(); } // FIXME: 7. If preventErrorReporting is false, then upon rejection of evaluationPromise with reason, report the exception given by reason for script. diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/Script.cpp b/Userland/Libraries/LibWeb/HTML/Scripting/Script.cpp index b8d71ff3500..6d76b713b47 100644 --- a/Userland/Libraries/LibWeb/HTML/Scripting/Script.cpp +++ b/Userland/Libraries/LibWeb/HTML/Scripting/Script.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Andreas Kling + * Copyright (c) 2021-2023, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ @@ -23,4 +23,12 @@ void Script::visit_host_defined_self(JS::Cell::Visitor& visitor) visitor.visit(this); } +void Script::visit_edges(Visitor& visitor) +{ + Base::visit_edges(visitor); + visitor.visit(m_settings_object); + visitor.visit(m_parse_error); + visitor.visit(m_error_to_rethrow); +} + } diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/Script.h b/Userland/Libraries/LibWeb/HTML/Scripting/Script.h index be0a8b22735..7ebec520dc6 100644 --- a/Userland/Libraries/LibWeb/HTML/Scripting/Script.h +++ b/Userland/Libraries/LibWeb/HTML/Scripting/Script.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Andreas Kling + * Copyright (c) 2021-2023, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ @@ -27,15 +27,29 @@ public: EnvironmentSettingsObject& settings_object() { return m_settings_object; } + [[nodiscard]] JS::Value error_to_rethrow() const { return m_error_to_rethrow; } + void set_error_to_rethrow(JS::Value value) { m_error_to_rethrow = value; } + + [[nodiscard]] JS::Value parse_error() const { return m_parse_error; } + void set_parse_error(JS::Value value) { m_parse_error = value; } + protected: Script(AK::URL base_url, DeprecatedString filename, EnvironmentSettingsObject& environment_settings_object); + virtual void visit_edges(Visitor&) override; + private: virtual void visit_host_defined_self(JS::Cell::Visitor&) override; AK::URL m_base_url; DeprecatedString m_filename; JS::NonnullGCPtr m_settings_object; + + // https://html.spec.whatwg.org/multipage/webappapis.html#concept-script-parse-error + JS::Value m_parse_error; + + // https://html.spec.whatwg.org/multipage/webappapis.html#concept-script-error-to-rethrow + JS::Value m_error_to_rethrow; }; }