Przeglądaj źródła

LibWeb: Use HeapFunction for EventLoopPlugin::spin_until

Shannon Booth 9 miesięcy temu
rodzic
commit
7487a782db

+ 2 - 2
Userland/Libraries/LibJS/Runtime/Completion.cpp

@@ -101,9 +101,9 @@ ThrowCompletionOr<Value> await(VM& vm, Value value)
     //        running all queued promise jobs.
     // Note: This is not used by LibJS itself, and is performed for the embedder (i.e. LibWeb).
     if (auto* custom_data = vm.custom_data()) {
-        custom_data->spin_event_loop_until([&] {
+        custom_data->spin_event_loop_until(create_heap_function(vm.heap(), [success] {
             return success.has_value();
-        });
+        }));
     }
 
     // 8. Remove asyncContext from the execution context stack and restore the execution context that is at the top of the execution context stack as the running execution context.

+ 1 - 1
Userland/Libraries/LibJS/Runtime/VM.h

@@ -42,7 +42,7 @@ public:
     struct CustomData {
         virtual ~CustomData() = default;
 
-        virtual void spin_event_loop_until(JS::SafeFunction<bool()> goal_condition) = 0;
+        virtual void spin_event_loop_until(JS::Handle<JS::HeapFunction<bool()>> goal_condition) = 0;
     };
 
     static ErrorOr<NonnullRefPtr<VM>> create(OwnPtr<CustomData> = {});

+ 1 - 1
Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp

@@ -658,7 +658,7 @@ NonnullOwnPtr<JS::ExecutionContext> create_a_new_javascript_realm(JS::VM& vm, Fu
     return realm_execution_context;
 }
 
-void WebEngineCustomData::spin_event_loop_until(JS::SafeFunction<bool()> goal_condition)
+void WebEngineCustomData::spin_event_loop_until(JS::Handle<JS::HeapFunction<bool()>> goal_condition)
 {
     Platform::EventLoopPlugin::the().spin_until(move(goal_condition));
 }

+ 1 - 1
Userland/Libraries/LibWeb/Bindings/MainThreadVM.h

