1
0
Fork 0
mirror of https://github.com/LadybirdBrowser/ladybird.git synced 2025-06-08 13:37:10 +09:00

LibGC+Everywhere: Factor out a LibGC from LibJS

Resulting in a massive rename across almost everywhere! Alongside the
namespace change, we now have the following names:

 * JS::NonnullGCPtr -> GC::Ref
 * JS::GCPtr -> GC::Ptr
 * JS::HeapFunction -> GC::Function
 * JS::CellImpl -> GC::Cell
 * JS::Handle -> GC::Root
This commit is contained in:
Shannon Booth 2024-11-15 04:01:23 +13:00 committed by Andreas Kling
parent ce23efc5f6
commit f87041bf3a
Notes: github-actions[bot] 2024-11-15 13:50:17 +00:00
1722 changed files with 9939 additions and 9906 deletions

View file

@ -10,7 +10,7 @@
#include <AK/String.h>
#include <AK/Utf8View.h>
#include <AK/Vector.h>
#include <LibJS/Heap/HeapFunction.h>
#include <LibGC/Function.h>
#include <LibJS/Runtime/Array.h>
#include <LibWeb/Bindings/MainThreadVM.h>
#include <LibWeb/Crypto/Crypto.h>
@ -106,18 +106,18 @@ bool WindowOrWorkerGlobalScopeMixin::cross_origin_isolated() const
}
// https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#dom-createimagebitmap
JS::NonnullGCPtr<WebIDL::Promise> WindowOrWorkerGlobalScopeMixin::create_image_bitmap(ImageBitmapSource image, Optional<ImageBitmapOptions> options) const
GC::Ref<WebIDL::Promise> WindowOrWorkerGlobalScopeMixin::create_image_bitmap(ImageBitmapSource image, Optional<ImageBitmapOptions> options) const
{
return create_image_bitmap_impl(image, {}, {}, {}, {}, options);
}
// https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#dom-createimagebitmap
JS::NonnullGCPtr<WebIDL::Promise> WindowOrWorkerGlobalScopeMixin::create_image_bitmap(ImageBitmapSource image, WebIDL::Long sx, WebIDL::Long sy, WebIDL::Long sw, WebIDL::Long sh, Optional<ImageBitmapOptions> options) const
GC::Ref<WebIDL::Promise> WindowOrWorkerGlobalScopeMixin::create_image_bitmap(ImageBitmapSource image, WebIDL::Long sx, WebIDL::Long sy, WebIDL::Long sw, WebIDL::Long sh, Optional<ImageBitmapOptions> options) const
{
return create_image_bitmap_impl(image, sx, sy, sw, sh, options);
}
JS::NonnullGCPtr<WebIDL::Promise> WindowOrWorkerGlobalScopeMixin::create_image_bitmap_impl(ImageBitmapSource& image, Optional<WebIDL::Long> sx, Optional<WebIDL::Long> sy, Optional<WebIDL::Long> sw, Optional<WebIDL::Long> sh, Optional<ImageBitmapOptions>& options) const
GC::Ref<WebIDL::Promise> WindowOrWorkerGlobalScopeMixin::create_image_bitmap_impl(ImageBitmapSource& image, Optional<WebIDL::Long> sx, Optional<WebIDL::Long> sy, Optional<WebIDL::Long> sw, Optional<WebIDL::Long> sh, Optional<ImageBitmapOptions>& options) const
{
auto& realm = this_impl().realm();
@ -149,9 +149,9 @@ JS::NonnullGCPtr<WebIDL::Promise> WindowOrWorkerGlobalScopeMixin::create_image_b
// 6. Switch on image:
image.visit(
[&](JS::Handle<FileAPI::Blob>& blob) {
[&](GC::Root<FileAPI::Blob>& blob) {
// Run these step in parallel:
Platform::EventLoopPlugin::the().deferred_invoke(JS::create_heap_function(realm.heap(), [=]() {
Platform::EventLoopPlugin::the().deferred_invoke(GC::create_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.
@ -161,7 +161,7 @@ JS::NonnullGCPtr<WebIDL::Promise> WindowOrWorkerGlobalScopeMixin::create_image_b
// 2. Apply the image sniffing rules to determine the file format of imageData, with MIME type of
// image (as given by image's type attribute) giving the official type.
auto on_failed_decode = [p = JS::Handle(*p)](Error&) {
auto on_failed_decode = [p = GC::Root(*p)](Error&) {
// 3. If imageData is not in a supported image file format (e.g., it's not an image at all), or if
// imageData is corrupted in some fatal way such that the image dimensions cannot be obtained
// (e.g., a vector graphic with no natural size), then reject p with an "InvalidStateError" DOMException
@ -171,7 +171,7 @@ JS::NonnullGCPtr<WebIDL::Promise> WindowOrWorkerGlobalScopeMixin::create_image_b
WebIDL::reject_promise(realm, *p, WebIDL::InvalidStateError::create(realm, "image does not contain a supported image format"_string));
};
auto on_successful_decode = [image_bitmap = JS::Handle(*image_bitmap), p = JS::Handle(*p)](Web::Platform::DecodedImage& result) -> ErrorOr<void> {
auto on_successful_decode = [image_bitmap = GC::Root(*image_bitmap), p = GC::Root(*p)](Web::Platform::DecodedImage& result) -> ErrorOr<void> {
// 4. Set imageBitmap's bitmap data to imageData, cropped to the source rectangle with formatting.
// If this is an animated image, imageBitmap's bitmap data must only be taken from the default image
// of the animation (the one that the format defines is to be used when animation is not supported
@ -202,20 +202,20 @@ JS::NonnullGCPtr<WebIDL::Promise> WindowOrWorkerGlobalScopeMixin::create_image_b
return p;
}
JS::NonnullGCPtr<WebIDL::Promise> WindowOrWorkerGlobalScopeMixin::fetch(Fetch::RequestInfo const& input, Fetch::RequestInit const& init) const
GC::Ref<WebIDL::Promise> WindowOrWorkerGlobalScopeMixin::fetch(Fetch::RequestInfo const& input, Fetch::RequestInit const& init) const
{
auto& vm = this_impl().vm();
return Fetch::fetch(vm, input, init);
}
// https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#dom-settimeout
i32 WindowOrWorkerGlobalScopeMixin::set_timeout(TimerHandler handler, i32 timeout, JS::MarkedVector<JS::Value> arguments)
i32 WindowOrWorkerGlobalScopeMixin::set_timeout(TimerHandler handler, i32 timeout, GC::MarkedVector<JS::Value> arguments)
{
return run_timer_initialization_steps(move(handler), timeout, move(arguments), Repeat::No);
}
// https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#dom-setinterval
i32 WindowOrWorkerGlobalScopeMixin::set_interval(TimerHandler handler, i32 timeout, JS::MarkedVector<JS::Value> arguments)
i32 WindowOrWorkerGlobalScopeMixin::set_interval(TimerHandler handler, i32 timeout, GC::MarkedVector<JS::Value> arguments)
{
return run_timer_initialization_steps(move(handler), timeout, move(arguments), Repeat::Yes);
}
@ -245,7 +245,7 @@ void WindowOrWorkerGlobalScopeMixin::clear_map_of_active_timers()
// https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timer-initialisation-steps
// With no active script fix from https://github.com/whatwg/html/pull/9712
i32 WindowOrWorkerGlobalScopeMixin::run_timer_initialization_steps(TimerHandler handler, i32 timeout, JS::MarkedVector<JS::Value> arguments, Repeat repeat, Optional<i32> previous_id)
i32 WindowOrWorkerGlobalScopeMixin::run_timer_initialization_steps(TimerHandler handler, i32 timeout, GC::MarkedVector<JS::Value> arguments, Repeat repeat, Optional<i32> previous_id)
{
// 1. Let thisArg be global if that is a WorkerGlobalScope object; otherwise let thisArg be the WindowProxy that corresponds to global.
@ -269,14 +269,14 @@ i32 WindowOrWorkerGlobalScopeMixin::run_timer_initialization_steps(TimerHandler
auto& vm = this_impl().vm();
// 8. Let task be a task that runs the following substeps:
auto task = JS::create_heap_function(vm.heap(), Function<void()>([this, handler = move(handler), timeout, arguments = move(arguments), repeat, id, initiating_script]() {
auto task = GC::create_function(vm.heap(), Function<void()>([this, handler = move(handler), timeout, arguments = move(arguments), repeat, id, initiating_script]() {
// 1. If id does not exist in global's map of active timers, then abort these steps.
if (!m_timers.contains(id))
return;
handler.visit(
// 2. If handler is a Function, then invoke handler given arguments with the callback this value set to thisArg. If this throws an exception, catch it, and report the exception.
[&](JS::Handle<WebIDL::CallbackType> const& callback) {
[&](GC::Root<WebIDL::CallbackType> const& callback) {
if (auto result = WebIDL::invoke_callback(*callback, &this_impl(), arguments); result.is_error())
report_exception(result, this_impl().realm());
},
@ -338,7 +338,7 @@ i32 WindowOrWorkerGlobalScopeMixin::run_timer_initialization_steps(TimerHandler
// 11. Let completionStep be an algorithm step which queues a global task on the timer task source given global to run task.
Function<void()> completion_step = [this, task = move(task)]() mutable {
queue_global_task(Task::Source::TimerTask, this_impl(), JS::create_heap_function(this_impl().heap(), [this, task] {
queue_global_task(Task::Source::TimerTask, this_impl(), GC::create_function(this_impl().heap(), [this, task] {
HTML::TemporaryExecutionContext execution_context { this_impl().realm(), HTML::TemporaryExecutionContext::CallbacksEnabled::Yes };
task->function()();
}));
@ -364,10 +364,10 @@ PerformanceTimeline::PerformanceEntryTuple& WindowOrWorkerGlobalScopeMixin::rele
}
// https://www.w3.org/TR/performance-timeline/#dfn-queue-a-performanceentry
void WindowOrWorkerGlobalScopeMixin::queue_performance_entry(JS::NonnullGCPtr<PerformanceTimeline::PerformanceEntry> new_entry)
void WindowOrWorkerGlobalScopeMixin::queue_performance_entry(GC::Ref<PerformanceTimeline::PerformanceEntry> new_entry)
{
// 1. Let interested observers be an initially empty set of PerformanceObserver objects.
Vector<JS::Handle<PerformanceTimeline::PerformanceObserver>> interested_observers;
Vector<GC::Root<PerformanceTimeline::PerformanceObserver>> interested_observers;
// 2. Let entryType be newEntrys entryType value.
auto const& entry_type = new_entry->entry_type();
@ -428,16 +428,16 @@ void WindowOrWorkerGlobalScopeMixin::clear_performance_entry_buffer(Badge<HighRe
void WindowOrWorkerGlobalScopeMixin::remove_entries_from_performance_entry_buffer(Badge<HighResolutionTime::Performance>, FlyString const& entry_type, String entry_name)
{
auto& tuple = relevant_performance_entry_tuple(entry_type);
tuple.performance_entry_buffer.remove_all_matching([&entry_name](JS::Handle<PerformanceTimeline::PerformanceEntry> const& entry) {
tuple.performance_entry_buffer.remove_all_matching([&entry_name](GC::Root<PerformanceTimeline::PerformanceEntry> const& entry) {
return entry->name() == entry_name;
});
}
// https://www.w3.org/TR/performance-timeline/#dfn-filter-buffer-map-by-name-and-type
ErrorOr<Vector<JS::Handle<PerformanceTimeline::PerformanceEntry>>> WindowOrWorkerGlobalScopeMixin::filter_buffer_map_by_name_and_type(Optional<String> name, Optional<String> type) const
ErrorOr<Vector<GC::Root<PerformanceTimeline::PerformanceEntry>>> WindowOrWorkerGlobalScopeMixin::filter_buffer_map_by_name_and_type(Optional<String> name, Optional<String> type) const
{
// 1. Let result be an initially empty list.
Vector<JS::Handle<PerformanceTimeline::PerformanceEntry>> result;
Vector<GC::Root<PerformanceTimeline::PerformanceEntry>> result;
// 2. Let map be the performance entry buffer map associated with the relevant global object of this.
auto const& map = m_performance_entry_buffer_map;
@ -481,17 +481,17 @@ ErrorOr<Vector<JS::Handle<PerformanceTimeline::PerformanceEntry>>> WindowOrWorke
return result;
}
void WindowOrWorkerGlobalScopeMixin::register_performance_observer(Badge<PerformanceTimeline::PerformanceObserver>, JS::NonnullGCPtr<PerformanceTimeline::PerformanceObserver> observer)
void WindowOrWorkerGlobalScopeMixin::register_performance_observer(Badge<PerformanceTimeline::PerformanceObserver>, GC::Ref<PerformanceTimeline::PerformanceObserver> observer)
{
m_registered_performance_observer_objects.set(observer, AK::HashSetExistingEntryBehavior::Keep);
}
void WindowOrWorkerGlobalScopeMixin::unregister_performance_observer(Badge<PerformanceTimeline::PerformanceObserver>, JS::NonnullGCPtr<PerformanceTimeline::PerformanceObserver> observer)
void WindowOrWorkerGlobalScopeMixin::unregister_performance_observer(Badge<PerformanceTimeline::PerformanceObserver>, GC::Ref<PerformanceTimeline::PerformanceObserver> observer)
{
m_registered_performance_observer_objects.remove(observer);
}
bool WindowOrWorkerGlobalScopeMixin::has_registered_performance_observer(JS::NonnullGCPtr<PerformanceTimeline::PerformanceObserver> observer)
bool WindowOrWorkerGlobalScopeMixin::has_registered_performance_observer(GC::Ref<PerformanceTimeline::PerformanceObserver> observer)
{
return m_registered_performance_observer_objects.contains(observer);
}
@ -508,7 +508,7 @@ void WindowOrWorkerGlobalScopeMixin::queue_the_performance_observer_task()
// 3. Queue a task that consists of running the following substeps. The task source for the queued task is the performance
// timeline task source.
queue_global_task(Task::Source::PerformanceTimeline, this_impl(), JS::create_heap_function(this_impl().heap(), [this]() {
queue_global_task(Task::Source::PerformanceTimeline, this_impl(), GC::create_function(this_impl().heap(), [this]() {
auto& realm = this_impl().realm();
HTML::TemporaryExecutionContext execution_context { realm, HTML::TemporaryExecutionContext::CallbacksEnabled::Yes };
@ -530,7 +530,7 @@ void WindowOrWorkerGlobalScopeMixin::queue_the_performance_observer_task()
if (entries.is_empty())
continue;
Vector<JS::NonnullGCPtr<PerformanceTimeline::PerformanceEntry>> entries_as_gc_ptrs;
Vector<GC::Ref<PerformanceTimeline::PerformanceEntry>> entries_as_gc_ptrs;
for (auto& entry : entries)
entries_as_gc_ptrs.append(*entry);
@ -589,12 +589,12 @@ void WindowOrWorkerGlobalScopeMixin::queue_the_performance_observer_task()
}));
}
void WindowOrWorkerGlobalScopeMixin::register_event_source(Badge<EventSource>, JS::NonnullGCPtr<EventSource> event_source)
void WindowOrWorkerGlobalScopeMixin::register_event_source(Badge<EventSource>, GC::Ref<EventSource> event_source)
{
m_registered_event_sources.set(event_source);
}
void WindowOrWorkerGlobalScopeMixin::unregister_event_source(Badge<EventSource>, JS::NonnullGCPtr<EventSource> event_source)
void WindowOrWorkerGlobalScopeMixin::unregister_event_source(Badge<EventSource>, GC::Ref<EventSource> event_source)
{
m_registered_event_sources.remove(event_source);
}
@ -638,15 +638,15 @@ void WindowOrWorkerGlobalScopeMixin::run_steps_after_a_timeout_impl(i32 timeout,
}
// https://w3c.github.io/hr-time/#dom-windoworworkerglobalscope-performance
JS::NonnullGCPtr<HighResolutionTime::Performance> WindowOrWorkerGlobalScopeMixin::performance()
GC::Ref<HighResolutionTime::Performance> WindowOrWorkerGlobalScopeMixin::performance()
{
auto& realm = this_impl().realm();
if (!m_performance)
m_performance = realm.create<HighResolutionTime::Performance>(realm);
return JS::NonnullGCPtr { *m_performance };
return GC::Ref { *m_performance };
}
JS::NonnullGCPtr<IndexedDB::IDBFactory> WindowOrWorkerGlobalScopeMixin::indexed_db()
GC::Ref<IndexedDB::IDBFactory> WindowOrWorkerGlobalScopeMixin::indexed_db()
{
auto& realm = this_impl().realm();
@ -656,7 +656,7 @@ JS::NonnullGCPtr<IndexedDB::IDBFactory> WindowOrWorkerGlobalScopeMixin::indexed_
}
// https://w3c.github.io/performance-timeline/#dfn-frozen-array-of-supported-entry-types
JS::NonnullGCPtr<JS::Object> WindowOrWorkerGlobalScopeMixin::supported_entry_types() const
GC::Ref<JS::Object> WindowOrWorkerGlobalScopeMixin::supported_entry_types() const
{
// Each global object has an associated frozen array of supported entry types, which is initialized to the
// FrozenArray created from the sequence of strings among the registry that are supported for the global
@ -665,7 +665,7 @@ JS::NonnullGCPtr<JS::Object> WindowOrWorkerGlobalScopeMixin::supported_entry_typ
auto& realm = this_impl().realm();
if (!m_supported_entry_types_array) {
JS::MarkedVector<JS::Value> supported_entry_types(vm.heap());
GC::MarkedVector<JS::Value> supported_entry_types(vm.heap());
#define __ENUMERATE_SUPPORTED_PERFORMANCE_ENTRY_TYPES(entry_type, cpp_class) \
supported_entry_types.append(JS::PrimitiveString::create(vm, entry_type));
@ -735,7 +735,7 @@ void WindowOrWorkerGlobalScopeMixin::report_an_exception(JS::Value const& e)
// 6. If script is a classic script and script's muted errors is true, then set message to "Script error.",
// urlString to the empty string, line and col to 0, and errorValue to null.
script_or_module.visit(
[&](JS::NonnullGCPtr<JS::Script> const& js_script) {
[&](GC::Ref<JS::Script> const& js_script) {
if (verify_cast<ClassicScript>(js_script->host_defined())->muted_errors() == ClassicScript::MutedErrors::Yes) {
message = "Script error."_string;
url_string = String {};
@ -746,7 +746,7 @@ void WindowOrWorkerGlobalScopeMixin::report_an_exception(JS::Value const& e)
url_string = script_or_module_filename(js_script);
}
},
[&](JS::NonnullGCPtr<JS::Module> const& js_module) {
[&](GC::Ref<JS::Module> const& js_module) {
url_string = script_or_module_filename(js_module);
},
[](Empty) {});
@ -783,14 +783,14 @@ void WindowOrWorkerGlobalScopeMixin::report_an_exception(JS::Value const& e)
}
// https://w3c.github.io/webcrypto/#dom-windoworworkerglobalscope-crypto
JS::NonnullGCPtr<Crypto::Crypto> WindowOrWorkerGlobalScopeMixin::crypto()
GC::Ref<Crypto::Crypto> WindowOrWorkerGlobalScopeMixin::crypto()
{
auto& platform_object = this_impl();
auto& realm = platform_object.realm();
if (!m_crypto)
m_crypto = realm.create<Crypto::Crypto>(realm);
return JS::NonnullGCPtr { *m_crypto };
return GC::Ref { *m_crypto };
}
void WindowOrWorkerGlobalScopeMixin::push_onto_outstanding_rejected_promises_weak_set(JS::Promise* promise)
@ -805,12 +805,12 @@ bool WindowOrWorkerGlobalScopeMixin::remove_from_outstanding_rejected_promises_w
});
}
void WindowOrWorkerGlobalScopeMixin::push_onto_about_to_be_notified_rejected_promises_list(JS::NonnullGCPtr<JS::Promise> promise)
void WindowOrWorkerGlobalScopeMixin::push_onto_about_to_be_notified_rejected_promises_list(GC::Ref<JS::Promise> promise)
{
m_about_to_be_notified_rejected_promises_list.append(JS::make_handle(promise));
m_about_to_be_notified_rejected_promises_list.append(GC::make_root(promise));
}
bool WindowOrWorkerGlobalScopeMixin::remove_from_about_to_be_notified_rejected_promises_list(JS::NonnullGCPtr<JS::Promise> promise)
bool WindowOrWorkerGlobalScopeMixin::remove_from_about_to_be_notified_rejected_promises_list(GC::Ref<JS::Promise> promise)
{
return m_about_to_be_notified_rejected_promises_list.remove_first_matching([&](auto& promise_in_list) {
return promise == promise_in_list;
@ -837,7 +837,7 @@ void WindowOrWorkerGlobalScopeMixin::notify_about_rejected_promises(Badge<EventL
auto& global = verify_cast<DOM::EventTarget>(this_impl());
// 5. Queue a global task on the DOM manipulation task source given global to run the following substep:
queue_global_task(Task::Source::DOMManipulation, global, JS::create_heap_function(realm.heap(), [this, &global, list = move(list)] {
queue_global_task(Task::Source::DOMManipulation, global, GC::create_function(realm.heap(), [this, &global, list = move(list)] {
auto& realm = global.realm();
// 1. For each promise p in list: