diff --git a/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp b/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp index 9dc09f17bb3..0b8211b45be 100644 --- a/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp +++ b/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp @@ -250,7 +250,7 @@ ErrorOr initialize_main_thread_vm(HTML::EventLoop::Type type) auto result = finalization_registry.cleanup(); // 5. Clean up after running script with entry. - entry.clean_up_after_running_script(); + HTML::clean_up_after_running_script(realm); // 6. If result is an abrupt completion, then report the exception given by result.[[Value]]. if (result.is_error()) @@ -309,15 +309,15 @@ ErrorOr initialize_main_thread_vm(HTML::EventLoop::Type type) // 3. Let result be job(). auto result = job->function()(); - // 4. If job settings is not null, then clean up after running script with job settings. - if (job_settings) { + // 4. If realm is not null, then clean up after running script with job settings. + if (realm) { // IMPLEMENTATION DEFINED: Disassociate the realm execution context from the script or module. job_settings->realm_execution_context().script_or_module = Empty {}; // IMPLEMENTATION DEFINED: See comment above, we need to clean up the non-standard prepare_to_run_callback() call. job_settings->clean_up_after_running_callback(); - job_settings->clean_up_after_running_script(); + HTML::clean_up_after_running_script(*realm); } else { // Pop off the dummy execution context. See the above FIXME block about why this is done. s_main_thread_vm->pop_execution_context(); diff --git a/Userland/Libraries/LibWeb/HTML/Navigation.cpp b/Userland/Libraries/LibWeb/HTML/Navigation.cpp index 68719f53dd2..9d55a7a093b 100644 --- a/Userland/Libraries/LibWeb/HTML/Navigation.cpp +++ b/Userland/Libraries/LibWeb/HTML/Navigation.cpp @@ -1498,8 +1498,8 @@ void Navigation::update_the_navigation_api_entries_for_a_same_document_navigatio disposed_nhe->dispatch_event(DOM::Event::create(realm, EventNames::dispose, {})); } - // 12. Clean up after running script given navigation's relevant settings object. - relevant_settings_object(*this).clean_up_after_running_script(); + // 12. Clean up after running script given navigation's relevant realm. + clean_up_after_running_script(relevant_realm(*this)); } } diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/ClassicScript.cpp b/Userland/Libraries/LibWeb/HTML/Scripting/ClassicScript.cpp index 9fc8a96987f..22fb2539935 100644 --- a/Userland/Libraries/LibWeb/HTML/Scripting/ClassicScript.cpp +++ b/Userland/Libraries/LibWeb/HTML/Scripting/ClassicScript.cpp @@ -112,8 +112,8 @@ JS::Completion ClassicScript::run(RethrowErrors rethrow_errors) if (evaluation_status.is_abrupt()) { // 1. If rethrow errors is true and script's muted errors is false, then: if (rethrow_errors == RethrowErrors::Yes && m_muted_errors == MutedErrors::No) { - // 1. Clean up after running script with settings. - settings.clean_up_after_running_script(); + // 1. Clean up after running script with realm. + clean_up_after_running_script(realm); // 2. Rethrow evaluationStatus.[[Value]]. return JS::throw_completion(*evaluation_status.value()); @@ -121,8 +121,8 @@ JS::Completion ClassicScript::run(RethrowErrors rethrow_errors) // 2. If rethrow errors is true and script's muted errors is true, then: if (rethrow_errors == RethrowErrors::Yes && m_muted_errors == MutedErrors::Yes) { - // 1. Clean up after running script with settings. - settings.clean_up_after_running_script(); + // 1. Clean up after running script with realm. + clean_up_after_running_script(realm); // 2. Throw a "NetworkError" DOMException. return throw_completion(WebIDL::NetworkError::create(realm, "Script error."_string)); @@ -136,15 +136,15 @@ JS::Completion ClassicScript::run(RethrowErrors rethrow_errors) VERIFY(window_or_worker); window_or_worker->report_an_exception(*evaluation_status.value()); - // 2. Clean up after running script with settings. - settings.clean_up_after_running_script(); + // 2. Clean up after running script with realm. + clean_up_after_running_script(realm); // 3. Return evaluationStatus. return evaluation_status; } - // 8. Clean up after running script with settings. - settings.clean_up_after_running_script(); + // 8. Clean up after running script with realm. + clean_up_after_running_script(realm); // 9. If evaluationStatus is a normal completion, then return evaluationStatus. VERIFY(!evaluation_status.is_abrupt()); diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/Environments.cpp b/Userland/Libraries/LibWeb/HTML/Scripting/Environments.cpp index 6d38fffaa8c..90f958f2f55 100644 --- a/Userland/Libraries/LibWeb/HTML/Scripting/Environments.cpp +++ b/Userland/Libraries/LibWeb/HTML/Scripting/Environments.cpp @@ -2,6 +2,7 @@ * Copyright (c) 2021, Luke Wilde * Copyright (c) 2022, Linus Groh * Copyright (c) 2022, networkException + * Copyright (c) 2024, Shannon Booth * * SPDX-License-Identifier: BSD-2-Clause */ @@ -140,19 +141,20 @@ JS::ExecutionContext const& execution_context_of_realm(JS::Realm const& realm) } // https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-script -void EnvironmentSettingsObject::clean_up_after_running_script() +// https://whatpr.org/html/9893/webappapis.html#clean-up-after-running-script +void clean_up_after_running_script(JS::Realm const& realm) { - auto& vm = global_object().vm(); + auto& vm = realm.global_object().vm(); - // 1. Assert: settings's realm execution context is the running JavaScript execution context. - VERIFY(&realm_execution_context() == &vm.running_execution_context()); + // 1. Assert: realm's execution context is the running JavaScript execution context. + VERIFY(&execution_context_of_realm(realm) == &vm.running_execution_context()); - // 2. Remove settings's realm execution context from the JavaScript execution context stack. + // 2. Remove realm's execution context from the JavaScript execution context stack. vm.pop_execution_context(); // 3. If the JavaScript execution context stack is now empty, perform a microtask checkpoint. (If this runs scripts, these algorithms will be invoked reentrantly.) if (vm.execution_context_stack().is_empty()) - responsible_event_loop().perform_a_microtask_checkpoint(); + main_thread_event_loop().perform_a_microtask_checkpoint(); } static JS::ExecutionContext* top_most_script_having_execution_context(JS::VM& vm) diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/Environments.h b/Userland/Libraries/LibWeb/HTML/Scripting/Environments.h index dfbbe9d97fe..54ce9c35257 100644 --- a/Userland/Libraries/LibWeb/HTML/Scripting/Environments.h +++ b/Userland/Libraries/LibWeb/HTML/Scripting/Environments.h @@ -1,6 +1,7 @@ /* * Copyright (c) 2021, Luke Wilde * Copyright (c) 2022, Linus Groh + * Copyright (c) 2024, Shannon Booth * * SPDX-License-Identifier: BSD-2-Clause */ @@ -96,7 +97,6 @@ public: Vector>& fetch_group() { return m_fetch_group; } void prepare_to_run_script(); - void clean_up_after_running_script(); void prepare_to_run_callback(); void clean_up_after_running_callback(); @@ -141,6 +141,7 @@ JS::ExecutionContext const& execution_context_of_realm(JS::Realm const&); RunScriptDecision can_run_script(JS::Realm const&); bool is_scripting_enabled(JS::Realm const&); bool is_scripting_disabled(JS::Realm const&); +void clean_up_after_running_script(JS::Realm const&); EnvironmentSettingsObject& incumbent_settings_object(); JS::Realm& incumbent_realm(); diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/ModuleScript.cpp b/Userland/Libraries/LibWeb/HTML/Scripting/ModuleScript.cpp index 1e4be66b737..c74c81cf456 100644 --- a/Userland/Libraries/LibWeb/HTML/Scripting/ModuleScript.cpp +++ b/Userland/Libraries/LibWeb/HTML/Scripting/ModuleScript.cpp @@ -177,8 +177,8 @@ JS::Promise* JavaScriptModuleScript::run(PreventErrorReporting) // FIXME: 7. If preventErrorReporting is false, then upon rejection of evaluationPromise with reason, report the exception given by reason for script. - // 8. Clean up after running script with settings. - settings.clean_up_after_running_script(); + // 8. Clean up after running script with realm. + clean_up_after_running_script(realm); // 9. Return evaluationPromise. return evaluation_promise; diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/TemporaryExecutionContext.cpp b/Userland/Libraries/LibWeb/HTML/Scripting/TemporaryExecutionContext.cpp index cf5ac9898db..45879133692 100644 --- a/Userland/Libraries/LibWeb/HTML/Scripting/TemporaryExecutionContext.cpp +++ b/Userland/Libraries/LibWeb/HTML/Scripting/TemporaryExecutionContext.cpp @@ -20,7 +20,7 @@ TemporaryExecutionContext::TemporaryExecutionContext(EnvironmentSettingsObject& TemporaryExecutionContext::~TemporaryExecutionContext() { - m_environment_settings->clean_up_after_running_script(); + clean_up_after_running_script(m_environment_settings->realm()); if (m_callbacks_enabled == CallbacksEnabled::Yes) m_environment_settings->clean_up_after_running_callback(); } diff --git a/Userland/Libraries/LibWeb/HTML/StructuredSerialize.cpp b/Userland/Libraries/LibWeb/HTML/StructuredSerialize.cpp index fcf08de15ff..e65be7ef0dc 100644 --- a/Userland/Libraries/LibWeb/HTML/StructuredSerialize.cpp +++ b/Userland/Libraries/LibWeb/HTML/StructuredSerialize.cpp @@ -1310,7 +1310,7 @@ WebIDL::ExceptionOr structured_deserialize(JS::VM& vm, SerializationR auto result = TRY(structured_deserialize_internal(vm, serialized.span(), target_realm, *memory)); - target_settings.clean_up_after_running_script(); + clean_up_after_running_script(target_realm); VERIFY(result.value.has_value()); return *result.value; } diff --git a/Userland/Libraries/LibWeb/WebDriver/ExecuteScript.cpp b/Userland/Libraries/LibWeb/WebDriver/ExecuteScript.cpp index e43beac9098..49ead9af035 100644 --- a/Userland/Libraries/LibWeb/WebDriver/ExecuteScript.cpp +++ b/Userland/Libraries/LibWeb/WebDriver/ExecuteScript.cpp @@ -306,8 +306,8 @@ JS::ThrowCompletionOr execute_a_function_body(HTML::Window const& win // 10. Clean up after running a callback with environment settings. environment_settings.clean_up_after_running_callback(); - // 11. Clean up after running a script with environment settings. - environment_settings.clean_up_after_running_script(); + // 11. Clean up after running a script with realm. + HTML::clean_up_after_running_script(realm); // 12. Return completion. return completion; diff --git a/Userland/Libraries/LibWeb/WebIDL/AbstractOperations.cpp b/Userland/Libraries/LibWeb/WebIDL/AbstractOperations.cpp index 5acfdb3e6e1..a69d944bd89 100644 --- a/Userland/Libraries/LibWeb/WebIDL/AbstractOperations.cpp +++ b/Userland/Libraries/LibWeb/WebIDL/AbstractOperations.cpp @@ -102,6 +102,7 @@ ErrorOr get_buffer_source_copy(JS::Object const& buffer_source) } // https://webidl.spec.whatwg.org/#call-user-object-operation-return +// https://whatpr.org/webidl/1437.html#call-user-object-operation-return inline JS::Completion clean_up_on_return(HTML::EnvironmentSettingsObject& stored_settings, HTML::EnvironmentSettingsObject& relevant_settings, JS::Completion& completion, OperationReturnsPromise operation_returns_promise) { auto& realm = stored_settings.realm(); @@ -111,8 +112,8 @@ inline JS::Completion clean_up_on_return(HTML::EnvironmentSettingsObject& stored // 1. Clean up after running a callback with stored settings. stored_settings.clean_up_after_running_callback(); - // 2. Clean up after running script with relevant settings. - relevant_settings.clean_up_after_running_script(); + // 2. Clean up after running script with relevant realm. + HTML::clean_up_after_running_script(relevant_settings.realm()); // 3. If completion is a normal completion, return completion. if (completion.type() == JS::Completion::Type::Normal) @@ -313,8 +314,8 @@ JS::Completion construct(WebIDL::CallbackType& callback, JS::MarkedVectorclean_up_after_running_callback(); - // 2. Clean up after running script with relevant settings. - relevant_settings.clean_up_after_running_script(); + // 2. Clean up after running script with relevant realm. + HTML::clean_up_after_running_script(realm); // 3. Return completion. return completion;