@@ -38,7 +38,7 @@ struct CustomElementReactionsStack {
 struct WebEngineCustomData final : public JS::VM::CustomData {
     virtual ~WebEngineCustomData() override = default;
 
-    virtual void spin_event_loop_until(JS::SafeFunction<bool()> goal_condition) override;
+    virtual void spin_event_loop_until(JS::Handle<JS::HeapFunction<bool()>> goal_condition) override;
 
     JS::Handle<HTML::EventLoop> event_loop;
 

+ 2 - 2
Userland/Libraries/LibWeb/FileAPI/FileReader.cpp

@@ -157,9 +157,9 @@ WebIDL::ExceptionOr<void> FileReader::read_operation(Blob& blob, Type type, Opti
 
             // 1. Wait for chunkPromise to be fulfilled or rejected.
             // FIXME: Create spec issue to use WebIDL react to promise steps here instead of this custom logic
-            Platform::EventLoopPlugin::the().spin_until([&]() {
+            Platform::EventLoopPlugin::the().spin_until(JS::create_heap_function(heap(), [promise]() {
                 return promise->state() == JS::Promise::State::Fulfilled || promise->state() == JS::Promise::State::Rejected;
-            });
+            }));
 
             // 2. If chunkPromise is fulfilled, and isFirstChunk is true, queue a task to fire a progress event called loadstart at fr.
             // NOTE: ISSUE 2 We might change loadstart to be dispatched synchronously, to align with XMLHttpRequest behavior. [Issue #119]

+ 4 - 4
Userland/Libraries/LibWeb/HTML/EventLoop/EventLoop.cpp

@@ -92,7 +92,7 @@ void EventLoop::spin_until(JS::SafeFunction<bool()> goal_condition)
     //       2. Perform any steps that appear after this spin the event loop instance in the original algorithm.
     //       NOTE: This is achieved by returning from the function.
 
-    Platform::EventLoopPlugin::the().spin_until([&] {
+    Platform::EventLoopPlugin::the().spin_until(JS::create_heap_function(heap(), [&] {
         if (goal_condition())
             return true;
         if (m_task_queue->has_runnable_tasks()) {
@@ -101,7 +101,7 @@ void EventLoop::spin_until(JS::SafeFunction<bool()> goal_condition)
             Core::EventLoop::current().wake();
         }
         return goal_condition();
-    });
+    }));
 
     vm.restore_execution_context_stack();
 
@@ -120,7 +120,7 @@ void EventLoop::spin_processing_tasks_with_source_until(Task::Source source, JS:
     // NOTE: HTML event loop processing steps could run a task with arbitrary source
     m_skip_event_loop_processing_steps = true;
 
-    Platform::EventLoopPlugin::the().spin_until([&] {
+    Platform::EventLoopPlugin::the().spin_until(JS::create_heap_function(heap(), [&] {
         if (goal_condition())
             return true;
         if (m_task_queue->has_runnable_tasks()) {
@@ -138,7 +138,7 @@ void EventLoop::spin_processing_tasks_with_source_until(Task::Source source, JS:
         // FIXME: Remove the platform event loop plugin so that this doesn't look out of place
         Core::EventLoop::current().wake();
         return goal_condition();
-    });
+    }));
 
     m_skip_event_loop_processing_steps = false;
 

+ 2 - 2
Userland/Libraries/LibWeb/HTML/HTMLImageElement.cpp

@@ -324,11 +324,11 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> HTMLImageElement::decode(
 
         // 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().spin_until([&] {
+            Platform::EventLoopPlugin::the().spin_until(JS::create_heap_function(heap(), [&] {
                 auto state = this->current_request().state();
 
                 return !this->document().is_fully_active() || state == ImageRequest::State::Broken || state == ImageRequest::State::CompletelyAvailable;
-            });
+            }));
 
             // 2.2.1 This img element's node document stops being fully active
             // 2.2.1 Reject promise with an "EncodingError" DOMException.

+ 2 - 2
Userland/Libraries/LibWeb/Page/Page.cpp

@@ -269,9 +269,9 @@ static ResponseType spin_event_loop_until_dialog_closed(PageClient& client, Opti
     ScopeGuard guard { [&] { event_loop.set_execution_paused(false); } };
     event_loop.set_execution_paused(true);
 
-    Web::Platform::EventLoopPlugin::the().spin_until([&]() {
+    Web::Platform::EventLoopPlugin::the().spin_until(JS::create_heap_function(event_loop.heap(), [&]() {
         return response.has_value() || !client.is_connection_open();
-    });
+    }));
 
     if (!client.is_connection_open()) {
         dbgln("WebContent client disconnected during {}. Exiting peacefully.", location.function_name());

+ 2 - 1
Userland/Libraries/LibWeb/Platform/EventLoopPlugin.h

@@ -8,6 +8,7 @@
 
 #include <AK/Forward.h>
 #include <LibJS/Heap/GCPtr.h>
+#include <LibJS/Heap/HeapFunction.h>
 #include <LibJS/SafeFunction.h>
 #include <LibWeb/Forward.h>
 
@@ -20,7 +21,7 @@ public:
 
     virtual ~EventLoopPlugin();
 
-    virtual void spin_until(JS::SafeFunction<bool()> goal_condition) = 0;
+    virtual void spin_until(JS::Handle<JS::HeapFunction<bool()>> goal_condition) = 0;
     virtual void deferred_invoke(ESCAPING JS::SafeFunction<void()>) = 0;
     virtual JS::NonnullGCPtr<Timer> create_timer(JS::Heap&) = 0;
     virtual void quit() = 0;

+ 4 - 2
Userland/Libraries/LibWeb/Platform/EventLoopPluginSerenity.cpp

@@ -14,9 +14,11 @@ namespace Web::Platform {
 EventLoopPluginSerenity::EventLoopPluginSerenity() = default;
 EventLoopPluginSerenity::~EventLoopPluginSerenity() = default;
 
-void EventLoopPluginSerenity::spin_until(JS::SafeFunction<bool()> goal_condition)
+void EventLoopPluginSerenity::spin_until(JS::Handle<JS::HeapFunction<bool()>> goal_condition)
 {
-    Core::EventLoop::current().spin_until(move(goal_condition));
+    Core::EventLoop::current().spin_until([goal_condition = move(goal_condition)]() {
+        return goal_condition->function()();
+    });
 }
 
 void EventLoopPluginSerenity::deferred_invoke(JS::SafeFunction<void()> function)

+ 1 - 1
Userland/Libraries/LibWeb/Platform/EventLoopPluginSerenity.h

@@ -15,7 +15,7 @@ public:
     EventLoopPluginSerenity();
     virtual ~EventLoopPluginSerenity() override;
 
-    virtual void spin_until(JS::SafeFunction<bool()> goal_condition) override;
+    virtual void spin_until(JS::Handle<JS::HeapFunction<bool()>> goal_condition) override;
     virtual void deferred_invoke(JS::SafeFunction<void()>) override;
     virtual JS::NonnullGCPtr<Timer> create_timer(JS::Heap&) override;
     virtual void quit() override;

+ 2 - 2
Userland/Libraries/LibWeb/WebDriver/ExecuteScript.cpp

@@ -470,9 +470,9 @@ void execute_async_script(HTML::BrowsingContext const& browsing_context, ByteStr
             return;
         auto& script_promise = static_cast<JS::Promise&>(*script_promise_or_error.value());
 
-        vm.custom_data()->spin_event_loop_until([&] {
+        vm.custom_data()->spin_event_loop_until(JS::create_heap_function(vm.heap(), [timer, &script_promise]() {
             return timer->is_timed_out() || script_promise.state() != JS::Promise::State::Pending;
-        });
+        }));
 
         // 10. Upon fulfillment of scriptPromise with value v, resolve promise with value v.
         if (script_promise.state() == JS::Promise::State::Fulfilled)

+ 1 - 1
Userland/Libraries/LibWeb/WebDriver/Screenshot.cpp

@@ -102,7 +102,7 @@ Response capture_element_screenshot(Painter const& painter, Page& page, DOM::Ele
         encoded_string_or_error = encode_canvas_element(canvas_or_error.release_value());
     });
 
-    Platform::EventLoopPlugin::the().spin_until([&]() { return encoded_string_or_error.has_value(); });
+    Platform::EventLoopPlugin::the().spin_until(JS::create_heap_function(element.document().heap(), [&]() { return encoded_string_or_error.has_value(); }));
     return encoded_string_or_error.release_value();
 }
 

+ 2 - 2
Userland/Libraries/LibWeb/XHR/XMLHttpRequest.cpp

@@ -942,9 +942,9 @@ WebIDL::ExceptionOr<void> XMLHttpRequest::send(Optional<DocumentOrXMLHttpRequest
         }
 
         // FIXME: This is not exactly correct, as it allows the HTML event loop to continue executing tasks.
-        Platform::EventLoopPlugin::the().spin_until([&]() {
+        Platform::EventLoopPlugin::the().spin_until(JS::create_heap_function(heap(), [&]() {
             return processed_response || did_time_out;
-        });
+        }));
 
         // 6. If processedResponse is false, then set this’s timed out flag and terminate this’s fetch controller.
         if (!processed_response) {

+ 2 - 2
Userland/Services/WebContent/WebDriverConnection.cpp

@@ -2613,14 +2613,14 @@ ErrorOr<JsonArray, Web::WebDriver::Error> WebDriverConnection::find(StartNodeGet
         return elements.release_value();
     };
 
-    Web::Platform::EventLoopPlugin::the().spin_until([&]() {
+    Web::Platform::EventLoopPlugin::the().spin_until(JS::create_heap_function(current_top_level_browsing_context()->heap(), [&]() {
         maybe_elements = try_to_find_element();
         if (maybe_elements.is_error())
             return true;
 
         // 6. If elements returned is empty and the current time is less than end time return to step 4. Otherwise, continue to the next step.
         return maybe_elements.value()->length() != 0 || MonotonicTime::now() >= end_time;
-    });
+    }));
 
     auto elements = TRY(maybe_elements);
     VERIFY(elements);