mirror of
https://github.com/RGBCube/serenity
synced 2025-07-28 09:37:44 +00:00
LibJS+LibWeb: Replace GlobalObject with Realm in create() functions
This is a continuation of the previous two commits. As allocating a JS cell already primarily involves a realm instead of a global object, and we'll need to pass one to the allocate() function itself eventually (it's bridged via the global object right now), the create() functions need to receive a realm as well. The plan is for this to be the highest-level function that actually receives a realm and passes it around, AOs on an even higher level will use the "current realm" concept via VM::current_realm() as that's what the spec assumes; passing around realms (or global objects, for that matter) on higher AO levels is pointless and unlike for allocating individual objects, which may happen outside of regular JS execution, we don't need control over the specific realm that is being used there.
This commit is contained in:
parent
5dd5896588
commit
b99cc7d050
178 changed files with 883 additions and 609 deletions
|
@ -16,6 +16,7 @@
|
|||
#include <LibWeb/Bindings/CrossOriginAbstractOperations.h>
|
||||
#include <LibWeb/Bindings/DOMExceptionWrapper.h>
|
||||
#include <LibWeb/Bindings/LocationObject.h>
|
||||
#include <LibWeb/Bindings/MainThreadVM.h>
|
||||
#include <LibWeb/Bindings/WindowObject.h>
|
||||
#include <LibWeb/DOM/DOMException.h>
|
||||
#include <LibWeb/HTML/Scripting/Environments.h>
|
||||
|
@ -93,6 +94,7 @@ bool is_platform_object_same_origin(JS::Object const& object)
|
|||
// 7.2.3.4 CrossOriginGetOwnPropertyHelper ( O, P ), https://html.spec.whatwg.org/multipage/browsers.html#crossorigingetownpropertyhelper-(-o,-p-)
|
||||
Optional<JS::PropertyDescriptor> cross_origin_get_own_property_helper(Variant<LocationObject*, WindowObject*> const& object, JS::PropertyKey const& property_key)
|
||||
{
|
||||
auto& realm = *main_thread_vm().current_realm();
|
||||
auto const* object_ptr = object.visit([](auto* o) { return static_cast<JS::Object const*>(o); });
|
||||
auto const object_const_variant = object.visit([](auto* o) { return Variant<LocationObject const*, WindowObject const*> { o }; });
|
||||
|
||||
|
@ -126,7 +128,7 @@ Optional<JS::PropertyDescriptor> cross_origin_get_own_property_helper(Variant<Lo
|
|||
// 2. If IsCallable(value) is true, then set value to an anonymous built-in function, created in the current Realm Record, that performs the same steps as the IDL operation P on object O.
|
||||
if (value->is_function()) {
|
||||
value = JS::NativeFunction::create(
|
||||
HTML::current_global_object(), [function = JS::make_handle(*value)](auto&, auto& global_object) {
|
||||
realm, [function = JS::make_handle(*value)](auto&, auto& global_object) {
|
||||
return JS::call(global_object, function.value(), JS::js_undefined());
|
||||
},
|
||||
0, "");
|
||||
|
@ -143,7 +145,7 @@ Optional<JS::PropertyDescriptor> cross_origin_get_own_property_helper(Variant<Lo
|
|||
// 2. If e.[[NeedsGet]] is true, then set crossOriginGet to an anonymous built-in function, created in the current Realm Record, that performs the same steps as the getter of the IDL attribute P on object O.
|
||||
if (*entry.needs_get) {
|
||||
cross_origin_get = JS::NativeFunction::create(
|
||||
HTML::current_global_object(), [object_ptr, getter = JS::make_handle(*original_descriptor->get)](auto&, auto& global_object) {
|
||||
realm, [object_ptr, getter = JS::make_handle(*original_descriptor->get)](auto&, auto& global_object) {
|
||||
return JS::call(global_object, getter.cell(), object_ptr);
|
||||
},
|
||||
0, "");
|
||||
|
@ -155,7 +157,7 @@ Optional<JS::PropertyDescriptor> cross_origin_get_own_property_helper(Variant<Lo
|
|||
// If e.[[NeedsSet]] is true, then set crossOriginSet to an anonymous built-in function, created in the current Realm Record, that performs the same steps as the setter of the IDL attribute P on object O.
|
||||
if (*entry.needs_set) {
|
||||
cross_origin_set = JS::NativeFunction::create(
|
||||
HTML::current_global_object(), [object_ptr, setter = JS::make_handle(*original_descriptor->set)](auto&, auto& global_object) {
|
||||
realm, [object_ptr, setter = JS::make_handle(*original_descriptor->set)](auto&, auto& global_object) {
|
||||
return JS::call(global_object, setter.cell(), object_ptr);
|
||||
},
|
||||
0, "");
|
||||
|
|
|
@ -299,7 +299,6 @@ JS::VM& main_thread_vm()
|
|||
// https://dom.spec.whatwg.org/#queue-a-mutation-observer-compound-microtask
|
||||
void queue_mutation_observer_microtask(DOM::Document& document)
|
||||
{
|
||||
// FIXME: Is this the correct VM?
|
||||
auto& vm = main_thread_vm();
|
||||
auto& custom_data = verify_cast<WebEngineCustomData>(*vm.custom_data());
|
||||
|
||||
|
@ -345,8 +344,9 @@ void queue_mutation_observer_microtask(DOM::Document& document)
|
|||
if (!records.is_empty()) {
|
||||
auto& callback = mutation_observer.callback();
|
||||
auto& global_object = callback.callback_context.global_object();
|
||||
auto& realm = callback.callback_context.realm();
|
||||
|
||||
auto* wrapped_records = MUST(JS::Array::create(global_object, 0));
|
||||
auto* wrapped_records = MUST(JS::Array::create(realm, 0));
|
||||
for (size_t i = 0; i < records.size(); ++i) {
|
||||
auto& record = records.at(i);
|
||||
auto* wrapped_record = Bindings::wrap(global_object, record);
|
||||
|
|
|
@ -21,7 +21,7 @@ NavigatorObject::NavigatorObject(JS::Realm& realm)
|
|||
void NavigatorObject::initialize(JS::Realm& realm)
|
||||
{
|
||||
auto& heap = this->heap();
|
||||
auto* languages = MUST(JS::Array::create(realm.global_object(), 0));
|
||||
auto* languages = MUST(JS::Array::create(realm, 0));
|
||||
languages->indexed_properties().append(js_string(heap, "en-US"));
|
||||
|
||||
// FIXME: All of these should be in Navigator's prototype and be native accessors
|
||||
|
|
|
@ -618,6 +618,8 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::scroll)
|
|||
// https://www.w3.org/TR/cssom-view/#dom-window-scrollby
|
||||
JS_DEFINE_NATIVE_FUNCTION(WindowObject::scroll_by)
|
||||
{
|
||||
auto& realm = *global_object.associated_realm();
|
||||
|
||||
auto* impl = TRY(impl_from(vm, global_object));
|
||||
if (!impl->page())
|
||||
return JS::js_undefined();
|
||||
|
@ -626,12 +628,12 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::scroll_by)
|
|||
JS::Object* options = nullptr;
|
||||
|
||||
if (vm.argument_count() == 0) {
|
||||
options = JS::Object::create(global_object, nullptr);
|
||||
options = JS::Object::create(realm, nullptr);
|
||||
} else if (vm.argument_count() == 1) {
|
||||
options = TRY(vm.argument(0).to_object(global_object));
|
||||
} else if (vm.argument_count() >= 2) {
|
||||
// We ignore arguments 2+ in line with behavior of Chrome and Firefox
|
||||
options = JS::Object::create(global_object, nullptr);
|
||||
options = JS::Object::create(realm, nullptr);
|
||||
MUST(options->set("left", vm.argument(0), ShouldThrowExceptions::No));
|
||||
MUST(options->set("top", vm.argument(1), ShouldThrowExceptions::No));
|
||||
MUST(options->set("behavior", JS::js_string(vm, "auto"), ShouldThrowExceptions::No));
|
||||
|
|
|
@ -30,7 +30,7 @@ inline Wrapper* wrap_impl(JS::GlobalObject& global_object, NativeObject& native_
|
|||
{
|
||||
auto& realm = *global_object.associated_realm();
|
||||
if (!native_object.wrapper()) {
|
||||
native_object.set_wrapper(*global_object.heap().allocate<typename NativeObject::WrapperType>(global_object, realm, native_object));
|
||||
native_object.set_wrapper(*realm.heap().allocate<typename NativeObject::WrapperType>(realm.global_object(), realm, native_object));
|
||||
}
|
||||
return native_object.wrapper();
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ namespace Web::Crypto {
|
|||
JS::Promise* SubtleCrypto::digest(String const& algorithm, JS::Handle<JS::Object> const& data)
|
||||
{
|
||||
auto& global_object = wrapper()->global_object();
|
||||
auto& realm = *global_object.associated_realm();
|
||||
|
||||
// 1. Let algorithm be the algorithm parameter passed to the digest() method.
|
||||
|
||||
|
@ -25,7 +26,7 @@ JS::Promise* SubtleCrypto::digest(String const& algorithm, JS::Handle<JS::Object
|
|||
auto data_buffer_or_error = Bindings::IDL::get_buffer_source_copy(*data.cell());
|
||||
if (data_buffer_or_error.is_error()) {
|
||||
auto* error = wrap(wrapper()->global_object(), DOM::OperationError::create("Failed to copy bytes from ArrayBuffer"));
|
||||
auto* promise = JS::Promise::create(global_object);
|
||||
auto* promise = JS::Promise::create(realm);
|
||||
promise->reject(error);
|
||||
return promise;
|
||||
}
|
||||
|
@ -46,13 +47,13 @@ JS::Promise* SubtleCrypto::digest(String const& algorithm, JS::Handle<JS::Object
|
|||
// 4. If an error occurred, return a Promise rejected with normalizedAlgorithm.
|
||||
else {
|
||||
auto* error = wrap(wrapper()->global_object(), DOM::NotSupportedError::create(String::formatted("Invalid hash function '{}'", algorithm)));
|
||||
auto* promise = JS::Promise::create(global_object);
|
||||
auto* promise = JS::Promise::create(realm);
|
||||
promise->reject(error);
|
||||
return promise;
|
||||
}
|
||||
|
||||
// 5. Let promise be a new Promise.
|
||||
auto* promise = JS::Promise::create(global_object);
|
||||
auto* promise = JS::Promise::create(realm);
|
||||
|
||||
// 6. Return promise and perform the remaining steps in parallel.
|
||||
// FIXME: We don't have a good abstraction for this yet, so we do it in sync.
|
||||
|
@ -71,7 +72,7 @@ JS::Promise* SubtleCrypto::digest(String const& algorithm, JS::Handle<JS::Object
|
|||
return promise;
|
||||
}
|
||||
|
||||
auto* result = JS::ArrayBuffer::create(global_object, result_buffer.release_value());
|
||||
auto* result = JS::ArrayBuffer::create(realm, result_buffer.release_value());
|
||||
|
||||
// 9. Resolve promise with result.
|
||||
promise->fulfill(result);
|
||||
|
|
|
@ -437,7 +437,7 @@ Bindings::CallbackType* EventTarget::get_current_value_of_event_handler(FlyStrin
|
|||
|
||||
// 6. Return scope. (NOTE: Not necessary)
|
||||
|
||||
auto* function = JS::ECMAScriptFunctionObject::create(global_object, name, builder.to_string(), program->body(), program->parameters(), program->function_length(), scope, nullptr, JS::FunctionKind::Normal, program->is_strict_mode(), program->might_need_arguments_object(), is_arrow_function);
|
||||
auto* function = JS::ECMAScriptFunctionObject::create(realm, name, builder.to_string(), program->body(), program->parameters(), program->function_length(), scope, nullptr, JS::FunctionKind::Normal, program->is_strict_mode(), program->might_need_arguments_object(), is_arrow_function);
|
||||
VERIFY(function);
|
||||
|
||||
// 10. Remove settings object's realm execution context from the JavaScript execution context stack.
|
||||
|
@ -488,7 +488,7 @@ void EventTarget::set_event_handler_attribute(FlyString const& name, Optional<Bi
|
|||
// Optimization: We pass in the event handler here instead of having activate_event_handler do another hash map lookup just to get the same object.
|
||||
// This handles a new event handler while the other path handles an existing event handler. As such, both paths must have their own
|
||||
// unique call to activate_event_handler.
|
||||
event_target->activate_event_handler(name, new_event_handler, IsAttribute::No);
|
||||
event_target->activate_event_handler(name, new_event_handler);
|
||||
|
||||
handler_map.set(name, move(new_event_handler));
|
||||
return;
|
||||
|
@ -500,12 +500,14 @@ void EventTarget::set_event_handler_attribute(FlyString const& name, Optional<Bi
|
|||
|
||||
// 4. Activate an event handler given eventTarget and name.
|
||||
// NOTE: See the optimization comment above.
|
||||
event_target->activate_event_handler(name, event_handler, IsAttribute::No);
|
||||
event_target->activate_event_handler(name, event_handler);
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#activate-an-event-handler
|
||||
void EventTarget::activate_event_handler(FlyString const& name, HTML::EventHandler& event_handler, IsAttribute is_attribute)
|
||||
void EventTarget::activate_event_handler(FlyString const& name, HTML::EventHandler& event_handler)
|
||||
{
|
||||
auto& realm = *Bindings::main_thread_vm().current_realm();
|
||||
|
||||
// 1. Let handlerMap be eventTarget's event handler map.
|
||||
// 2. Let eventHandler be handlerMap[name].
|
||||
// NOTE: These are achieved by using the passed in event handler.
|
||||
|
@ -517,36 +519,12 @@ void EventTarget::activate_event_handler(FlyString const& name, HTML::EventHandl
|
|||
// 4. Let callback be the result of creating a Web IDL EventListener instance representing a reference to a function of one argument that executes the steps of the event handler processing algorithm, given eventTarget, name, and its argument.
|
||||
// The EventListener's callback context can be arbitrary; it does not impact the steps of the event handler processing algorithm. [DOM]
|
||||
|
||||
// FIXME: This is guess work on what global object the NativeFunction should be allocated on.
|
||||
// For <body> or <frameset> elements who just had an element attribute set, it will be this's wrapper, as `this` is the result of determine_target_of_event_handler
|
||||
// returning the element's document's global object, which is the HTML::Window object.
|
||||
// For any other HTMLElement who just had an element attribute set, `this` will be that HTMLElement, so the global object is this's document's realm's global object.
|
||||
// For anything else, it came from JavaScript, so use the global object of the provided callback function.
|
||||
JS::GlobalObject* global_object = nullptr;
|
||||
if (is_attribute == IsAttribute::Yes) {
|
||||
if (is<HTML::Window>(this)) {
|
||||
auto& window = verify_cast<HTML::Window>(*this);
|
||||
// If an element attribute is set on a <body> element before any script is run, Window::wrapper() will be null.
|
||||
// Force creation of the global object via the Document::interpreter() lazy initialization mechanism.
|
||||
if (window.wrapper() == nullptr)
|
||||
window.associated_document().interpreter();
|
||||
global_object = static_cast<JS::GlobalObject*>(window.wrapper());
|
||||
} else {
|
||||
auto& html_element = verify_cast<HTML::HTMLElement>(*this);
|
||||
global_object = &html_element.document().realm().global_object();
|
||||
}
|
||||
} else {
|
||||
global_object = &event_handler.value.get<Bindings::CallbackType>().callback.cell()->global_object();
|
||||
}
|
||||
|
||||
VERIFY(global_object);
|
||||
|
||||
// NOTE: The callback must keep `this` alive. For example:
|
||||
// document.body.onunload = () => { console.log("onunload called!"); }
|
||||
// document.body.remove();
|
||||
// location.reload();
|
||||
// The body element is no longer in the DOM and there is no variable holding onto it. However, the onunload handler is still called, meaning the callback keeps the body element alive.
|
||||
auto callback_function = JS::NativeFunction::create(*global_object, "", [event_target = NonnullRefPtr(*this), name](JS::VM& vm, auto&) mutable -> JS::ThrowCompletionOr<JS::Value> {
|
||||
auto callback_function = JS::NativeFunction::create(realm, "", [event_target = NonnullRefPtr(*this), name](JS::VM& vm, auto&) mutable -> JS::ThrowCompletionOr<JS::Value> {
|
||||
// The event dispatcher should only call this with one argument.
|
||||
VERIFY(vm.argument_count() == 1);
|
||||
|
||||
|
@ -561,7 +539,7 @@ void EventTarget::activate_event_handler(FlyString const& name, HTML::EventHandl
|
|||
});
|
||||
|
||||
// NOTE: As per the spec, the callback context is arbitrary.
|
||||
Bindings::CallbackType callback { JS::make_handle(static_cast<JS::Object*>(callback_function)), verify_cast<HTML::EnvironmentSettingsObject>(*global_object->associated_realm()->host_defined()) };
|
||||
Bindings::CallbackType callback { JS::make_handle(static_cast<JS::Object*>(callback_function)), verify_cast<HTML::EnvironmentSettingsObject>(*realm.host_defined()) };
|
||||
|
||||
// 5. Let listener be a new event listener whose type is the event handler event type corresponding to eventHandler and callback is callback.
|
||||
auto listener = adopt_ref(*new DOMEventListener);
|
||||
|
@ -725,7 +703,7 @@ void EventTarget::element_event_handler_attribute_changed(FlyString const& local
|
|||
HTML::EventHandler new_event_handler { value };
|
||||
|
||||
// 6. Activate an event handler given eventTarget and name.
|
||||
event_target->activate_event_handler(local_name, new_event_handler, IsAttribute::Yes);
|
||||
event_target->activate_event_handler(local_name, new_event_handler);
|
||||
|
||||
handler_map.set(local_name, move(new_event_handler));
|
||||
return;
|
||||
|
@ -735,7 +713,7 @@ void EventTarget::element_event_handler_attribute_changed(FlyString const& local
|
|||
|
||||
// 6. Activate an event handler given eventTarget and name.
|
||||
event_handler.value = value;
|
||||
event_target->activate_event_handler(local_name, event_handler, IsAttribute::Yes);
|
||||
event_target->activate_event_handler(local_name, event_handler);
|
||||
}
|
||||
|
||||
bool EventTarget::dispatch_event(NonnullRefPtr<Event> event)
|
||||
|
|
|
@ -75,13 +75,8 @@ private:
|
|||
// Spec Note: The order of the entries of event handler map could be arbitrary. It is not observable through any algorithms that operate on the map.
|
||||
HashMap<FlyString, HTML::EventHandler> m_event_handler_map;
|
||||
|
||||
enum class IsAttribute {
|
||||
No,
|
||||
Yes,
|
||||
};
|
||||
|
||||
Bindings::CallbackType* get_current_value_of_event_handler(FlyString const& name);
|
||||
void activate_event_handler(FlyString const& name, HTML::EventHandler& event_handler, IsAttribute is_attribute);
|
||||
void activate_event_handler(FlyString const& name, HTML::EventHandler& event_handler);
|
||||
void deactivate_event_handler(FlyString const& name);
|
||||
JS::ThrowCompletionOr<void> process_event_handler_for_event(FlyString const& name, Event& event);
|
||||
};
|
||||
|
|
|
@ -15,6 +15,7 @@ namespace Web::Encoding {
|
|||
JS::Uint8Array* TextEncoder::encode(String const& input) const
|
||||
{
|
||||
auto& global_object = wrapper()->global_object();
|
||||
auto& realm = *global_object.associated_realm();
|
||||
|
||||
// NOTE: The AK::String returned from PrimitiveString::string() is always UTF-8, regardless of the internal string type, so most of these steps are no-ops.
|
||||
|
||||
|
@ -28,8 +29,8 @@ JS::Uint8Array* TextEncoder::encode(String const& input) const
|
|||
|
||||
auto byte_buffer = input.to_byte_buffer();
|
||||
auto array_length = byte_buffer.size();
|
||||
auto* array_buffer = JS::ArrayBuffer::create(global_object, move(byte_buffer));
|
||||
return JS::Uint8Array::create(global_object, array_length, *array_buffer);
|
||||
auto* array_buffer = JS::ArrayBuffer::create(realm, move(byte_buffer));
|
||||
return JS::Uint8Array::create(realm, array_length, *array_buffer);
|
||||
}
|
||||
|
||||
// https://encoding.spec.whatwg.org/#dom-textencoder-encoding
|
||||
|
|
|
@ -17,6 +17,7 @@ JS::ThrowCompletionOr<JS::Object*> HeadersIterator::next()
|
|||
{
|
||||
auto& global_object = wrapper()->global_object();
|
||||
auto& vm = global_object.vm();
|
||||
auto& realm = *global_object.associated_realm();
|
||||
|
||||
// The value pairs to iterate over are the return value of running sort and combine with this’s header list.
|
||||
auto value_pairs_to_iterate_over = [&]() -> JS::ThrowCompletionOr<Vector<Fetch::Infrastructure::Header>> {
|
||||
|
@ -39,7 +40,7 @@ JS::ThrowCompletionOr<JS::Object*> HeadersIterator::next()
|
|||
case JS::Object::PropertyKind::Value:
|
||||
return create_iterator_result_object(global_object, JS::js_string(vm, StringView { pair.value }), false);
|
||||
case JS::Object::PropertyKind::KeyAndValue: {
|
||||
auto* array = JS::Array::create_from(global_object, { JS::js_string(vm, StringView { pair.name }), JS::js_string(vm, StringView { pair.value }) });
|
||||
auto* array = JS::Array::create_from(realm, { JS::js_string(vm, StringView { pair.name }), JS::js_string(vm, StringView { pair.value }) });
|
||||
return create_iterator_result_object(global_object, array, false);
|
||||
}
|
||||
default:
|
||||
|
|
|
@ -222,13 +222,14 @@ DOM::ExceptionOr<NonnullRefPtr<Blob>> Blob::slice(Optional<i64> start, Optional<
|
|||
JS::Promise* Blob::text()
|
||||
{
|
||||
auto& global_object = wrapper()->global_object();
|
||||
auto& realm = *global_object.associated_realm();
|
||||
|
||||
// FIXME: 1. Let stream be the result of calling get stream on this.
|
||||
// FIXME: 2. Let reader be the result of getting a reader from stream. If that threw an exception, return a new promise rejected with that exception.
|
||||
|
||||
// FIXME: We still need to implement ReadableStream for this step to be fully valid.
|
||||
// 3. Let promise be the result of reading all bytes from stream with reader
|
||||
auto* promise = JS::Promise::create(global_object);
|
||||
auto* promise = JS::Promise::create(realm);
|
||||
auto* result = JS::js_string(global_object.heap(), String { m_byte_buffer.bytes() });
|
||||
|
||||
// 4. Return the result of transforming promise by a fulfillment handler that returns the result of running UTF-8 decode on its first argument.
|
||||
|
@ -240,14 +241,15 @@ JS::Promise* Blob::text()
|
|||
JS::Promise* Blob::array_buffer()
|
||||
{
|
||||
auto& global_object = wrapper()->global_object();
|
||||
auto& realm = *global_object.associated_realm();
|
||||
|
||||
// FIXME: 1. Let stream be the result of calling get stream on this.
|
||||
// FIXME: 2. Let reader be the result of getting a reader from stream. If that threw an exception, return a new promise rejected with that exception.
|
||||
|
||||
// FIXME: We still need to implement ReadableStream for this step to be fully valid.
|
||||
// 3. Let promise be the result of reading all bytes from stream with reader.
|
||||
auto* promise = JS::Promise::create(global_object);
|
||||
auto buffer_result = JS::ArrayBuffer::create(global_object, m_byte_buffer.size());
|
||||
auto* promise = JS::Promise::create(realm);
|
||||
auto buffer_result = JS::ArrayBuffer::create(realm, m_byte_buffer.size());
|
||||
if (buffer_result.is_error()) {
|
||||
promise->reject(buffer_result.release_error().value().release_value());
|
||||
return promise;
|
||||
|
|
|
@ -12,13 +12,15 @@ namespace Web::HTML {
|
|||
|
||||
RefPtr<ImageData> ImageData::create_with_size(JS::GlobalObject& global_object, int width, int height)
|
||||
{
|
||||
auto& realm = *global_object.associated_realm();
|
||||
|
||||
if (width <= 0 || height <= 0)
|
||||
return nullptr;
|
||||
|
||||
if (width > 16384 || height > 16384)
|
||||
return nullptr;
|
||||
|
||||
auto data_or_error = JS::Uint8ClampedArray::create(global_object, width * height * 4);
|
||||
auto data_or_error = JS::Uint8ClampedArray::create(realm, width * height * 4);
|
||||
if (data_or_error.is_error())
|
||||
return nullptr;
|
||||
auto* data = data_or_error.release_value();
|
||||
|
|
|
@ -16,6 +16,7 @@ JS::Object* URLSearchParamsIterator::next()
|
|||
{
|
||||
auto& global_object = wrapper()->global_object();
|
||||
auto& vm = global_object.vm();
|
||||
auto& realm = *global_object.associated_realm();
|
||||
|
||||
if (m_index >= m_url_search_params.m_list.size())
|
||||
return create_iterator_result_object(global_object, JS::js_undefined(), true);
|
||||
|
@ -26,7 +27,7 @@ JS::Object* URLSearchParamsIterator::next()
|
|||
else if (m_iteration_kind == JS::Object::PropertyKind::Value)
|
||||
return create_iterator_result_object(global_object, JS::js_string(vm, entry.value), false);
|
||||
|
||||
return create_iterator_result_object(global_object, JS::Array::create_from(global_object, { JS::js_string(vm, entry.name), JS::js_string(vm, entry.value) }), false);
|
||||
return create_iterator_result_object(global_object, JS::Array::create_from(realm, { JS::js_string(vm, entry.name), JS::js_string(vm, entry.value) }), false);
|
||||
}
|
||||
|
||||
void URLSearchParamsIterator::visit_edges(JS::Cell::Visitor& visitor)
|
||||
|
|
|
@ -28,7 +28,7 @@ void WebAssemblyInstanceObject::initialize(JS::Realm& realm)
|
|||
Object::initialize(realm);
|
||||
|
||||
VERIFY(!m_exports_object);
|
||||
m_exports_object = create(realm.global_object(), nullptr);
|
||||
m_exports_object = create(realm, nullptr);
|
||||
auto& instance = this->instance();
|
||||
auto& cache = this->cache();
|
||||
for (auto& export_ : instance.exports()) {
|
||||
|
|
|
@ -38,6 +38,8 @@ JS_DEFINE_NATIVE_FUNCTION(WebAssemblyMemoryPrototype::grow)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(WebAssemblyMemoryPrototype::buffer_getter)
|
||||
{
|
||||
auto& realm = *global_object.associated_realm();
|
||||
|
||||
auto* this_object = TRY(vm.this_value(global_object).to_object(global_object));
|
||||
if (!is<WebAssemblyMemoryObject>(this_object))
|
||||
return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "WebAssembly.Memory");
|
||||
|
@ -47,7 +49,7 @@ JS_DEFINE_NATIVE_FUNCTION(WebAssemblyMemoryPrototype::buffer_getter)
|
|||
if (!memory)
|
||||
return JS::js_undefined();
|
||||
|
||||
auto* array_buffer = JS::ArrayBuffer::create(global_object, &memory->data());
|
||||
auto* array_buffer = JS::ArrayBuffer::create(realm, &memory->data());
|
||||
array_buffer->set_detach_key(JS::js_string(vm, "WebAssembly.Memory"));
|
||||
return array_buffer;
|
||||
}
|
||||
|
|
|
@ -164,7 +164,7 @@ JS_DEFINE_NATIVE_FUNCTION(WebAssemblyObject::compile)
|
|||
if (buffer_or_error.is_error())
|
||||
rejection_value = *buffer_or_error.throw_completion().value();
|
||||
|
||||
auto promise = JS::Promise::create(global_object);
|
||||
auto promise = JS::Promise::create(realm);
|
||||
if (!rejection_value.is_empty()) {
|
||||
promise->reject(rejection_value);
|
||||
return promise;
|
||||
|
@ -323,7 +323,7 @@ JS_DEFINE_NATIVE_FUNCTION(WebAssemblyObject::instantiate)
|
|||
|
||||
// FIXME: This shouldn't block!
|
||||
auto buffer_or_error = vm.argument(0).to_object(global_object);
|
||||
auto promise = JS::Promise::create(global_object);
|
||||
auto promise = JS::Promise::create(realm);
|
||||
bool should_return_module = false;
|
||||
if (buffer_or_error.is_error()) {
|
||||
auto rejection_value = *buffer_or_error.throw_completion().value();
|
||||
|
@ -344,7 +344,7 @@ JS_DEFINE_NATIVE_FUNCTION(WebAssemblyObject::instantiate)
|
|||
} else if (is<WebAssemblyModuleObject>(buffer)) {
|
||||
module = &static_cast<WebAssemblyModuleObject*>(buffer)->module();
|
||||
} else {
|
||||
auto error = JS::TypeError::create(global_object, String::formatted("{} is not an ArrayBuffer or a Module", buffer->class_name()));
|
||||
auto error = JS::TypeError::create(realm, String::formatted("{} is not an ArrayBuffer or a Module", buffer->class_name()));
|
||||
promise->reject(error);
|
||||
return promise;
|
||||
}
|
||||
|
@ -356,7 +356,7 @@ JS_DEFINE_NATIVE_FUNCTION(WebAssemblyObject::instantiate)
|
|||
} else {
|
||||
auto instance_object = vm.heap().allocate<WebAssemblyInstanceObject>(global_object, realm, result.release_value());
|
||||
if (should_return_module) {
|
||||
auto object = JS::Object::create(global_object, nullptr);
|
||||
auto object = JS::Object::create(realm, nullptr);
|
||||
object->define_direct_property("module", vm.heap().allocate<WebAssemblyModuleObject>(global_object, realm, s_compiled_modules.size() - 1), JS::default_attributes);
|
||||
object->define_direct_property("instance", instance_object, JS::default_attributes);
|
||||
promise->fulfill(object);
|
||||
|
@ -442,15 +442,17 @@ JS::ThrowCompletionOr<Wasm::Value> to_webassembly_value(JS::GlobalObject& global
|
|||
|
||||
JS::NativeFunction* create_native_function(JS::GlobalObject& global_object, Wasm::FunctionAddress address, String const& name)
|
||||
{
|
||||
auto& realm = *global_object.associated_realm();
|
||||
Optional<Wasm::FunctionType> type;
|
||||
WebAssemblyObject::s_abstract_machine.store().get(address)->visit([&](auto const& value) { type = value.type(); });
|
||||
if (auto entry = WebAssemblyObject::s_global_cache.function_instances.get(address); entry.has_value())
|
||||
return *entry;
|
||||
|
||||
auto function = JS::NativeFunction::create(
|
||||
global_object,
|
||||
realm,
|
||||
name,
|
||||
[address, type = type.release_value()](JS::VM& vm, JS::GlobalObject& global_object) -> JS::ThrowCompletionOr<JS::Value> {
|
||||
auto& realm = *global_object.associated_realm();
|
||||
Vector<Wasm::Value> values;
|
||||
values.ensure_capacity(type.parameters().size());
|
||||
|
||||
|
@ -474,7 +476,7 @@ JS::NativeFunction* create_native_function(JS::GlobalObject& global_object, Wasm
|
|||
for (auto& entry : result.values())
|
||||
result_values.append(to_js_value(global_object, entry));
|
||||
|
||||
return JS::Value(JS::Array::create_from(global_object, result_values));
|
||||
return JS::Value(JS::Array::create_from(realm, result_values));
|
||||
});
|
||||
|
||||
WebAssemblyObject::s_global_cache.function_instances.set(address, function);
|
||||
|
|
|
@ -214,8 +214,9 @@ void WebSocket::on_message(ByteBuffer message, bool is_text)
|
|||
} else if (m_binary_type == "arraybuffer") {
|
||||
// type indicates that the data is Binary and binaryType is "arraybuffer"
|
||||
auto& global_object = wrapper()->global_object();
|
||||
auto& realm = *global_object.associated_realm();
|
||||
HTML::MessageEventInit event_init;
|
||||
event_init.data = JS::ArrayBuffer::create(global_object, message);
|
||||
event_init.data = JS::ArrayBuffer::create(realm, message);
|
||||
event_init.origin = url();
|
||||
dispatch_event(HTML::MessageEvent::create(HTML::EventNames::message, event_init));
|
||||
return;
|
||||
|
|
|
@ -83,6 +83,7 @@ DOM::ExceptionOr<String> XMLHttpRequest::response_text() const
|
|||
DOM::ExceptionOr<JS::Value> XMLHttpRequest::response()
|
||||
{
|
||||
auto& global_object = wrapper()->global_object();
|
||||
auto& realm = *global_object.associated_realm();
|
||||
|
||||
// 1. If this’s response type is the empty string or "text", then:
|
||||
if (m_response_type == Bindings::XMLHttpRequestResponseType::Empty || m_response_type == Bindings::XMLHttpRequestResponseType::Text) {
|
||||
|
@ -108,7 +109,7 @@ DOM::ExceptionOr<JS::Value> XMLHttpRequest::response()
|
|||
// 5. If this’s response type is "arraybuffer",
|
||||
if (m_response_type == Bindings::XMLHttpRequestResponseType::Arraybuffer) {
|
||||
// then set this’s response object to a new ArrayBuffer object representing this’s received bytes. If this throws an exception, then set this’s response object to failure and return null.
|
||||
auto buffer_result = JS::ArrayBuffer::create(global_object, m_received_bytes.size());
|
||||
auto buffer_result = JS::ArrayBuffer::create(realm, m_received_bytes.size());
|
||||
if (buffer_result.is_error()) {
|
||||
m_response_object = Failure();
|
||||
return JS::js_null();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue