mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 07:38:10 +00:00
LibWeb+LibJS: Make the EventTarget hierarchy (incl. DOM) GC-allocated
This is a monster patch that turns all EventTargets into GC-allocated PlatformObjects. Their C++ wrapper classes are removed, and the LibJS garbage collector is now responsible for their lifetimes. There's a fair amount of hacks and band-aids in this patch, and we'll have a lot of cleanup to do after this.
This commit is contained in:
parent
bb547ce1c4
commit
6f433c8656
445 changed files with 4797 additions and 4268 deletions
|
@ -8,7 +8,7 @@
|
|||
#include <LibJS/Runtime/ConsoleObject.h>
|
||||
#include <LibJS/Runtime/Realm.h>
|
||||
#include <LibWeb/Bindings/MainThreadVM.h>
|
||||
#include <LibWeb/Bindings/WorkerWrapper.h>
|
||||
#include <LibWeb/Bindings/WorkerPrototype.h>
|
||||
#include <LibWeb/DOM/ExceptionOr.h>
|
||||
#include <LibWeb/HTML/Scripting/Environments.h>
|
||||
#include <LibWeb/HTML/Worker.h>
|
||||
|
@ -18,19 +18,31 @@ namespace Web::HTML {
|
|||
|
||||
// https://html.spec.whatwg.org/multipage/workers.html#dedicated-workers-and-the-worker-interface
|
||||
Worker::Worker(FlyString const& script_url, WorkerOptions const options, DOM::Document& document)
|
||||
: m_script_url(script_url)
|
||||
: DOM::EventTarget(document.realm())
|
||||
, m_script_url(script_url)
|
||||
, m_options(options)
|
||||
, m_document(&document)
|
||||
, m_custom_data()
|
||||
, m_worker_vm(JS::VM::create(adopt_own(m_custom_data)))
|
||||
, m_interpreter(JS::Interpreter::create<JS::GlobalObject>(m_worker_vm))
|
||||
, m_interpreter_scope(*m_interpreter)
|
||||
, m_implicit_port(MessagePort::create())
|
||||
, m_implicit_port(MessagePort::create(document.window()))
|
||||
{
|
||||
set_prototype(&document.window().ensure_web_prototype<Bindings::WorkerPrototype>("Worker"));
|
||||
}
|
||||
|
||||
void Worker::visit_edges(Cell::Visitor& visitor)
|
||||
{
|
||||
Base::visit_edges(visitor);
|
||||
visitor.visit(m_document.ptr());
|
||||
visitor.visit(m_worker_realm.ptr());
|
||||
visitor.visit(m_worker_scope.ptr());
|
||||
visitor.visit(m_implicit_port.ptr());
|
||||
visitor.visit(m_outside_port.ptr());
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/workers.html#dom-worker
|
||||
DOM::ExceptionOr<NonnullRefPtr<Worker>> Worker::create(FlyString const& script_url, WorkerOptions const options, DOM::Document& document)
|
||||
DOM::ExceptionOr<JS::NonnullGCPtr<Worker>> Worker::create(FlyString const& script_url, WorkerOptions const options, DOM::Document& document)
|
||||
{
|
||||
dbgln_if(WEB_WORKER_DEBUG, "WebWorker: Creating worker with script_url = {}", script_url);
|
||||
|
||||
|
@ -60,20 +72,20 @@ DOM::ExceptionOr<NonnullRefPtr<Worker>> Worker::create(FlyString const& script_u
|
|||
// 5. Let worker URL be the resulting URL record.
|
||||
|
||||
// 6. Let worker be a new Worker object.
|
||||
auto worker = adopt_ref(*new Worker(script_url, options, document));
|
||||
auto worker = document.heap().allocate<Worker>(document.realm(), script_url, options, document);
|
||||
|
||||
// 7. Let outside port be a new MessagePort in outside settings's Realm.
|
||||
auto outside_port = MessagePort::create();
|
||||
auto outside_port = MessagePort::create(verify_cast<HTML::Window>(outside_settings.realm().global_object()));
|
||||
|
||||
// 8. Associate the outside port with worker
|
||||
worker->m_outside_port = outside_port;
|
||||
|
||||
// 9. Run this step in parallel:
|
||||
// 1. Run a worker given worker, worker URL, outside settings, outside port, and options.
|
||||
worker->run_a_worker(url, outside_settings, outside_port, options);
|
||||
worker->run_a_worker(url, outside_settings, *outside_port, options);
|
||||
|
||||
// 10. Return worker
|
||||
return worker;
|
||||
return JS::NonnullGCPtr(*worker);
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/workers.html#run-a-worker
|
||||
|
@ -103,7 +115,7 @@ void Worker::run_a_worker(AK::URL& url, EnvironmentSettingsObject& outside_setti
|
|||
// 7. Let realm execution context be the result of creating a new JavaScript realm given agent and the following customizations:
|
||||
auto realm_execution_context = Bindings::create_a_new_javascript_realm(
|
||||
*m_worker_vm,
|
||||
[&](JS::Realm& realm) -> JS::GlobalObject* {
|
||||
[&](JS::Realm& realm) -> JS::Object* {
|
||||
// 7a. For the global object, if is shared is true, create a new SharedWorkerGlobalScope object.
|
||||
// 7b. Otherwise, create a new DedicatedWorkerGlobalScope object.
|
||||
// FIXME: Proper support for both SharedWorkerGlobalScope and DedicatedWorkerGlobalScope
|
||||
|
@ -112,7 +124,7 @@ void Worker::run_a_worker(AK::URL& url, EnvironmentSettingsObject& outside_setti
|
|||
// FIXME: Make and use subclasses of WorkerGlobalScope, however this requires JS::GlobalObject to
|
||||
// play nicely with the IDL interpreter, to make spec-compliant extensions, which it currently does not.
|
||||
m_worker_scope = m_worker_vm->heap().allocate_without_realm<JS::GlobalObject>(realm);
|
||||
return m_worker_scope;
|
||||
return m_worker_scope.ptr();
|
||||
},
|
||||
nullptr);
|
||||
|
||||
|
@ -148,8 +160,8 @@ void Worker::run_a_worker(AK::URL& url, EnvironmentSettingsObject& outside_setti
|
|||
MessageEventInit event_init {};
|
||||
event_init.data = message;
|
||||
event_init.origin = "<origin>";
|
||||
// FIXME: The cast here is totally bogus, since workers don't have a WindowObject..
|
||||
dispatch_event(*MessageEvent::create(verify_cast<Bindings::WindowObject>(*m_worker_scope), HTML::EventNames::message, event_init));
|
||||
// FIXME: The cast here is totally bogus, since workers don't have a Window object..
|
||||
dispatch_event(*MessageEvent::create(verify_cast<HTML::Window>(*m_worker_scope), HTML::EventNames::message, event_init));
|
||||
}));
|
||||
|
||||
return JS::js_undefined();
|
||||
|
@ -246,7 +258,8 @@ void Worker::run_a_worker(AK::URL& url, EnvironmentSettingsObject& outside_setti
|
|||
// FIXME: Global scope association
|
||||
|
||||
// 16. Let inside port be a new MessagePort object in inside settings's Realm.
|
||||
auto inside_port = MessagePort::create();
|
||||
// FIXME: The cast here is totally bogus, since workers don't have a Window object..
|
||||
auto inside_port = MessagePort::create(verify_cast<HTML::Window>(*m_worker_scope));
|
||||
|
||||
// 17. Associate inside port with worker global scope.
|
||||
// FIXME: Global scope association
|
||||
|
@ -319,11 +332,6 @@ void Worker::post_message(JS::Value message, JS::Value)
|
|||
target_port->post_message(message);
|
||||
}
|
||||
|
||||
JS::Object* Worker::create_wrapper(JS::Realm& realm)
|
||||
{
|
||||
return wrap(realm, *this);
|
||||
}
|
||||
|
||||
#undef __ENUMERATE
|
||||
#define __ENUMERATE(attribute_name, event_name) \
|
||||
void Worker::set_##attribute_name(Bindings::CallbackType* value) \
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue