From 29cea5bd24f784561bdc7e7d0e0be6147310773d Mon Sep 17 00:00:00 2001 From: Shannon Booth Date: Thu, 31 Oct 2024 02:39:29 +1300 Subject: [PATCH] LibWeb: Make EventLoopPlugin::deferred_invoke take a HeapFunction --- .../Libraries/LibWeb/CSS/CSSStyleSheet.cpp | 4 +- Userland/Libraries/LibWeb/CSS/FontFace.cpp | 14 +++---- Userland/Libraries/LibWeb/CSS/FontFaceSet.cpp | 4 +- .../Libraries/LibWeb/Clipboard/Clipboard.cpp | 4 +- .../Libraries/LibWeb/Crypto/SubtleCrypto.cpp | 40 +++++++++---------- .../Libraries/LibWeb/DOM/DocumentLoading.cpp | 4 +- Userland/Libraries/LibWeb/Fetch/BodyInit.cpp | 4 +- .../LibWeb/Fetch/Fetching/Fetching.cpp | 8 ++-- .../LibWeb/Fetch/Fetching/PendingResponse.cpp | 4 +- .../Libraries/LibWeb/FileAPI/FileReader.cpp | 4 +- .../LibWeb/HTML/HTMLCanvasElement.cpp | 4 +- .../LibWeb/HTML/HTMLImageElement.cpp | 4 +- Userland/Libraries/LibWeb/HTML/Navigable.cpp | 4 +- .../LibWeb/HTML/TraversableNavigable.cpp | 8 ++-- .../LibWeb/HTML/WindowOrWorkerGlobalScope.cpp | 4 +- Userland/Libraries/LibWeb/Loader/Resource.cpp | 4 +- .../LibWeb/Loader/ResourceLoader.cpp | 12 +++--- .../LibWeb/Platform/EventLoopPlugin.h | 2 +- .../Platform/EventLoopPluginSerenity.cpp | 6 ++- .../LibWeb/Platform/EventLoopPluginSerenity.h | 2 +- .../LibWeb/WebDriver/ExecuteScript.cpp | 8 ++-- 21 files changed, 75 insertions(+), 73 deletions(-) diff --git a/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp b/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp index d33fda45083..278ef39a84a 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp +++ b/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp @@ -209,7 +209,7 @@ JS::NonnullGCPtr CSSStyleSheet::replace(String text) set_disallow_modification(true); // 4. In parallel, do these steps: - Platform::EventLoopPlugin::the().deferred_invoke([&realm, this, text = move(text), promise = JS::Handle(promise)] { + Platform::EventLoopPlugin::the().deferred_invoke(JS::create_heap_function(realm.heap(), [&realm, this, text = move(text), promise = JS::Handle(promise)] { HTML::TemporaryExecutionContext execution_context { HTML::relevant_settings_object(*this), HTML::TemporaryExecutionContext::CallbacksEnabled::Yes }; // 1. Let rules be the result of running parse a stylesheet’s contents from text. @@ -232,7 +232,7 @@ JS::NonnullGCPtr CSSStyleSheet::replace(String text) // 5. Resolve promise with sheet. WebIDL::resolve_promise(realm, *promise, this); - }); + })); return promise; } diff --git a/Userland/Libraries/LibWeb/CSS/FontFace.cpp b/Userland/Libraries/LibWeb/CSS/FontFace.cpp index 0a090ebc0cc..20b7e3a2c0d 100644 --- a/Userland/Libraries/LibWeb/CSS/FontFace.cpp +++ b/Userland/Libraries/LibWeb/CSS/FontFace.cpp @@ -25,13 +25,13 @@ namespace Web::CSS { -static NonnullRefPtr>> load_vector_font(ByteBuffer const& data) +static NonnullRefPtr>> load_vector_font(JS::Realm& realm, ByteBuffer const& data) { auto promise = Core::Promise>::construct(); // FIXME: 'Asynchronously' shouldn't mean 'later on the main thread'. // Can we defer this to a background thread? - Platform::EventLoopPlugin::the().deferred_invoke([&data, promise] { + Platform::EventLoopPlugin::the().deferred_invoke(JS::create_heap_function(realm.heap(), [&data, promise] { // FIXME: This should be de-duplicated with StyleComputer::FontLoader::try_load_font // We don't have the luxury of knowing the MIME type, so we have to try all formats. auto ttf = Gfx::Typeface::try_load_from_externally_owned_memory(data); @@ -50,7 +50,7 @@ static NonnullRefPtr>> load_vector_fo return; } promise->reject(Error::from_string_literal("Automatic format detection failed")); - }); + })); return promise; } @@ -118,7 +118,7 @@ JS::NonnullGCPtr FontFace::construct_impl(JS::Realm& realm, String fam if (font->m_binary_data.is_empty()) return font; - HTML::queue_global_task(HTML::Task::Source::FontLoading, HTML::relevant_global_object(*font), JS::create_heap_function(vm.heap(), [font] { + HTML::queue_global_task(HTML::Task::Source::FontLoading, HTML::relevant_global_object(*font), JS::create_heap_function(vm.heap(), [&realm, font] { // 1. Set font face’s status attribute to "loading". font->m_status = Bindings::FontFaceLoadStatus::Loading; @@ -126,7 +126,7 @@ JS::NonnullGCPtr FontFace::construct_impl(JS::Realm& realm, String fam // 3. Asynchronously, attempt to parse the data in it as a font. // When this is completed, successfully or not, queue a task to run the following steps synchronously: - font->m_font_load_promise = load_vector_font(font->m_binary_data); + font->m_font_load_promise = load_vector_font(realm, font->m_binary_data); font->m_font_load_promise->when_resolved([font = JS::make_handle(font)](auto const& vector_font) -> ErrorOr { HTML::queue_global_task(HTML::Task::Source::FontLoading, HTML::relevant_global_object(*font), JS::create_heap_function(font->heap(), [font = JS::NonnullGCPtr(*font), vector_font] { @@ -349,7 +349,7 @@ void FontFace::load_font_source() // and continue executing the rest of this algorithm asynchronously. m_status = Bindings::FontFaceLoadStatus::Loading; - Web::Platform::EventLoopPlugin::the().deferred_invoke([font = JS::make_handle(this)] { + Web::Platform::EventLoopPlugin::the().deferred_invoke(JS::create_heap_function(heap(), [font = JS::make_handle(this)] { // 4. Using the value of font face’s [[Urls]] slot, attempt to load a font as defined in [CSS-FONTS-3], // as if it was the value of a @font-face rule’s src descriptor. @@ -411,7 +411,7 @@ void FontFace::load_font_source() // FIXME: Don't know how to load fonts in workers! They don't have a StyleComputer dbgln("FIXME: Worker font loading not implemented"); } - }); + })); } } diff --git a/Userland/Libraries/LibWeb/CSS/FontFaceSet.cpp b/Userland/Libraries/LibWeb/CSS/FontFaceSet.cpp index 3cd3dd19cf9..dfed14e74cc 100644 --- a/Userland/Libraries/LibWeb/CSS/FontFaceSet.cpp +++ b/Userland/Libraries/LibWeb/CSS/FontFaceSet.cpp @@ -235,7 +235,7 @@ JS::ThrowCompletionOr> FontFaceSet::load(Strin JS::NonnullGCPtr font_face_set = *this; auto promise = WebIDL::create_promise(realm); - Platform::EventLoopPlugin::the().deferred_invoke([&realm, font_face_set, promise, font, text]() mutable { + Platform::EventLoopPlugin::the().deferred_invoke(JS::create_heap_function(realm.heap(), [&realm, font_face_set, promise, font, text]() mutable { // 3. Find the matching font faces from font face set using the font and text arguments passed to the function, // and let font face list be the return value (ignoring the found faces flag). If a syntax error was returned, // reject promise with a SyntaxError exception and terminate these steps. @@ -275,7 +275,7 @@ JS::ThrowCompletionOr> FontFaceSet::load(Strin WebIDL::reject_promise(realm, promise, error); }); })); - }); + })); // 2. Return promise. Complete the rest of these steps asynchronously. return promise; diff --git a/Userland/Libraries/LibWeb/Clipboard/Clipboard.cpp b/Userland/Libraries/LibWeb/Clipboard/Clipboard.cpp index 92162ff415b..5af85c0e85f 100644 --- a/Userland/Libraries/LibWeb/Clipboard/Clipboard.cpp +++ b/Userland/Libraries/LibWeb/Clipboard/Clipboard.cpp @@ -151,7 +151,7 @@ JS::NonnullGCPtr Clipboard::write_text(String data) auto promise = WebIDL::create_promise(realm); // 3. Run the following steps in parallel: - Platform::EventLoopPlugin::the().deferred_invoke([&realm, promise, data = move(data)]() mutable { + Platform::EventLoopPlugin::the().deferred_invoke(JS::create_heap_function(realm.heap(), [&realm, promise, data = move(data)]() mutable { // 1. Let r be the result of running check clipboard write permission. auto result = check_clipboard_write_permission(realm); @@ -191,7 +191,7 @@ JS::NonnullGCPtr Clipboard::write_text(String data) HTML::TemporaryExecutionContext execution_context { Bindings::host_defined_environment_settings_object(realm) }; WebIDL::resolve_promise(realm, promise, JS::js_undefined()); })); - }); + })); // 4. Return p. return promise; diff --git a/Userland/Libraries/LibWeb/Crypto/SubtleCrypto.cpp b/Userland/Libraries/LibWeb/Crypto/SubtleCrypto.cpp index e58dccb1b7c..93bc327a187 100644 --- a/Userland/Libraries/LibWeb/Crypto/SubtleCrypto.cpp +++ b/Userland/Libraries/LibWeb/Crypto/SubtleCrypto.cpp @@ -147,7 +147,7 @@ JS::NonnullGCPtr SubtleCrypto::encrypt(AlgorithmIdentifier cons // 6. Return promise and perform the remaining steps in parallel. - Platform::EventLoopPlugin::the().deferred_invoke([&realm, normalized_algorithm = normalized_algorithm.release_value(), promise, key, data = move(data)]() -> void { + Platform::EventLoopPlugin::the().deferred_invoke(JS::create_heap_function(realm.heap(), [&realm, normalized_algorithm = normalized_algorithm.release_value(), promise, key, data = move(data)]() -> void { HTML::TemporaryExecutionContext context(Bindings::host_defined_environment_settings_object(realm), HTML::TemporaryExecutionContext::CallbacksEnabled::Yes); // 7. If the following steps or referenced procedures say to throw an error, reject promise with the returned error and then terminate the algorithm. @@ -172,7 +172,7 @@ JS::NonnullGCPtr SubtleCrypto::encrypt(AlgorithmIdentifier cons // 9. Resolve promise with ciphertext. WebIDL::resolve_promise(realm, promise, cipher_text.release_value()); - }); + })); return promise; } @@ -204,7 +204,7 @@ JS::NonnullGCPtr SubtleCrypto::decrypt(AlgorithmIdentifier cons // 6. Return promise and perform the remaining steps in parallel. - Platform::EventLoopPlugin::the().deferred_invoke([&realm, normalized_algorithm = normalized_algorithm.release_value(), promise, key, data = move(data)]() -> void { + Platform::EventLoopPlugin::the().deferred_invoke(JS::create_heap_function(realm.heap(), [&realm, normalized_algorithm = normalized_algorithm.release_value(), promise, key, data = move(data)]() -> void { HTML::TemporaryExecutionContext context(Bindings::host_defined_environment_settings_object(realm), HTML::TemporaryExecutionContext::CallbacksEnabled::Yes); // 7. If the following steps or referenced procedures say to throw an error, reject promise with the returned error and then terminate the algorithm. @@ -229,7 +229,7 @@ JS::NonnullGCPtr SubtleCrypto::decrypt(AlgorithmIdentifier cons // 9. Resolve promise with plaintext. WebIDL::resolve_promise(realm, promise, plain_text.release_value()); - }); + })); return promise; } @@ -262,7 +262,7 @@ JS::NonnullGCPtr SubtleCrypto::digest(AlgorithmIdentifier const auto promise = WebIDL::create_promise(realm); // 6. Return promise and perform the remaining steps in parallel. - Platform::EventLoopPlugin::the().deferred_invoke([&realm, algorithm_object = normalized_algorithm.release_value(), promise, data_buffer = move(data_buffer)]() -> void { + Platform::EventLoopPlugin::the().deferred_invoke(JS::create_heap_function(realm.heap(), [&realm, algorithm_object = normalized_algorithm.release_value(), promise, data_buffer = move(data_buffer)]() -> void { HTML::TemporaryExecutionContext context(Bindings::host_defined_environment_settings_object(realm), HTML::TemporaryExecutionContext::CallbacksEnabled::Yes); // 7. If the following steps or referenced procedures say to throw an error, reject promise with the returned error and then terminate the algorithm. // FIXME: Need spec reference to https://webidl.spec.whatwg.org/#reject @@ -277,7 +277,7 @@ JS::NonnullGCPtr SubtleCrypto::digest(AlgorithmIdentifier const // 9. Resolve promise with result. WebIDL::resolve_promise(realm, promise, result.release_value()); - }); + })); return promise; } @@ -302,7 +302,7 @@ JS::ThrowCompletionOr> SubtleCrypto::generate_ auto promise = WebIDL::create_promise(realm); // 5. Return promise and perform the remaining steps in parallel. - Platform::EventLoopPlugin::the().deferred_invoke([&realm, normalized_algorithm = normalized_algorithm.release_value(), promise, extractable, key_usages = move(key_usages)]() -> void { + Platform::EventLoopPlugin::the().deferred_invoke(JS::create_heap_function(realm.heap(), [&realm, normalized_algorithm = normalized_algorithm.release_value(), promise, extractable, key_usages = move(key_usages)]() -> void { HTML::TemporaryExecutionContext context(Bindings::host_defined_environment_settings_object(realm), HTML::TemporaryExecutionContext::CallbacksEnabled::Yes); // 6. If the following steps or referenced procedures say to throw an error, reject promise with // the returned error and then terminate the algorithm. @@ -337,7 +337,7 @@ JS::ThrowCompletionOr> SubtleCrypto::generate_ } WebIDL::resolve_promise(realm, promise, key_pair); }); - }); + })); return promise; } @@ -384,7 +384,7 @@ JS::ThrowCompletionOr> SubtleCrypto::import_ke auto promise = WebIDL::create_promise(realm); // 8. Return promise and perform the remaining steps in parallel. - Platform::EventLoopPlugin::the().deferred_invoke([&realm, real_key_data = move(real_key_data), normalized_algorithm = normalized_algorithm.release_value(), promise, format, extractable, key_usages = move(key_usages), algorithm = move(algorithm)]() mutable -> void { + Platform::EventLoopPlugin::the().deferred_invoke(JS::create_heap_function(heap(), [&realm, real_key_data = move(real_key_data), normalized_algorithm = normalized_algorithm.release_value(), promise, format, extractable, key_usages = move(key_usages), algorithm = move(algorithm)]() mutable -> void { HTML::TemporaryExecutionContext context(Bindings::host_defined_environment_settings_object(realm), HTML::TemporaryExecutionContext::CallbacksEnabled::Yes); // 9. If the following steps or referenced procedures say to throw an error, reject promise with the returned error and then terminate the algorithm. @@ -413,7 +413,7 @@ JS::ThrowCompletionOr> SubtleCrypto::import_ke // 14. Resolve promise with result. WebIDL::resolve_promise(realm, promise, result); - }); + })); return promise; } @@ -428,7 +428,7 @@ JS::ThrowCompletionOr> SubtleCrypto::export_ke auto promise = WebIDL::create_promise(realm); // 3. Return promise and perform the remaining steps in parallel. - Platform::EventLoopPlugin::the().deferred_invoke([&realm, key, promise, format]() -> void { + Platform::EventLoopPlugin::the().deferred_invoke(JS::create_heap_function(heap(), [&realm, key, promise, format]() -> void { HTML::TemporaryExecutionContext context(Bindings::host_defined_environment_settings_object(realm), HTML::TemporaryExecutionContext::CallbacksEnabled::Yes); // 4. If the following steps or referenced procedures say to throw an error, reject promise with the returned error and then terminate the algorithm. @@ -459,7 +459,7 @@ JS::ThrowCompletionOr> SubtleCrypto::export_ke // 8. Resolve promise with result. WebIDL::resolve_promise(realm, promise, result_or_error.release_value()); - }); + })); return promise; } @@ -491,7 +491,7 @@ JS::ThrowCompletionOr> SubtleCrypto::sign(Algo // 6. Return promise and perform the remaining steps in parallel. - Platform::EventLoopPlugin::the().deferred_invoke([&realm, normalized_algorithm = normalized_algorithm.release_value(), promise, key, data = move(data)]() -> void { + Platform::EventLoopPlugin::the().deferred_invoke(JS::create_heap_function(realm.heap(), [&realm, normalized_algorithm = normalized_algorithm.release_value(), promise, key, data = move(data)]() -> void { HTML::TemporaryExecutionContext context(Bindings::host_defined_environment_settings_object(realm), HTML::TemporaryExecutionContext::CallbacksEnabled::Yes); // 7. If the following steps or referenced procedures say to throw an error, reject promise with the returned error and then terminate the algorithm. @@ -516,7 +516,7 @@ JS::ThrowCompletionOr> SubtleCrypto::sign(Algo // 9. Resolve promise with result. WebIDL::resolve_promise(realm, promise, result.release_value()); - }); + })); return promise; } @@ -555,7 +555,7 @@ JS::ThrowCompletionOr> SubtleCrypto::verify(Al auto promise = WebIDL::create_promise(realm); // 7. Return promise and perform the remaining steps in parallel. - Platform::EventLoopPlugin::the().deferred_invoke([&realm, normalized_algorithm = normalized_algorithm.release_value(), promise, key, signature = move(signature), data = move(data)]() -> void { + Platform::EventLoopPlugin::the().deferred_invoke(JS::create_heap_function(realm.heap(), [&realm, normalized_algorithm = normalized_algorithm.release_value(), promise, key, signature = move(signature), data = move(data)]() -> void { HTML::TemporaryExecutionContext context(Bindings::host_defined_environment_settings_object(realm), HTML::TemporaryExecutionContext::CallbacksEnabled::Yes); // 8. If the following steps or referenced procedures say to throw an error, reject promise with the returned error and then terminate the algorithm. @@ -580,7 +580,7 @@ JS::ThrowCompletionOr> SubtleCrypto::verify(Al // 12. Resolve promise with result. WebIDL::resolve_promise(realm, promise, result.release_value()); - }); + })); return promise; } @@ -602,7 +602,7 @@ JS::ThrowCompletionOr> SubtleCrypto::derive_bi auto promise = WebIDL::create_promise(realm); // 5. Return promise and perform the remaining steps in parallel. - Platform::EventLoopPlugin::the().deferred_invoke([&realm, normalized_algorithm = normalized_algorithm.release_value(), promise, base_key, length]() -> void { + Platform::EventLoopPlugin::the().deferred_invoke(JS::create_heap_function(realm.heap(), [&realm, normalized_algorithm = normalized_algorithm.release_value(), promise, base_key, length]() -> void { HTML::TemporaryExecutionContext context(Bindings::host_defined_environment_settings_object(realm), HTML::TemporaryExecutionContext::CallbacksEnabled::Yes); // 6. If the following steps or referenced procedures say to throw an error, reject promise with the returned error and then terminate the algorithm. @@ -627,7 +627,7 @@ JS::ThrowCompletionOr> SubtleCrypto::derive_bi // 10. Resolve promise with result. WebIDL::resolve_promise(realm, promise, result.release_value()); - }); + })); return promise; } @@ -663,7 +663,7 @@ JS::ThrowCompletionOr> SubtleCrypto::derive_ke auto promise = WebIDL::create_promise(realm); // 9. Return promise and perform the remaining steps in parallel. - Platform::EventLoopPlugin::the().deferred_invoke([&realm, &vm, normalized_algorithm = normalized_algorithm.release_value(), promise, normalized_derived_key_algorithm_import = normalized_derived_key_algorithm_import.release_value(), normalized_derived_key_algorithm_length = normalized_derived_key_algorithm_length.release_value(), base_key = move(base_key), extractable, key_usages = move(key_usages)]() -> void { + Platform::EventLoopPlugin::the().deferred_invoke(JS::create_heap_function(realm.heap(), [&realm, &vm, normalized_algorithm = normalized_algorithm.release_value(), promise, normalized_derived_key_algorithm_import = normalized_derived_key_algorithm_import.release_value(), normalized_derived_key_algorithm_length = normalized_derived_key_algorithm_length.release_value(), base_key = move(base_key), extractable, key_usages = move(key_usages)]() -> void { HTML::TemporaryExecutionContext context(Bindings::host_defined_environment_settings_object(realm), HTML::TemporaryExecutionContext::CallbacksEnabled::Yes); // 10. If the following steps or referenced procedures say to throw an error, reject promise with the returned error and then terminate the algorithm. @@ -720,7 +720,7 @@ JS::ThrowCompletionOr> SubtleCrypto::derive_ke // 17. Resolve promise with result. WebIDL::resolve_promise(realm, promise, result.release_value()); - }); + })); return promise; } diff --git a/Userland/Libraries/LibWeb/DOM/DocumentLoading.cpp b/Userland/Libraries/LibWeb/DOM/DocumentLoading.cpp index 684a7b6e3a3..458bc4d116e 100644 --- a/Userland/Libraries/LibWeb/DOM/DocumentLoading.cpp +++ b/Userland/Libraries/LibWeb/DOM/DocumentLoading.cpp @@ -92,10 +92,10 @@ static WebIDL::ExceptionOr> load_html_document(H else { // FIXME: Parse as we receive the document data, instead of waiting for the whole document to be fetched first. auto process_body = JS::create_heap_function(document->heap(), [document, url = navigation_params.response->url().value(), mime_type = navigation_params.response->header_list()->extract_mime_type()](ByteBuffer data) { - Platform::EventLoopPlugin::the().deferred_invoke([document = document, data = move(data), url = url, mime_type] { + Platform::EventLoopPlugin::the().deferred_invoke(JS::create_heap_function(document->heap(), [document = document, data = move(data), url = url, mime_type] { auto parser = HTML::HTMLParser::create_with_uncertain_encoding(document, data, mime_type); parser->run(url); - }); + })); }); auto process_body_error = JS::create_heap_function(document->heap(), [](JS::Value) { diff --git a/Userland/Libraries/LibWeb/Fetch/BodyInit.cpp b/Userland/Libraries/LibWeb/Fetch/BodyInit.cpp index 3509c22e83b..a8fd43781ab 100644 --- a/Userland/Libraries/LibWeb/Fetch/BodyInit.cpp +++ b/Userland/Libraries/LibWeb/Fetch/BodyInit.cpp @@ -145,7 +145,7 @@ WebIDL::ExceptionOr extract_body(JS::Realm& realm, // 12. If action is non-null, then run these steps in parallel: if (action) { - Platform::EventLoopPlugin::the().deferred_invoke([&realm, stream, action = move(action)] { + Platform::EventLoopPlugin::the().deferred_invoke(JS::create_heap_function(realm.heap(), [&realm, stream, action = move(action)] { HTML::TemporaryExecutionContext execution_context { Bindings::host_defined_environment_settings_object(realm), HTML::TemporaryExecutionContext::CallbacksEnabled::Yes }; // 1. Run action. @@ -162,7 +162,7 @@ WebIDL::ExceptionOr extract_body(JS::Realm& realm, // When running action is done, close stream. stream->close(); - }); + })); } // 13. Let body be a body whose stream is stream, source is source, and length is length. diff --git a/Userland/Libraries/LibWeb/Fetch/Fetching/Fetching.cpp b/Userland/Libraries/LibWeb/Fetch/Fetching/Fetching.cpp index 8874fa2640f..4991efa425d 100644 --- a/Userland/Libraries/LibWeb/Fetch/Fetching/Fetching.cpp +++ b/Userland/Libraries/LibWeb/Fetch/Fetching/Fetching.cpp @@ -440,7 +440,7 @@ WebIDL::ExceptionOr> main_fetch(JS::Realm& realm, Inf } // 11. If recursive is false, then run the remaining steps in parallel. - Platform::EventLoopPlugin::the().deferred_invoke([&realm, &vm, &fetch_params, request, response, get_response = move(get_response)] { + Platform::EventLoopPlugin::the().deferred_invoke(JS::create_heap_function(realm.heap(), [&realm, &vm, &fetch_params, request, response, get_response = move(get_response)] { // 12. If response is null, then set response to the result of running the steps corresponding to the first // matching statement: auto pending_response = PendingResponse::create(vm, request, Infrastructure::Response::create(vm)); @@ -589,7 +589,7 @@ WebIDL::ExceptionOr> main_fetch(JS::Realm& realm, Inf fetch_response_handover(realm, fetch_params, *response); } }); - }); + })); return JS::GCPtr {}; } @@ -1920,9 +1920,9 @@ WebIDL::ExceptionOr> http_network_or_cache_fet revalidate_request->set_service_workers_mode(Infrastructure::Request::ServiceWorkersMode::None); // 7. In parallel, run main fetch given a new fetch params whose request is revalidateRequest. - Platform::EventLoopPlugin::the().deferred_invoke([&vm, &realm, revalidate_request, fetch_params = JS::NonnullGCPtr(fetch_params)] { + Platform::EventLoopPlugin::the().deferred_invoke(JS::create_heap_function(realm.heap(), [&vm, &realm, revalidate_request, fetch_params = JS::NonnullGCPtr(fetch_params)] { (void)main_fetch(realm, Infrastructure::FetchParams::create(vm, revalidate_request, fetch_params->timing_info())); - }); + })); } // 2. Otherwise: else { diff --git a/Userland/Libraries/LibWeb/Fetch/Fetching/PendingResponse.cpp b/Userland/Libraries/LibWeb/Fetch/Fetching/PendingResponse.cpp index 1b4b8fde8d0..9f8abff8064 100644 --- a/Userland/Libraries/LibWeb/Fetch/Fetching/PendingResponse.cpp +++ b/Userland/Libraries/LibWeb/Fetch/Fetching/PendingResponse.cpp @@ -59,12 +59,12 @@ void PendingResponse::run_callback() { VERIFY(m_callback); VERIFY(m_response); - Platform::EventLoopPlugin::the().deferred_invoke([this] { + Platform::EventLoopPlugin::the().deferred_invoke(JS::create_heap_function(heap(), [this] { VERIFY(m_callback); VERIFY(m_response); m_callback->function()(*m_response); m_request->remove_pending_response({}, *this); - }); + })); } } diff --git a/Userland/Libraries/LibWeb/FileAPI/FileReader.cpp b/Userland/Libraries/LibWeb/FileAPI/FileReader.cpp index 29c225e89b5..b4603e18df8 100644 --- a/Userland/Libraries/LibWeb/FileAPI/FileReader.cpp +++ b/Userland/Libraries/LibWeb/FileAPI/FileReader.cpp @@ -146,7 +146,7 @@ WebIDL::ExceptionOr FileReader::read_operation(Blob& blob, Type type, Opti bool is_first_chunk = true; // 10. In parallel, while true: - Platform::EventLoopPlugin::the().deferred_invoke([this, chunk_promise, reader, bytes, is_first_chunk, &realm, type, encoding_name, blobs_type]() mutable { + Platform::EventLoopPlugin::the().deferred_invoke(JS::create_heap_function(heap(), [this, chunk_promise, reader, bytes, is_first_chunk, &realm, type, encoding_name, blobs_type]() mutable { HTML::TemporaryExecutionContext execution_context { Bindings::host_defined_environment_settings_object(realm), HTML::TemporaryExecutionContext::CallbacksEnabled::Yes }; Optional progress_timer; @@ -257,7 +257,7 @@ WebIDL::ExceptionOr FileReader::read_operation(Blob& blob, Type type, Opti return; } } - }); + })); return {}; } diff --git a/Userland/Libraries/LibWeb/HTML/HTMLCanvasElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLCanvasElement.cpp index ebdc90843f9..2b9e32ad2c1 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLCanvasElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLCanvasElement.cpp @@ -297,7 +297,7 @@ WebIDL::ExceptionOr HTMLCanvasElement::to_blob(JS::NonnullGCPtrclone()); // 4. Run these steps in parallel: - Platform::EventLoopPlugin::the().deferred_invoke([this, callback, bitmap_result, type, quality] { + Platform::EventLoopPlugin::the().deferred_invoke(JS::create_heap_function(heap(), [this, callback, bitmap_result, type, quality] { // 1. If result is non-null, then set result to a serialization of result as a file with type and quality if given. Optional file_result; if (bitmap_result) { @@ -320,7 +320,7 @@ WebIDL::ExceptionOr HTMLCanvasElement::to_blob(JS::NonnullGCPtr> HTMLImageElement::decode( return; // 2.2 Otherwise, in parallel wait for one of the following cases to occur, and perform the corresponding actions: - Platform::EventLoopPlugin::the().deferred_invoke([this, promise, &realm, reject_if_document_not_fully_active, reject_if_current_request_state_broken] { + Platform::EventLoopPlugin::the().deferred_invoke(JS::create_heap_function(heap(), [this, promise, &realm, reject_if_document_not_fully_active, reject_if_current_request_state_broken] { Platform::EventLoopPlugin::the().spin_until(JS::create_heap_function(heap(), [&] { auto state = this->current_request().state(); @@ -357,7 +357,7 @@ WebIDL::ExceptionOr> HTMLImageElement::decode( HTML::TemporaryExecutionContext context(HTML::relevant_settings_object(*this)); WebIDL::resolve_promise(realm, promise, JS::js_undefined()); } - }); + })); })); return promise; diff --git a/Userland/Libraries/LibWeb/HTML/Navigable.cpp b/Userland/Libraries/LibWeb/HTML/Navigable.cpp index 1b8ce929aea..57a5d914109 100644 --- a/Userland/Libraries/LibWeb/HTML/Navigable.cpp +++ b/Userland/Libraries/LibWeb/HTML/Navigable.cpp @@ -1401,7 +1401,7 @@ WebIDL::ExceptionOr Navigable::navigate(NavigateParams params) } // 20. In parallel, run these steps: - Platform::EventLoopPlugin::the().deferred_invoke([this, source_snapshot_params, target_snapshot_params, csp_navigation_type, document_resource, url, navigation_id, referrer_policy, initiator_origin_snapshot, response, history_handling, initiator_base_url_snapshot] { + Platform::EventLoopPlugin::the().deferred_invoke(JS::create_heap_function(heap(), [this, source_snapshot_params, target_snapshot_params, csp_navigation_type, document_resource, url, navigation_id, referrer_policy, initiator_origin_snapshot, response, history_handling, initiator_base_url_snapshot] { // AD-HOC: Not in the spec but subsequent steps will fail if the navigable doesn't have an active window. if (!active_window()) { set_delaying_load_events(false); @@ -1489,7 +1489,7 @@ WebIDL::ExceptionOr Navigable::navigate(NavigateParams params) finalize_a_cross_document_navigation(*this, to_history_handling_behavior(history_handling), history_entry); })); })).release_value_but_fixme_should_propagate_errors(); - }); + })); return {}; } diff --git a/Userland/Libraries/LibWeb/HTML/TraversableNavigable.cpp b/Userland/Libraries/LibWeb/HTML/TraversableNavigable.cpp index 4ca0f5818a0..a9d4fe26f1b 100644 --- a/Userland/Libraries/LibWeb/HTML/TraversableNavigable.cpp +++ b/Userland/Libraries/LibWeb/HTML/TraversableNavigable.cpp @@ -146,14 +146,14 @@ WebIDL::ExceptionOr> TraversableNavigable // Skip the initial navigation as well. This matches the behavior of the window open steps. if (url_matches_about_blank(initial_navigation_url)) { - Platform::EventLoopPlugin::the().deferred_invoke([traversable, initial_navigation_url] { + Platform::EventLoopPlugin::the().deferred_invoke(JS::create_heap_function(traversable->heap(), [traversable, initial_navigation_url] { // FIXME: We do this other places too when creating a new about:blank document. Perhaps it's worth a spec issue? HTML::HTMLParser::the_end(*traversable->active_document()); // FIXME: If we perform the URL and history update steps here, we start hanging tests and the UI process will // try to load() the initial URLs passed on the command line before we finish processing the events here. // However, because we call this before the PageClient is fully initialized... that gets awkward. - }); + })); } else { @@ -642,7 +642,7 @@ TraversableNavigable::HistoryStepResult TraversableNavigable::apply_the_history_ // 7. In parallel, attempt to populate the history entry's document for targetEntry, given navigable, potentiallyTargetSpecificSourceSnapshotParams, // targetSnapshotParams, with allowPOST set to allowPOST and completionSteps set to queue a global task on the navigation and traversal task source given // navigable's active window to run afterDocumentPopulated. - Platform::EventLoopPlugin::the().deferred_invoke([populated_target_entry, potentially_target_specific_source_snapshot_params, target_snapshot_params, this, allow_POST, navigable, after_document_populated = JS::create_heap_function(this->heap(), move(after_document_populated))] { + Platform::EventLoopPlugin::the().deferred_invoke(JS::create_heap_function(this->heap(), [populated_target_entry, potentially_target_specific_source_snapshot_params, target_snapshot_params, this, allow_POST, navigable, after_document_populated = JS::create_heap_function(this->heap(), move(after_document_populated))] { navigable->populate_session_history_entry_document(populated_target_entry, *potentially_target_specific_source_snapshot_params, target_snapshot_params, {}, Empty {}, CSPNavigationType::Other, allow_POST, JS::create_heap_function(this->heap(), [this, after_document_populated, populated_target_entry]() mutable { VERIFY(active_window()); queue_global_task(Task::Source::NavigationAndTraversal, *active_window(), JS::create_heap_function(this->heap(), [after_document_populated, populated_target_entry]() mutable { @@ -650,7 +650,7 @@ TraversableNavigable::HistoryStepResult TraversableNavigable::apply_the_history_ })); })) .release_value_but_fixme_should_propagate_errors(); - }); + })); } // Otherwise, run afterDocumentPopulated immediately. else { diff --git a/Userland/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.cpp b/Userland/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.cpp index e618fb0aed3..ccf672f4b0d 100644 --- a/Userland/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.cpp +++ b/Userland/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.cpp @@ -210,7 +210,7 @@ JS::NonnullGCPtr WindowOrWorkerGlobalScopeMixin::create_image_b image.visit( [&](JS::Handle& blob) { // Run these step in parallel: - Platform::EventLoopPlugin::the().deferred_invoke([=]() { + Platform::EventLoopPlugin::the().deferred_invoke(JS::create_heap_function(realm.heap(), [=]() { // 1. Let imageData be the result of reading image's data. If an error occurs during reading of the // object, then reject p with an "InvalidStateError" DOMException and abort these steps. // FIXME: I guess this is always fine for us as the data is already read. @@ -246,7 +246,7 @@ JS::NonnullGCPtr WindowOrWorkerGlobalScopeMixin::create_image_b }; (void)Web::Platform::ImageCodecPlugin::the().decode_image(image_data, move(on_successful_decode), move(on_failed_decode)); - }); + })); }, [&](auto&) { dbgln("(STUBBED) createImageBitmap() for non-blob types"); diff --git a/Userland/Libraries/LibWeb/Loader/Resource.cpp b/Userland/Libraries/LibWeb/Loader/Resource.cpp index 98c94dacf96..395ae3cb0c4 100644 --- a/Userland/Libraries/LibWeb/Loader/Resource.cpp +++ b/Userland/Libraries/LibWeb/Loader/Resource.cpp @@ -159,7 +159,7 @@ void ResourceClient::set_resource(Resource* resource) // This ensures that these callbacks always happen in a consistent way, instead of being invoked // synchronously in some cases, and asynchronously in others. if (resource->is_loaded() || resource->is_failed()) { - Platform::EventLoopPlugin::the().deferred_invoke([weak_this = make_weak_ptr(), strong_resource = NonnullRefPtr { *m_resource }] { + Platform::EventLoopPlugin::the().deferred_invoke(JS::create_heap_function(ResourceLoader::the().heap(), [weak_this = make_weak_ptr(), strong_resource = NonnullRefPtr { *m_resource }] { if (!weak_this) return; @@ -177,7 +177,7 @@ void ResourceClient::set_resource(Resource* resource) weak_this->resource_did_fail(); return; } - }); + })); } } } diff --git a/Userland/Libraries/LibWeb/Loader/ResourceLoader.cpp b/Userland/Libraries/LibWeb/Loader/ResourceLoader.cpp index 1ffb8a769e7..ba772873ad4 100644 --- a/Userland/Libraries/LibWeb/Loader/ResourceLoader.cpp +++ b/Userland/Libraries/LibWeb/Loader/ResourceLoader.cpp @@ -278,9 +278,9 @@ void ResourceLoader::load(LoadRequest& request, SuccessCallback success_callback return; } - Platform::EventLoopPlugin::the().deferred_invoke([success_callback = move(success_callback), response_headers = move(response_headers)] { + Platform::EventLoopPlugin::the().deferred_invoke(JS::create_heap_function(m_heap, [success_callback = move(success_callback), response_headers = move(response_headers)] { success_callback(ByteString::empty().to_byte_buffer(), response_headers, {}); - }); + })); return; } @@ -303,9 +303,9 @@ void ResourceLoader::load(LoadRequest& request, SuccessCallback success_callback log_success(request); - Platform::EventLoopPlugin::the().deferred_invoke([data = move(data_url.body), response_headers = move(response_headers), success_callback = move(success_callback)] { + Platform::EventLoopPlugin::the().deferred_invoke(JS::create_heap_function(m_heap, [data = move(data_url.body), response_headers = move(response_headers), success_callback = move(success_callback)] { success_callback(data, response_headers, {}); - }); + })); return; } @@ -560,9 +560,9 @@ void ResourceLoader::finish_network_request(NonnullRefPtr con if (on_load_counter_change) on_load_counter_change(); - Platform::EventLoopPlugin::the().deferred_invoke([this, protocol_request] { + Platform::EventLoopPlugin::the().deferred_invoke(JS::create_heap_function(m_heap, [this, protocol_request] { m_active_requests.remove(protocol_request); - }); + })); } void ResourceLoader::clear_cache() diff --git a/Userland/Libraries/LibWeb/Platform/EventLoopPlugin.h b/Userland/Libraries/LibWeb/Platform/EventLoopPlugin.h index d3ed6182c9f..4630ed40d40 100644 --- a/Userland/Libraries/LibWeb/Platform/EventLoopPlugin.h +++ b/Userland/Libraries/LibWeb/Platform/EventLoopPlugin.h @@ -22,7 +22,7 @@ public: virtual ~EventLoopPlugin(); virtual void spin_until(JS::Handle> goal_condition) = 0; - virtual void deferred_invoke(ESCAPING JS::SafeFunction) = 0; + virtual void deferred_invoke(ESCAPING JS::Handle>) = 0; virtual JS::NonnullGCPtr create_timer(JS::Heap&) = 0; virtual void quit() = 0; }; diff --git a/Userland/Libraries/LibWeb/Platform/EventLoopPluginSerenity.cpp b/Userland/Libraries/LibWeb/Platform/EventLoopPluginSerenity.cpp index c5acd37e78b..721712bf98a 100644 --- a/Userland/Libraries/LibWeb/Platform/EventLoopPluginSerenity.cpp +++ b/Userland/Libraries/LibWeb/Platform/EventLoopPluginSerenity.cpp @@ -21,10 +21,12 @@ void EventLoopPluginSerenity::spin_until(JS::Handle> go }); } -void EventLoopPluginSerenity::deferred_invoke(JS::SafeFunction function) +void EventLoopPluginSerenity::deferred_invoke(JS::Handle> function) { VERIFY(function); - Core::deferred_invoke(move(function)); + Core::deferred_invoke([function = move(function)]() { + function->function()(); + }); } JS::NonnullGCPtr EventLoopPluginSerenity::create_timer(JS::Heap& heap) diff --git a/Userland/Libraries/LibWeb/Platform/EventLoopPluginSerenity.h b/Userland/Libraries/LibWeb/Platform/EventLoopPluginSerenity.h index ff29ba267d2..94b9048b402 100644 --- a/Userland/Libraries/LibWeb/Platform/EventLoopPluginSerenity.h +++ b/Userland/Libraries/LibWeb/Platform/EventLoopPluginSerenity.h @@ -16,7 +16,7 @@ public: virtual ~EventLoopPluginSerenity() override; virtual void spin_until(JS::Handle> goal_condition) override; - virtual void deferred_invoke(JS::SafeFunction) override; + virtual void deferred_invoke(JS::Handle>) override; virtual JS::NonnullGCPtr create_timer(JS::Heap&) override; virtual void quit() override; }; diff --git a/Userland/Libraries/LibWeb/WebDriver/ExecuteScript.cpp b/Userland/Libraries/LibWeb/WebDriver/ExecuteScript.cpp index 0d9ba610c1f..e43beac9098 100644 --- a/Userland/Libraries/LibWeb/WebDriver/ExecuteScript.cpp +++ b/Userland/Libraries/LibWeb/WebDriver/ExecuteScript.cpp @@ -346,7 +346,7 @@ void execute_script(HTML::BrowsingContext const& browsing_context, ByteString bo auto promise = WebIDL::create_promise(realm); // 8. Run the following substeps in parallel: - Platform::EventLoopPlugin::the().deferred_invoke([&realm, &browsing_context, promise, document, body = move(body), arguments = move(arguments)]() mutable { + Platform::EventLoopPlugin::the().deferred_invoke(JS::create_heap_function(realm.heap(), [&realm, &browsing_context, promise, document, body = move(body), arguments = move(arguments)]() mutable { HTML::TemporaryExecutionContext execution_context { document->relevant_settings_object() }; // 1. Let scriptPromise be the result of promise-calling execute a function body, with arguments body and arguments. @@ -362,7 +362,7 @@ void execute_script(HTML::BrowsingContext const& browsing_context, ByteString bo if (script_result.is_throw_completion()) { WebIDL::reject_promise(realm, promise, *script_result.throw_completion().value()); } - }); + })); // 9. Wait until promise is resolved, or timer's timeout fired flag is set, whichever occurs first. auto reaction_steps = JS::create_heap_function(vm.heap(), [&realm, &browsing_context, promise, timer, on_complete](JS::Value) -> WebIDL::ExceptionOr { @@ -425,7 +425,7 @@ void execute_async_script(HTML::BrowsingContext const& browsing_context, ByteStr JS::NonnullGCPtr promise { verify_cast(*promise_capability->promise()) }; // 8. Run the following substeps in parallel: - Platform::EventLoopPlugin::the().deferred_invoke([&vm, &realm, &browsing_context, timer, document, promise_capability, promise, body = move(body), arguments = move(arguments)]() mutable { + Platform::EventLoopPlugin::the().deferred_invoke(JS::create_heap_function(realm.heap(), [&vm, &realm, &browsing_context, timer, document, promise_capability, promise, body = move(body), arguments = move(arguments)]() mutable { HTML::TemporaryExecutionContext execution_context { document->relevant_settings_object() }; // 1. Let resolvingFunctions be CreateResolvingFunctions(promise). @@ -481,7 +481,7 @@ void execute_async_script(HTML::BrowsingContext const& browsing_context, ByteStr // 11. Upon rejection of scriptPromise with value r, reject promise with value r. if (script_promise.state() == JS::Promise::State::Rejected) WebIDL::reject_promise(realm, promise_capability, script_promise.result()); - }); + })); // 9. Wait until promise is resolved, or timer's timeout fired flag is set, whichever occurs first. auto reaction_steps = JS::create_heap_function(vm.heap(), [&realm, &browsing_context, promise, timer, on_complete](JS::Value) -> WebIDL::ExceptionOr {