diff --git a/Libraries/LibWeb/Bindings/MainThreadVM.cpp b/Libraries/LibWeb/Bindings/MainThreadVM.cpp index 113a551d85f..743a3fe5626 100644 --- a/Libraries/LibWeb/Bindings/MainThreadVM.cpp +++ b/Libraries/LibWeb/Bindings/MainThreadVM.cpp @@ -713,7 +713,7 @@ void queue_mutation_observer_microtask(DOM::Document const& document) MUST(wrapped_records->create_data_property(property_index, record.ptr())); } - (void)WebIDL::invoke_callback(callback, mutation_observer, WebIDL::ExceptionBehavior::Report, wrapped_records, mutation_observer); + (void)WebIDL::invoke_callback(callback, mutation_observer, WebIDL::ExceptionBehavior::Report, { { wrapped_records, mutation_observer } }); } } diff --git a/Libraries/LibWeb/DOM/Document.cpp b/Libraries/LibWeb/DOM/Document.cpp index 0e8e5d7ac95..bbcd8936da3 100644 --- a/Libraries/LibWeb/DOM/Document.cpp +++ b/Libraries/LibWeb/DOM/Document.cpp @@ -4569,7 +4569,7 @@ void Document::queue_intersection_observer_task() // 5. Invoke callback with queue as the first argument, observer as the second argument, and observer as the callback this value. If this throws an exception, report the exception. // NOTE: This does not follow the spec as written precisely, but this is the same thing we do elsewhere and there is a WPT test that relies on this. - (void)WebIDL::invoke_callback(callback, observer.ptr(), WebIDL::ExceptionBehavior::Report, wrapped_queue, observer.ptr()); + (void)WebIDL::invoke_callback(callback, observer.ptr(), WebIDL::ExceptionBehavior::Report, { { wrapped_queue, observer.ptr() } }); } })); } diff --git a/Libraries/LibWeb/DOM/Element.cpp b/Libraries/LibWeb/DOM/Element.cpp index f9b30c574c1..e9a47a9093c 100644 --- a/Libraries/LibWeb/DOM/Element.cpp +++ b/Libraries/LibWeb/DOM/Element.cpp @@ -2517,7 +2517,7 @@ JS::ThrowCompletionOr Element::upgrade_element(GC::Ref> create_element(Document& document, FlyStri auto& constructor = definition->constructor(); // 2. Set result to the result of constructing C, with no arguments. - auto result = TRY(WebIDL::construct(constructor)); + auto result = TRY(WebIDL::construct(constructor, {})); // NOTE: IDL does not currently convert the object for us, so we will have to do it here. if (!result.is_object() || !is(result.as_object())) diff --git a/Libraries/LibWeb/DOM/EventDispatcher.cpp b/Libraries/LibWeb/DOM/EventDispatcher.cpp index 57c3d38eefe..ec0cdc34ad1 100644 --- a/Libraries/LibWeb/DOM/EventDispatcher.cpp +++ b/Libraries/LibWeb/DOM/EventDispatcher.cpp @@ -91,7 +91,7 @@ bool EventDispatcher::inner_invoke(Event& event, Vector EventTarget::process_event_handler_for_event(FlyStri // calls directly into the callback without considering things such as proxies, it is a waste. However, if it observable, then we must reuse the this_value that was given to the callback. auto* this_value = error_event.current_target().ptr(); - return_value_or_error = WebIDL::invoke_callback(*callback, this_value, wrapped_message, wrapped_filename, wrapped_lineno, wrapped_colno, error_event.error()); + return_value_or_error = WebIDL::invoke_callback(*callback, this_value, { { wrapped_message, wrapped_filename, wrapped_lineno, wrapped_colno, error_event.error() } }); } else { // -> Otherwise // Invoke callback with one argument, the value of which is the Event object event, with the callback this value set to event's currentTarget. Let return value be the callback's return value. [WEBIDL] @@ -709,7 +709,7 @@ JS::ThrowCompletionOr EventTarget::process_event_handler_for_event(FlyStri // FIXME: The comments about this in the special_error_event_handling path also apply here. auto* this_value = event.current_target().ptr(); - return_value_or_error = WebIDL::invoke_callback(*callback, this_value, wrapped_event); + return_value_or_error = WebIDL::invoke_callback(*callback, this_value, { { wrapped_event } }); } // If an exception gets thrown by the callback, end these steps and allow the exception to propagate. (It will propagate to the DOM event dispatch logic, which will then report the exception.) diff --git a/Libraries/LibWeb/DOM/NodeIterator.cpp b/Libraries/LibWeb/DOM/NodeIterator.cpp index a4f8def926b..d15386878ea 100644 --- a/Libraries/LibWeb/DOM/NodeIterator.cpp +++ b/Libraries/LibWeb/DOM/NodeIterator.cpp @@ -169,7 +169,7 @@ JS::ThrowCompletionOr NodeIterator::filter(Node& node) // 6. Let result be the return value of call a user object’s operation with traverser’s filter, "acceptNode", and « node ». // If this throws an exception, then unset traverser’s active flag and rethrow the exception. - auto result = WebIDL::call_user_object_operation(m_filter->callback(), "acceptNode"_string, {}, &node); + auto result = WebIDL::call_user_object_operation(m_filter->callback(), "acceptNode"_string, {}, { { &node } }); if (result.is_abrupt()) { m_active = false; return result; diff --git a/Libraries/LibWeb/DOM/TreeWalker.cpp b/Libraries/LibWeb/DOM/TreeWalker.cpp index aeea0ae6f4e..ee4f0bf8850 100644 --- a/Libraries/LibWeb/DOM/TreeWalker.cpp +++ b/Libraries/LibWeb/DOM/TreeWalker.cpp @@ -274,7 +274,7 @@ JS::ThrowCompletionOr TreeWalker::filter(Node& node) // 6. Let result be the return value of call a user object’s operation with traverser’s filter, "acceptNode", and « node ». // If this throws an exception, then unset traverser’s active flag and rethrow the exception. - auto result = WebIDL::call_user_object_operation(m_filter->callback(), "acceptNode"_string, {}, &node); + auto result = WebIDL::call_user_object_operation(m_filter->callback(), "acceptNode"_string, {}, { { &node } }); if (result.is_abrupt()) { m_active = false; return result; diff --git a/Libraries/LibWeb/HTML/DataTransferItem.cpp b/Libraries/LibWeb/HTML/DataTransferItem.cpp index 27395435606..636c67e0ba6 100644 --- a/Libraries/LibWeb/HTML/DataTransferItem.cpp +++ b/Libraries/LibWeb/HTML/DataTransferItem.cpp @@ -117,7 +117,7 @@ void DataTransferItem::get_as_string(GC::Ptr callback) con HTML::queue_a_task(HTML::Task::Source::Unspecified, nullptr, nullptr, GC::Function::create(realm.heap(), [callback, data]() { - (void)WebIDL::invoke_callback(*callback, {}, data); + (void)WebIDL::invoke_callback(*callback, {}, { { data } }); })); } diff --git a/Libraries/LibWeb/HTML/HTMLCanvasElement.cpp b/Libraries/LibWeb/HTML/HTMLCanvasElement.cpp index 7334d9ba7ce..59d50fedbf6 100644 --- a/Libraries/LibWeb/HTML/HTMLCanvasElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLCanvasElement.cpp @@ -397,7 +397,7 @@ WebIDL::ExceptionOr HTMLCanvasElement::to_blob(GC::Refbuffer, TRY_OR_THROW_OOM(vm(), String::from_utf8(file_result->mime_type))); // 2. Invoke callback with « result » and "report". - TRY(WebIDL::invoke_callback(*callback, {}, WebIDL::ExceptionBehavior::Report, move(blob_result))); + TRY(WebIDL::invoke_callback(*callback, {}, WebIDL::ExceptionBehavior::Report, { { blob_result } })); return {}; }); if (maybe_error.is_throw_completion()) diff --git a/Libraries/LibWeb/HTML/Navigation.cpp b/Libraries/LibWeb/HTML/Navigation.cpp index 4a4ae1fc856..298e4d12b2c 100644 --- a/Libraries/LibWeb/HTML/Navigation.cpp +++ b/Libraries/LibWeb/HTML/Navigation.cpp @@ -1141,7 +1141,7 @@ bool Navigation::inner_navigate_event_firing_algorithm( // 2. For each handler of event's navigation handler list: for (auto const& handler : event->navigation_handler_list()) { // 1. Append the result of invoking handler with an empty arguments list to promisesList. - auto result = WebIDL::invoke_callback(handler, {}); + auto result = WebIDL::invoke_callback(handler, {}, {}); // This *should* be equivalent to converting a promise to a promise capability promises_list.append(WebIDL::create_resolved_promise(realm, result.value())); } diff --git a/Libraries/LibWeb/HTML/UniversalGlobalScope.cpp b/Libraries/LibWeb/HTML/UniversalGlobalScope.cpp index f769f572c1d..94795939b70 100644 --- a/Libraries/LibWeb/HTML/UniversalGlobalScope.cpp +++ b/Libraries/LibWeb/HTML/UniversalGlobalScope.cpp @@ -86,7 +86,7 @@ void UniversalGlobalScopeMixin::queue_microtask(WebIDL::CallbackType& callback) // The queueMicrotask(callback) method must queue a microtask to invoke callback with « » and "report". HTML::queue_a_microtask(document, GC::create_function(realm.heap(), [&callback] { - (void)WebIDL::invoke_callback(callback, {}, WebIDL::ExceptionBehavior::Report); + (void)WebIDL::invoke_callback(callback, {}, WebIDL::ExceptionBehavior::Report, {}); })); } diff --git a/Libraries/LibWeb/HTML/Window.cpp b/Libraries/LibWeb/HTML/Window.cpp index a665b2dbbdf..fa7c5f57113 100644 --- a/Libraries/LibWeb/HTML/Window.cpp +++ b/Libraries/LibWeb/HTML/Window.cpp @@ -1611,7 +1611,7 @@ WebIDL::UnsignedLong Window::request_animation_frame(GC::Ref deadline) -> JS::Completion { - return WebIDL::invoke_callback(*callback, {}, deadline.ptr()); + return WebIDL::invoke_callback(*callback, {}, { { deadline } }); }; m_idle_request_callbacks.append(adopt_ref(*new IdleCallback(move(handler), handle))); diff --git a/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.cpp b/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.cpp index 2b226197edb..395c7a00788 100644 --- a/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.cpp +++ b/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.cpp @@ -639,7 +639,7 @@ void WindowOrWorkerGlobalScopeMixin::queue_the_performance_observer_task() // 9. Call po’s observer callback with observerEntryList as the first argument, with po as the second // argument and as callback this value, and with callbackOptions as the third argument. // If this throws an exception, report the exception. - auto completion = WebIDL::invoke_callback(registered_observer->callback(), registered_observer, observer_entry_list, registered_observer, callback_options); + auto completion = WebIDL::invoke_callback(registered_observer->callback(), registered_observer, { { observer_entry_list, registered_observer, callback_options } }); if (completion.is_abrupt()) HTML::report_exception(completion, realm); } diff --git a/Libraries/LibWeb/ResizeObserver/ResizeObserver.cpp b/Libraries/LibWeb/ResizeObserver/ResizeObserver.cpp index 8e6f8567db5..2b5e2bfad10 100644 --- a/Libraries/LibWeb/ResizeObserver/ResizeObserver.cpp +++ b/Libraries/LibWeb/ResizeObserver/ResizeObserver.cpp @@ -109,7 +109,7 @@ void ResizeObserver::invoke_callback(ReadonlySpan> MUST(wrapped_records->create_data_property(property_index, record.ptr())); } - (void)WebIDL::invoke_callback(callback, JS::js_undefined(), WebIDL::ExceptionBehavior::Report, wrapped_records); + (void)WebIDL::invoke_callback(callback, JS::js_undefined(), WebIDL::ExceptionBehavior::Report, { { wrapped_records } }); } } diff --git a/Libraries/LibWeb/Streams/AbstractOperations.cpp b/Libraries/LibWeb/Streams/AbstractOperations.cpp index 91bb46e3fb2..269d152f630 100644 --- a/Libraries/LibWeb/Streams/AbstractOperations.cpp +++ b/Libraries/LibWeb/Streams/AbstractOperations.cpp @@ -1762,7 +1762,8 @@ GC::Ref extract_size_algorithm(JS::VM& vm, QueuingStrategy const& // 2. Return an algorithm that performs the following steps, taking a chunk argument: return GC::create_function(vm.heap(), [size = strategy.size](JS::Value chunk) { - return WebIDL::invoke_callback(*size, JS::js_undefined(), chunk); + // 1. Return the result of invoking strategy["size"] with argument list « chunk ». + return WebIDL::invoke_callback(*size, {}, { { chunk } }); }); } @@ -3145,7 +3146,7 @@ WebIDL::ExceptionOr set_up_readable_stream_default_controller_from_underly // invoking underlyingSourceDict["start"] with argument list « controller » and callback this value underlyingSource. if (underlying_source.start) { start_algorithm = GC::create_function(realm.heap(), [controller, underlying_source_value, callback = underlying_source.start]() -> WebIDL::ExceptionOr { - return TRY(WebIDL::invoke_callback(*callback, underlying_source_value, controller)); + return TRY(WebIDL::invoke_callback(*callback, underlying_source_value, { { controller } })); }); } @@ -3153,7 +3154,7 @@ WebIDL::ExceptionOr set_up_readable_stream_default_controller_from_underly // invoking underlyingSourceDict["pull"] with argument list « controller » and callback this value underlyingSource. if (underlying_source.pull) { pull_algorithm = GC::create_function(realm.heap(), [controller, underlying_source_value, callback = underlying_source.pull]() { - return WebIDL::invoke_promise_callback(*callback, underlying_source_value, controller); + return WebIDL::invoke_promise_callback(*callback, underlying_source_value, { { controller } }); }); } @@ -3162,7 +3163,7 @@ WebIDL::ExceptionOr set_up_readable_stream_default_controller_from_underly // callback this value underlyingSource. if (underlying_source.cancel) { cancel_algorithm = GC::create_function(realm.heap(), [underlying_source_value, callback = underlying_source.cancel](JS::Value reason) { - return WebIDL::invoke_promise_callback(*callback, underlying_source_value, reason); + return WebIDL::invoke_promise_callback(*callback, underlying_source_value, { { reason } }); }); } @@ -4846,7 +4847,7 @@ WebIDL::ExceptionOr set_up_writable_stream_default_controller_from_underly // callback this value underlyingSink. if (underlying_sink.start) { start_algorithm = GC::create_function(realm.heap(), [controller, underlying_sink_value, callback = underlying_sink.start]() -> WebIDL::ExceptionOr { - return TRY(WebIDL::invoke_callback(*callback, underlying_sink_value, WebIDL::ExceptionBehavior::Rethrow, controller)); + return TRY(WebIDL::invoke_callback(*callback, underlying_sink_value, WebIDL::ExceptionBehavior::Rethrow, { { controller } })); }); } @@ -4855,7 +4856,7 @@ WebIDL::ExceptionOr set_up_writable_stream_default_controller_from_underly // callback this value underlyingSink. if (underlying_sink.write) { write_algorithm = GC::create_function(realm.heap(), [controller, underlying_sink_value, callback = underlying_sink.write](JS::Value chunk) { - return WebIDL::invoke_promise_callback(*callback, underlying_sink_value, chunk, controller); + return WebIDL::invoke_promise_callback(*callback, underlying_sink_value, { { chunk, controller } }); }); } @@ -4863,7 +4864,7 @@ WebIDL::ExceptionOr set_up_writable_stream_default_controller_from_underly // invoking underlyingSinkDict["close"] with argument list «» and callback this value underlyingSink. if (underlying_sink.close) { close_algorithm = GC::create_function(realm.heap(), [underlying_sink_value, callback = underlying_sink.close]() { - return WebIDL::invoke_promise_callback(*callback, underlying_sink_value); + return WebIDL::invoke_promise_callback(*callback, underlying_sink_value, {}); }); } @@ -4872,7 +4873,7 @@ WebIDL::ExceptionOr set_up_writable_stream_default_controller_from_underly // value underlyingSink. if (underlying_sink.abort) { abort_algorithm = GC::create_function(realm.heap(), [underlying_sink_value, callback = underlying_sink.abort](JS::Value reason) { - return WebIDL::invoke_promise_callback(*callback, underlying_sink_value, reason); + return WebIDL::invoke_promise_callback(*callback, underlying_sink_value, { { reason } }); }); } @@ -5275,7 +5276,7 @@ void set_up_transform_stream_default_controller_from_transformer(TransformStream // callback this value transformer. if (transformer_dict.transform) { transform_algorithm = GC::create_function(realm.heap(), [controller, transformer, callback = transformer_dict.transform](JS::Value chunk) { - return WebIDL::invoke_promise_callback(*callback, transformer, chunk, controller); + return WebIDL::invoke_promise_callback(*callback, transformer, { { chunk, controller } }); }); } @@ -5283,7 +5284,7 @@ void set_up_transform_stream_default_controller_from_transformer(TransformStream // transformerDict["flush"] with argument list « controller » and callback this value transformer. if (transformer_dict.flush) { flush_algorithm = GC::create_function(realm.heap(), [transformer, callback = transformer_dict.flush, controller]() { - return WebIDL::invoke_promise_callback(*callback, transformer, controller); + return WebIDL::invoke_promise_callback(*callback, transformer, { { controller } }); }); } @@ -5291,7 +5292,7 @@ void set_up_transform_stream_default_controller_from_transformer(TransformStream // the result of invoking transformerDict["cancel"] with argument list « reason » and callback this value transformer. if (transformer_dict.cancel) { cancel_algorithm = GC::create_function(realm.heap(), [transformer, callback = transformer_dict.cancel](JS::Value reason) { - return WebIDL::invoke_promise_callback(*callback, transformer, reason); + return WebIDL::invoke_promise_callback(*callback, transformer, { { reason } }); }); } @@ -5816,7 +5817,7 @@ WebIDL::ExceptionOr set_up_readable_byte_stream_controller_from_underlying // invoking underlyingSourceDict["start"] with argument list « controller » and callback this value underlyingSource. if (underlying_source_dict.start) { start_algorithm = GC::create_function(realm.heap(), [controller, underlying_source, callback = underlying_source_dict.start]() -> WebIDL::ExceptionOr { - return TRY(WebIDL::invoke_callback(*callback, underlying_source, controller)); + return TRY(WebIDL::invoke_callback(*callback, underlying_source, { { controller } })); }); } @@ -5824,7 +5825,7 @@ WebIDL::ExceptionOr set_up_readable_byte_stream_controller_from_underlying // invoking underlyingSourceDict["pull"] with argument list « controller » and callback this value underlyingSource. if (underlying_source_dict.pull) { pull_algorithm = GC::create_function(realm.heap(), [controller, underlying_source, callback = underlying_source_dict.pull]() { - return WebIDL::invoke_promise_callback(*callback, underlying_source, controller); + return WebIDL::invoke_promise_callback(*callback, underlying_source, { { controller } }); }); } @@ -5833,7 +5834,7 @@ WebIDL::ExceptionOr set_up_readable_byte_stream_controller_from_underlying // callback this value underlyingSource. if (underlying_source_dict.cancel) { cancel_algorithm = GC::create_function(realm.heap(), [underlying_source, callback = underlying_source_dict.cancel](JS::Value reason) { - return WebIDL::invoke_promise_callback(*callback, underlying_source, reason); + return WebIDL::invoke_promise_callback(*callback, underlying_source, { { reason } }); }); } diff --git a/Libraries/LibWeb/Streams/TransformStream.cpp b/Libraries/LibWeb/Streams/TransformStream.cpp index 53b5cca71d0..13514cc2555 100644 --- a/Libraries/LibWeb/Streams/TransformStream.cpp +++ b/Libraries/LibWeb/Streams/TransformStream.cpp @@ -63,7 +63,7 @@ WebIDL::ExceptionOr> TransformStream::construct_impl(JS // 12. If transformerDict["start"] exists, then resolve startPromise with the result of invoking // transformerDict["start"] with argument list « this.[[controller]] » and callback this value transformer. if (transformer_dict.start) { - auto result = TRY(WebIDL::invoke_callback(*transformer_dict.start, transformer, stream->controller())); + auto result = TRY(WebIDL::invoke_callback(*transformer_dict.start, transformer, { { stream->controller() } })); WebIDL::resolve_promise(realm, start_promise, result); } // 13. Otherwise, resolve startPromise with undefined. diff --git a/Libraries/LibWeb/WebAudio/BaseAudioContext.cpp b/Libraries/LibWeb/WebAudio/BaseAudioContext.cpp index e2592601f16..9c5b5af17d9 100644 --- a/Libraries/LibWeb/WebAudio/BaseAudioContext.cpp +++ b/Libraries/LibWeb/WebAudio/BaseAudioContext.cpp @@ -243,7 +243,7 @@ GC::Ref BaseAudioContext::decode_audio_data(GC::Root // 4.2. If errorCallback is not missing, invoke errorCallback with error. if (error_callback) { - auto completion = WebIDL::invoke_callback(*error_callback, {}, error); + auto completion = WebIDL::invoke_callback(*error_callback, {}, { { error } }); if (completion.is_abrupt()) HTML::report_exception(completion, realm); } @@ -317,7 +317,7 @@ void BaseAudioContext::queue_a_decoding_operation(GC::Ref // 5.2.3. If successCallback is not missing, invoke successCallback with buffer. if (success_callback) { - auto completion = WebIDL::invoke_callback(*success_callback, {}, buffer); + auto completion = WebIDL::invoke_callback(*success_callback, {}, { { buffer } }); if (completion.is_abrupt()) HTML::report_exception(completion, realm); } diff --git a/Libraries/LibWeb/WebIDL/AbstractOperations.cpp b/Libraries/LibWeb/WebIDL/AbstractOperations.cpp index 30b993bef6f..794b27eb170 100644 --- a/Libraries/LibWeb/WebIDL/AbstractOperations.cpp +++ b/Libraries/LibWeb/WebIDL/AbstractOperations.cpp @@ -8,17 +8,17 @@ #include #include -#include #include #include #include #include -#include +#include #include #include -#include -#include +#include +#include #include +#include #include #include @@ -141,7 +141,7 @@ inline JS::Completion clean_up_on_return(JS::Realm& stored_realm, JS::Realm& rel // https://webidl.spec.whatwg.org/#call-a-user-objects-operation // https://whatpr.org/webidl/1437.html#call-a-user-objects-operation -JS::Completion call_user_object_operation(WebIDL::CallbackType& callback, String const& operation_name, Optional this_argument, GC::RootVector args) +JS::Completion call_user_object_operation(CallbackType& callback, String const& operation_name, Optional this_argument, ReadonlySpan args) { // 1. Let completion be an uninitialized variable. JS::Completion completion; @@ -197,9 +197,7 @@ JS::Completion call_user_object_operation(WebIDL::CallbackType& callback, String // For simplicity, we currently make the caller do this. However, this means we can't throw exceptions at this point like the spec wants us to. // 11. Let callResult be Call(X, thisArg, esArgs). - VERIFY(actual_function_object); - auto& vm = object->vm(); - auto call_result = JS::call(vm, as(*actual_function_object), this_argument.value(), args.span()); + auto call_result = JS::call(object->vm(), as(*actual_function_object), this_argument.value(), args); // 12. If callResult is an abrupt completion, set completion to callResult and jump to the step labeled return. if (call_result.is_throw_completion()) { @@ -244,7 +242,7 @@ JS::ThrowCompletionOr to_usv_string(JS::VM& vm, JS::Value value) // https://webidl.spec.whatwg.org/#invoke-a-callback-function // https://whatpr.org/webidl/1437.html#invoke-a-callback-function template -static auto invoke_callback_impl(WebIDL::CallbackType& callback, Optional this_argument, GC::RootVector args, ReturnSteps&& return_steps) +static auto invoke_callback_impl(CallbackType& callback, Optional this_argument, ReadonlySpan args, ReturnSteps&& return_steps) { // 1. Let completion be an uninitialized variable. @@ -279,8 +277,7 @@ static auto invoke_callback_impl(WebIDL::CallbackType& callback, Optionalvm(); - auto call_result = JS::call(vm, as(*function_object), this_argument.value(), args.span()); + auto call_result = JS::call(function_object->vm(), as(*function_object), this_argument.value(), args); // 11. If callResult is an abrupt completion, set completion to callResult and jump to the step labeled return. // 12. Set completion to the result of converting callResult.[[Value]] to an IDL value of the same type as callable’s @@ -298,7 +295,7 @@ static auto invoke_callback_impl(WebIDL::CallbackType& callback, Optional this_argument, ExceptionBehavior exception_behavior, GC::RootVector args) +JS::Completion invoke_callback(CallbackType& callback, Optional this_argument, ExceptionBehavior exception_behavior, ReadonlySpan args) { // https://webidl.spec.whatwg.org/#js-invoking-callback-functions // The exceptionBehavior argument must be supplied if, and only if, callable’s return type is not a promise type. If callable’s return type is neither undefined nor any, it must be "rethrow". @@ -308,7 +305,7 @@ JS::Completion invoke_callback(WebIDL::CallbackType& callback, Optional JS::Completion { + return invoke_callback_impl(callback, move(this_argument), args, [&](JS::Realm& relevant_realm, JS::Completion completion) -> JS::Completion { // 3. If completion is an IDL value, return completion. if (!completion.is_abrupt()) return completion; @@ -344,21 +341,21 @@ JS::Completion invoke_callback(WebIDL::CallbackType& callback, Optional this_argument, GC::RootVector args) +JS::Completion invoke_callback(CallbackType& callback, Optional this_argument, ReadonlySpan args) { - return invoke_callback(callback, move(this_argument), ExceptionBehavior::NotSpecified, move(args)); + return invoke_callback(callback, move(this_argument), ExceptionBehavior::NotSpecified, args); } // AD-HOC: This may be used as an alternative to WebIDL::invoke_callback when you know the callback returns a promise, // and the caller needs a WebIDL::Promise rather than a JS::Promise. -GC::Ref invoke_promise_callback(WebIDL::CallbackType& callback, Optional this_argument, GC::RootVector args) +GC::Ref invoke_promise_callback(CallbackType& callback, Optional this_argument, ReadonlySpan args) { VERIFY(callback.operation_returns_promise == OperationReturnsPromise::Yes); - return invoke_callback_impl(callback, move(this_argument), move(args), [&](JS::Realm& relevant_realm, JS::Completion completion) -> GC::Ref { + return invoke_callback_impl(callback, move(this_argument), args, [&](JS::Realm& relevant_realm, JS::Completion completion) { // 3. If completion is an IDL value, return completion. if (!completion.is_abrupt()) - return WebIDL::create_resolved_promise(relevant_realm, completion.release_value()); + return create_resolved_promise(relevant_realm, completion.release_value()); // 4. Assert: completion is an abrupt completion. VERIFY(completion.is_abrupt()); @@ -371,7 +368,7 @@ GC::Ref invoke_promise_callback(WebIDL::CallbackType& callback, }); } -JS::Completion construct(WebIDL::CallbackType& callback, GC::RootVector args) +JS::Completion construct(CallbackType& callback, ReadonlySpan args) { // 1. Let completion be an uninitialized variable. JS::Completion completion; @@ -399,8 +396,7 @@ JS::Completion construct(WebIDL::CallbackType& callback, GC::RootVectorvm(); - auto call_result = JS::construct(vm, as(*function_object), args.span()); + auto call_result = JS::construct(function_object->vm(), as(*function_object), args); // 9. If callResult is an abrupt completion, set completion to callResult and jump to the step labeled return. if (call_result.is_throw_completion()) { diff --git a/Libraries/LibWeb/WebIDL/AbstractOperations.h b/Libraries/LibWeb/WebIDL/AbstractOperations.h index f708538decf..3044a9c39ae 100644 --- a/Libraries/LibWeb/WebIDL/AbstractOperations.h +++ b/Libraries/LibWeb/WebIDL/AbstractOperations.h @@ -9,11 +9,9 @@ #pragma once #include +#include #include -#include -#include -#include -#include +#include namespace Web::WebIDL { @@ -21,77 +19,23 @@ bool is_buffer_source_type(JS::Value); GC::Ptr underlying_buffer_source(JS::Object& buffer_source); ErrorOr get_buffer_source_copy(JS::Object const& buffer_source); -JS::Completion call_user_object_operation(WebIDL::CallbackType& callback, String const& operation_name, Optional this_argument, GC::RootVector args); +JS::Completion call_user_object_operation(CallbackType& callback, String const& operation_name, Optional this_argument, ReadonlySpan args); JS::ThrowCompletionOr to_string(JS::VM&, JS::Value); JS::ThrowCompletionOr to_usv_string(JS::VM&, JS::Value); JS::ThrowCompletionOr to_byte_string(JS::VM&, JS::Value); -// https://webidl.spec.whatwg.org/#call-a-user-objects-operation -template -JS::Completion call_user_object_operation(WebIDL::CallbackType& callback, String const& operation_name, Optional this_argument, Args&&... args) -{ - auto& function_object = callback.callback; - - GC::RootVector arguments_list { function_object->heap() }; - (arguments_list.append(forward(args)), ...); - - return call_user_object_operation(callback, operation_name, move(this_argument), move(arguments_list)); -} - enum class ExceptionBehavior { NotSpecified, Report, Rethrow, }; +JS::Completion invoke_callback(CallbackType& callback, Optional this_argument, ExceptionBehavior exception_behavior, ReadonlySpan args); +JS::Completion invoke_callback(CallbackType& callback, Optional this_argument, ReadonlySpan args); -JS::Completion invoke_callback(WebIDL::CallbackType& callback, Optional this_argument, ExceptionBehavior exception_behavior, GC::RootVector args); -JS::Completion invoke_callback(WebIDL::CallbackType& callback, Optional this_argument, GC::RootVector args); +GC::Ref invoke_promise_callback(CallbackType& callback, Optional this_argument, ReadonlySpan args); -// https://webidl.spec.whatwg.org/#invoke-a-callback-function -template -JS::Completion invoke_callback(WebIDL::CallbackType& callback, Optional this_argument, ExceptionBehavior exception_behavior, Args&&... args) -{ - auto& function_object = callback.callback; - - GC::RootVector arguments_list { function_object->heap() }; - (arguments_list.append(forward(args)), ...); - - return invoke_callback(callback, move(this_argument), exception_behavior, move(arguments_list)); -} - -template -JS::Completion invoke_callback(WebIDL::CallbackType& callback, Optional this_argument, Args&&... args) -{ - return invoke_callback(callback, move(this_argument), ExceptionBehavior::NotSpecified, forward(args)...); -} - -GC::Ref invoke_promise_callback(WebIDL::CallbackType& callback, Optional this_argument, GC::RootVector args); - -template -GC::Ref invoke_promise_callback(WebIDL::CallbackType& callback, Optional this_argument, Args&&... args) -{ - auto& function_object = callback.callback; - - GC::RootVector arguments_list { function_object->heap() }; - (arguments_list.append(forward(args)), ...); - - return invoke_promise_callback(callback, move(this_argument), move(arguments_list)); -} - -JS::Completion construct(WebIDL::CallbackType& callback, GC::RootVector args); - -// https://webidl.spec.whatwg.org/#construct-a-callback-function -template -JS::Completion construct(WebIDL::CallbackType& callback, Args&&... args) -{ - auto& function_object = callback.callback; - - GC::RootVector arguments_list { function_object->heap() }; - (arguments_list.append(forward(args)), ...); - - return construct(callback, move(arguments_list)); -} +JS::Completion construct(CallbackType& callback, ReadonlySpan args); // https://webidl.spec.whatwg.org/#abstract-opdef-integerpart double integer_part(double n);