mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-29 04:09:13 +00:00
LibWeb: Do not create a RootVector to invoke IDL callbacks
These callbacks are evaluated synchronously via JS::Call. We do not need to construct an expensive RootVector container just to immediately invoke the callbacks. Stylistically, this also helps indicate where the actual arguments start at the call sites, by wrapping the arguments in braces.
This commit is contained in:
parent
ca2f0141f6
commit
6dd2a4c945
Notes:
github-actions[bot]
2025-04-16 11:32:56 +00:00
Author: https://github.com/trflynn89
Commit: 6dd2a4c945
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/4376
20 changed files with 60 additions and 119 deletions
|
@ -713,7 +713,7 @@ void queue_mutation_observer_microtask(DOM::Document const& document)
|
||||||
MUST(wrapped_records->create_data_property(property_index, record.ptr()));
|
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 } });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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.
|
// 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.
|
// 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() } });
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
|
@ -2517,7 +2517,7 @@ JS::ThrowCompletionOr<void> Element::upgrade_element(GC::Ref<HTML::CustomElement
|
||||||
set_custom_element_state(CustomElementState::Precustomized);
|
set_custom_element_state(CustomElementState::Precustomized);
|
||||||
|
|
||||||
// 3. Let constructResult be the result of constructing C, with no arguments.
|
// 3. Let constructResult be the result of constructing C, with no arguments.
|
||||||
auto construct_result = TRY(WebIDL::construct(constructor));
|
auto construct_result = TRY(WebIDL::construct(constructor, {}));
|
||||||
|
|
||||||
// 4. If SameValue(constructResult, element) is false, then throw a TypeError.
|
// 4. If SameValue(constructResult, element) is false, then throw a TypeError.
|
||||||
if (!JS::same_value(construct_result, this))
|
if (!JS::same_value(construct_result, this))
|
||||||
|
|
|
@ -578,7 +578,7 @@ WebIDL::ExceptionOr<GC::Ref<Element>> create_element(Document& document, FlyStri
|
||||||
auto& constructor = definition->constructor();
|
auto& constructor = definition->constructor();
|
||||||
|
|
||||||
// 2. Set result to the result of constructing C, with no arguments.
|
// 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.
|
// NOTE: IDL does not currently convert the object for us, so we will have to do it here.
|
||||||
if (!result.is_object() || !is<HTML::HTMLElement>(result.as_object()))
|
if (!result.is_object() || !is<HTML::HTMLElement>(result.as_object()))
|
||||||
|
|
|
@ -91,7 +91,7 @@ bool EventDispatcher::inner_invoke(Event& event, Vector<GC::Root<DOM::DOMEventLi
|
||||||
// FIXME: These should be wrapped for us in call_user_object_operation, but it currently doesn't do that.
|
// FIXME: These should be wrapped for us in call_user_object_operation, but it currently doesn't do that.
|
||||||
auto* this_value = event.current_target().ptr();
|
auto* this_value = event.current_target().ptr();
|
||||||
auto* wrapped_event = &event;
|
auto* wrapped_event = &event;
|
||||||
auto result = WebIDL::call_user_object_operation(callback, "handleEvent"_string, this_value, wrapped_event);
|
auto result = WebIDL::call_user_object_operation(callback, "handleEvent"_string, this_value, { { wrapped_event } });
|
||||||
|
|
||||||
// If this throws an exception, then:
|
// If this throws an exception, then:
|
||||||
if (result.is_error()) {
|
if (result.is_error()) {
|
||||||
|
|
|
@ -698,7 +698,7 @@ JS::ThrowCompletionOr<void> 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.
|
// 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();
|
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 {
|
} else {
|
||||||
// -> Otherwise
|
// -> 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]
|
// 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<void> EventTarget::process_event_handler_for_event(FlyStri
|
||||||
// FIXME: The comments about this in the special_error_event_handling path also apply here.
|
// FIXME: The comments about this in the special_error_event_handling path also apply here.
|
||||||
auto* this_value = event.current_target().ptr();
|
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.)
|
// 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.)
|
||||||
|
|
|
@ -169,7 +169,7 @@ JS::ThrowCompletionOr<NodeFilter::Result> 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 ».
|
// 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.
|
// 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()) {
|
if (result.is_abrupt()) {
|
||||||
m_active = false;
|
m_active = false;
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -274,7 +274,7 @@ JS::ThrowCompletionOr<NodeFilter::Result> 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 ».
|
// 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.
|
// 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()) {
|
if (result.is_abrupt()) {
|
||||||
m_active = false;
|
m_active = false;
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -117,7 +117,7 @@ void DataTransferItem::get_as_string(GC::Ptr<WebIDL::CallbackType> callback) con
|
||||||
|
|
||||||
HTML::queue_a_task(HTML::Task::Source::Unspecified, nullptr, nullptr,
|
HTML::queue_a_task(HTML::Task::Source::Unspecified, nullptr, nullptr,
|
||||||
GC::Function<void()>::create(realm.heap(), [callback, data]() {
|
GC::Function<void()>::create(realm.heap(), [callback, data]() {
|
||||||
(void)WebIDL::invoke_callback(*callback, {}, data);
|
(void)WebIDL::invoke_callback(*callback, {}, { { data } });
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -397,7 +397,7 @@ WebIDL::ExceptionOr<void> HTMLCanvasElement::to_blob(GC::Ref<WebIDL::CallbackTyp
|
||||||
blob_result = FileAPI::Blob::create(realm(), file_result->buffer, TRY_OR_THROW_OOM(vm(), String::from_utf8(file_result->mime_type)));
|
blob_result = FileAPI::Blob::create(realm(), file_result->buffer, TRY_OR_THROW_OOM(vm(), String::from_utf8(file_result->mime_type)));
|
||||||
|
|
||||||
// 2. Invoke callback with « result » and "report".
|
// 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 {};
|
return {};
|
||||||
});
|
});
|
||||||
if (maybe_error.is_throw_completion())
|
if (maybe_error.is_throw_completion())
|
||||||
|
|
|
@ -1141,7 +1141,7 @@ bool Navigation::inner_navigate_event_firing_algorithm(
|
||||||
// 2. For each handler of event's navigation handler list:
|
// 2. For each handler of event's navigation handler list:
|
||||||
for (auto const& handler : event->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.
|
// 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
|
// This *should* be equivalent to converting a promise to a promise capability
|
||||||
promises_list.append(WebIDL::create_resolved_promise(realm, result.value()));
|
promises_list.append(WebIDL::create_resolved_promise(realm, result.value()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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".
|
// 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] {
|
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, {});
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1611,7 +1611,7 @@ WebIDL::UnsignedLong Window::request_animation_frame(GC::Ref<WebIDL::CallbackTyp
|
||||||
// FIXME: Make this fully spec compliant. Currently implements a mix of 'requestAnimationFrame()' and 'run the animation frame callbacks'.
|
// FIXME: Make this fully spec compliant. Currently implements a mix of 'requestAnimationFrame()' and 'run the animation frame callbacks'.
|
||||||
return animation_frame_callback_driver().add(GC::create_function(heap(), [this, callback](double now) {
|
return animation_frame_callback_driver().add(GC::create_function(heap(), [this, callback](double now) {
|
||||||
// 3. Invoke callback, passing now as the only argument, and if an exception is thrown, report the exception.
|
// 3. Invoke callback, passing now as the only argument, and if an exception is thrown, report the exception.
|
||||||
auto result = WebIDL::invoke_callback(*callback, {}, JS::Value(now));
|
auto result = WebIDL::invoke_callback(*callback, {}, { { JS::Value(now) } });
|
||||||
if (result.is_error())
|
if (result.is_error())
|
||||||
report_exception(result, realm());
|
report_exception(result, realm());
|
||||||
}));
|
}));
|
||||||
|
@ -1655,7 +1655,7 @@ u32 Window::request_idle_callback(WebIDL::CallbackType& callback, RequestIdleCal
|
||||||
|
|
||||||
// 4. Push callback to the end of window's list of idle request callbacks, associated with handle.
|
// 4. Push callback to the end of window's list of idle request callbacks, associated with handle.
|
||||||
auto handler = [callback = GC::make_root(callback)](GC::Ref<RequestIdleCallback::IdleDeadline> deadline) -> JS::Completion {
|
auto handler = [callback = GC::make_root(callback)](GC::Ref<RequestIdleCallback::IdleDeadline> 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)));
|
m_idle_request_callbacks.append(adopt_ref(*new IdleCallback(move(handler), handle)));
|
||||||
|
|
||||||
|
|
|
@ -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
|
// 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.
|
// argument and as callback this value, and with callbackOptions as the third argument.
|
||||||
// If this throws an exception, report the exception.
|
// 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())
|
if (completion.is_abrupt())
|
||||||
HTML::report_exception(completion, realm);
|
HTML::report_exception(completion, realm);
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,7 +109,7 @@ void ResizeObserver::invoke_callback(ReadonlySpan<GC::Ref<ResizeObserverEntry>>
|
||||||
MUST(wrapped_records->create_data_property(property_index, record.ptr()));
|
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 } });
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1762,7 +1762,8 @@ GC::Ref<SizeAlgorithm> extract_size_algorithm(JS::VM& vm, QueuingStrategy const&
|
||||||
|
|
||||||
// 2. Return an algorithm that performs the following steps, taking a chunk argument:
|
// 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 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<void> set_up_readable_stream_default_controller_from_underly
|
||||||
// invoking underlyingSourceDict["start"] with argument list « controller » and callback this value underlyingSource.
|
// invoking underlyingSourceDict["start"] with argument list « controller » and callback this value underlyingSource.
|
||||||
if (underlying_source.start) {
|
if (underlying_source.start) {
|
||||||
start_algorithm = GC::create_function(realm.heap(), [controller, underlying_source_value, callback = underlying_source.start]() -> WebIDL::ExceptionOr<JS::Value> {
|
start_algorithm = GC::create_function(realm.heap(), [controller, underlying_source_value, callback = underlying_source.start]() -> WebIDL::ExceptionOr<JS::Value> {
|
||||||
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<void> set_up_readable_stream_default_controller_from_underly
|
||||||
// invoking underlyingSourceDict["pull"] with argument list « controller » and callback this value underlyingSource.
|
// invoking underlyingSourceDict["pull"] with argument list « controller » and callback this value underlyingSource.
|
||||||
if (underlying_source.pull) {
|
if (underlying_source.pull) {
|
||||||
pull_algorithm = GC::create_function(realm.heap(), [controller, underlying_source_value, callback = 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<void> set_up_readable_stream_default_controller_from_underly
|
||||||
// callback this value underlyingSource.
|
// callback this value underlyingSource.
|
||||||
if (underlying_source.cancel) {
|
if (underlying_source.cancel) {
|
||||||
cancel_algorithm = GC::create_function(realm.heap(), [underlying_source_value, callback = underlying_source.cancel](JS::Value reason) {
|
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<void> set_up_writable_stream_default_controller_from_underly
|
||||||
// callback this value underlyingSink.
|
// callback this value underlyingSink.
|
||||||
if (underlying_sink.start) {
|
if (underlying_sink.start) {
|
||||||
start_algorithm = GC::create_function(realm.heap(), [controller, underlying_sink_value, callback = underlying_sink.start]() -> WebIDL::ExceptionOr<JS::Value> {
|
start_algorithm = GC::create_function(realm.heap(), [controller, underlying_sink_value, callback = underlying_sink.start]() -> WebIDL::ExceptionOr<JS::Value> {
|
||||||
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<void> set_up_writable_stream_default_controller_from_underly
|
||||||
// callback this value underlyingSink.
|
// callback this value underlyingSink.
|
||||||
if (underlying_sink.write) {
|
if (underlying_sink.write) {
|
||||||
write_algorithm = GC::create_function(realm.heap(), [controller, underlying_sink_value, callback = underlying_sink.write](JS::Value chunk) {
|
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<void> set_up_writable_stream_default_controller_from_underly
|
||||||
// invoking underlyingSinkDict["close"] with argument list «» and callback this value underlyingSink.
|
// invoking underlyingSinkDict["close"] with argument list «» and callback this value underlyingSink.
|
||||||
if (underlying_sink.close) {
|
if (underlying_sink.close) {
|
||||||
close_algorithm = GC::create_function(realm.heap(), [underlying_sink_value, callback = 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<void> set_up_writable_stream_default_controller_from_underly
|
||||||
// value underlyingSink.
|
// value underlyingSink.
|
||||||
if (underlying_sink.abort) {
|
if (underlying_sink.abort) {
|
||||||
abort_algorithm = GC::create_function(realm.heap(), [underlying_sink_value, callback = underlying_sink.abort](JS::Value reason) {
|
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.
|
// callback this value transformer.
|
||||||
if (transformer_dict.transform) {
|
if (transformer_dict.transform) {
|
||||||
transform_algorithm = GC::create_function(realm.heap(), [controller, transformer, callback = transformer_dict.transform](JS::Value chunk) {
|
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.
|
// transformerDict["flush"] with argument list « controller » and callback this value transformer.
|
||||||
if (transformer_dict.flush) {
|
if (transformer_dict.flush) {
|
||||||
flush_algorithm = GC::create_function(realm.heap(), [transformer, callback = transformer_dict.flush, controller]() {
|
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.
|
// the result of invoking transformerDict["cancel"] with argument list « reason » and callback this value transformer.
|
||||||
if (transformer_dict.cancel) {
|
if (transformer_dict.cancel) {
|
||||||
cancel_algorithm = GC::create_function(realm.heap(), [transformer, callback = transformer_dict.cancel](JS::Value reason) {
|
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<void> set_up_readable_byte_stream_controller_from_underlying
|
||||||
// invoking underlyingSourceDict["start"] with argument list « controller » and callback this value underlyingSource.
|
// invoking underlyingSourceDict["start"] with argument list « controller » and callback this value underlyingSource.
|
||||||
if (underlying_source_dict.start) {
|
if (underlying_source_dict.start) {
|
||||||
start_algorithm = GC::create_function(realm.heap(), [controller, underlying_source, callback = underlying_source_dict.start]() -> WebIDL::ExceptionOr<JS::Value> {
|
start_algorithm = GC::create_function(realm.heap(), [controller, underlying_source, callback = underlying_source_dict.start]() -> WebIDL::ExceptionOr<JS::Value> {
|
||||||
return TRY(WebIDL::invoke_callback(*callback, underlying_source, controller));
|
return TRY(WebIDL::invoke_callback(*callback, underlying_source, { { controller } }));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5824,7 +5825,7 @@ WebIDL::ExceptionOr<void> set_up_readable_byte_stream_controller_from_underlying
|
||||||
// invoking underlyingSourceDict["pull"] with argument list « controller » and callback this value underlyingSource.
|
// invoking underlyingSourceDict["pull"] with argument list « controller » and callback this value underlyingSource.
|
||||||
if (underlying_source_dict.pull) {
|
if (underlying_source_dict.pull) {
|
||||||
pull_algorithm = GC::create_function(realm.heap(), [controller, underlying_source, callback = 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<void> set_up_readable_byte_stream_controller_from_underlying
|
||||||
// callback this value underlyingSource.
|
// callback this value underlyingSource.
|
||||||
if (underlying_source_dict.cancel) {
|
if (underlying_source_dict.cancel) {
|
||||||
cancel_algorithm = GC::create_function(realm.heap(), [underlying_source, callback = underlying_source_dict.cancel](JS::Value reason) {
|
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 } });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,7 @@ WebIDL::ExceptionOr<GC::Ref<TransformStream>> TransformStream::construct_impl(JS
|
||||||
// 12. If transformerDict["start"] exists, then resolve startPromise with the result of invoking
|
// 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.
|
// transformerDict["start"] with argument list « this.[[controller]] » and callback this value transformer.
|
||||||
if (transformer_dict.start) {
|
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);
|
WebIDL::resolve_promise(realm, start_promise, result);
|
||||||
}
|
}
|
||||||
// 13. Otherwise, resolve startPromise with undefined.
|
// 13. Otherwise, resolve startPromise with undefined.
|
||||||
|
|
|
@ -243,7 +243,7 @@ GC::Ref<WebIDL::Promise> BaseAudioContext::decode_audio_data(GC::Root<WebIDL::Bu
|
||||||
// 4.3. Queue a media element task to invoke errorCallback with error.
|
// 4.3. Queue a media element task to invoke errorCallback with error.
|
||||||
if (error_callback) {
|
if (error_callback) {
|
||||||
queue_a_media_element_task(GC::create_function(heap(), [&realm, error_callback, error] {
|
queue_a_media_element_task(GC::create_function(heap(), [&realm, error_callback, error] {
|
||||||
auto completion = WebIDL::invoke_callback(*error_callback, {}, error);
|
auto completion = WebIDL::invoke_callback(*error_callback, {}, { { error } });
|
||||||
if (completion.is_abrupt())
|
if (completion.is_abrupt())
|
||||||
HTML::report_exception(completion, realm);
|
HTML::report_exception(completion, realm);
|
||||||
}));
|
}));
|
||||||
|
@ -293,7 +293,7 @@ void BaseAudioContext::queue_a_decoding_operation(GC::Ref<JS::PromiseCapability>
|
||||||
|
|
||||||
// 4.2. If errorCallback is not missing, invoke errorCallback with error.
|
// 4.2. If errorCallback is not missing, invoke errorCallback with error.
|
||||||
if (error_callback) {
|
if (error_callback) {
|
||||||
auto completion = WebIDL::invoke_callback(*error_callback, {}, error);
|
auto completion = WebIDL::invoke_callback(*error_callback, {}, { { error } });
|
||||||
if (completion.is_abrupt())
|
if (completion.is_abrupt())
|
||||||
HTML::report_exception(completion, realm);
|
HTML::report_exception(completion, realm);
|
||||||
}
|
}
|
||||||
|
@ -317,7 +317,7 @@ void BaseAudioContext::queue_a_decoding_operation(GC::Ref<JS::PromiseCapability>
|
||||||
|
|
||||||
// 5.2.3. If successCallback is not missing, invoke successCallback with buffer.
|
// 5.2.3. If successCallback is not missing, invoke successCallback with buffer.
|
||||||
if (success_callback) {
|
if (success_callback) {
|
||||||
auto completion = WebIDL::invoke_callback(*success_callback, {}, buffer);
|
auto completion = WebIDL::invoke_callback(*success_callback, {}, { { buffer } });
|
||||||
if (completion.is_abrupt())
|
if (completion.is_abrupt())
|
||||||
HTML::report_exception(completion, realm);
|
HTML::report_exception(completion, realm);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,17 +8,17 @@
|
||||||
|
|
||||||
#include <AK/ByteBuffer.h>
|
#include <AK/ByteBuffer.h>
|
||||||
#include <AK/Enumerate.h>
|
#include <AK/Enumerate.h>
|
||||||
#include <AK/Math.h>
|
|
||||||
#include <AK/NumericLimits.h>
|
#include <AK/NumericLimits.h>
|
||||||
#include <LibJS/Runtime/AbstractOperations.h>
|
#include <LibJS/Runtime/AbstractOperations.h>
|
||||||
#include <LibJS/Runtime/ArrayBuffer.h>
|
#include <LibJS/Runtime/ArrayBuffer.h>
|
||||||
#include <LibJS/Runtime/DataView.h>
|
#include <LibJS/Runtime/DataView.h>
|
||||||
#include <LibJS/Runtime/PropertyKey.h>
|
#include <LibJS/Runtime/FunctionObject.h>
|
||||||
#include <LibJS/Runtime/TypedArray.h>
|
#include <LibJS/Runtime/TypedArray.h>
|
||||||
#include <LibJS/Runtime/ValueInlines.h>
|
#include <LibJS/Runtime/ValueInlines.h>
|
||||||
#include <LibWeb/Bindings/PlatformObject.h>
|
#include <LibWeb/HTML/Scripting/Environments.h>
|
||||||
#include <LibWeb/HTML/Window.h>
|
#include <LibWeb/HTML/WindowOrWorkerGlobalScope.h>
|
||||||
#include <LibWeb/WebIDL/AbstractOperations.h>
|
#include <LibWeb/WebIDL/AbstractOperations.h>
|
||||||
|
#include <LibWeb/WebIDL/CallbackType.h>
|
||||||
#include <LibWeb/WebIDL/Promise.h>
|
#include <LibWeb/WebIDL/Promise.h>
|
||||||
#include <LibWeb/WebIDL/Types.h>
|
#include <LibWeb/WebIDL/Types.h>
|
||||||
|
|
||||||
|
@ -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://webidl.spec.whatwg.org/#call-a-user-objects-operation
|
||||||
// https://whatpr.org/webidl/1437.html#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<JS::Value> this_argument, GC::RootVector<JS::Value> args)
|
JS::Completion call_user_object_operation(CallbackType& callback, String const& operation_name, Optional<JS::Value> this_argument, ReadonlySpan<JS::Value> args)
|
||||||
{
|
{
|
||||||
// 1. Let completion be an uninitialized variable.
|
// 1. Let completion be an uninitialized variable.
|
||||||
JS::Completion completion;
|
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.
|
// 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).
|
// 11. Let callResult be Call(X, thisArg, esArgs).
|
||||||
VERIFY(actual_function_object);
|
auto call_result = JS::call(object->vm(), as<JS::FunctionObject>(*actual_function_object), this_argument.value(), args);
|
||||||
auto& vm = object->vm();
|
|
||||||
auto call_result = JS::call(vm, as<JS::FunctionObject>(*actual_function_object), this_argument.value(), args.span());
|
|
||||||
|
|
||||||
// 12. If callResult is an abrupt completion, set completion to callResult and jump to the step labeled return.
|
// 12. If callResult is an abrupt completion, set completion to callResult and jump to the step labeled return.
|
||||||
if (call_result.is_throw_completion()) {
|
if (call_result.is_throw_completion()) {
|
||||||
|
@ -244,7 +242,7 @@ JS::ThrowCompletionOr<String> to_usv_string(JS::VM& vm, JS::Value value)
|
||||||
// https://webidl.spec.whatwg.org/#invoke-a-callback-function
|
// https://webidl.spec.whatwg.org/#invoke-a-callback-function
|
||||||
// https://whatpr.org/webidl/1437.html#invoke-a-callback-function
|
// https://whatpr.org/webidl/1437.html#invoke-a-callback-function
|
||||||
template<typename ReturnSteps>
|
template<typename ReturnSteps>
|
||||||
static auto invoke_callback_impl(WebIDL::CallbackType& callback, Optional<JS::Value> this_argument, GC::RootVector<JS::Value> args, ReturnSteps&& return_steps)
|
static auto invoke_callback_impl(CallbackType& callback, Optional<JS::Value> this_argument, ReadonlySpan<JS::Value> args, ReturnSteps&& return_steps)
|
||||||
{
|
{
|
||||||
// 1. Let completion be an uninitialized variable.
|
// 1. Let completion be an uninitialized variable.
|
||||||
|
|
||||||
|
@ -279,8 +277,7 @@ static auto invoke_callback_impl(WebIDL::CallbackType& callback, Optional<JS::Va
|
||||||
// If this throws an exception, set completion to the completion value representing the thrown exception and jump to the step labeled return.
|
// If this throws an exception, set completion to the completion value representing the thrown exception and jump to the step labeled return.
|
||||||
|
|
||||||
// 10. Let callResult be Call(F, thisArg, jsArgs).
|
// 10. Let callResult be Call(F, thisArg, jsArgs).
|
||||||
auto& vm = function_object->vm();
|
auto call_result = JS::call(function_object->vm(), as<JS::FunctionObject>(*function_object), this_argument.value(), args);
|
||||||
auto call_result = JS::call(vm, as<JS::FunctionObject>(*function_object), this_argument.value(), args.span());
|
|
||||||
|
|
||||||
// 11. If callResult is an abrupt completion, set completion to callResult and jump to the step labeled return.
|
// 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
|
// 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<JS::Va
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JS::Completion invoke_callback(WebIDL::CallbackType& callback, Optional<JS::Value> this_argument, ExceptionBehavior exception_behavior, GC::RootVector<JS::Value> args)
|
JS::Completion invoke_callback(CallbackType& callback, Optional<JS::Value> this_argument, ExceptionBehavior exception_behavior, ReadonlySpan<JS::Value> args)
|
||||||
{
|
{
|
||||||
// https://webidl.spec.whatwg.org/#js-invoking-callback-functions
|
// 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".
|
// 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::Valu
|
||||||
|
|
||||||
VERIFY(exception_behavior == ExceptionBehavior::NotSpecified || callback.operation_returns_promise == OperationReturnsPromise::No);
|
VERIFY(exception_behavior == ExceptionBehavior::NotSpecified || callback.operation_returns_promise == OperationReturnsPromise::No);
|
||||||
|
|
||||||
return invoke_callback_impl(callback, move(this_argument), move(args), [&](JS::Realm& relevant_realm, JS::Completion completion) -> 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.
|
// 3. If completion is an IDL value, return completion.
|
||||||
if (!completion.is_abrupt())
|
if (!completion.is_abrupt())
|
||||||
return completion;
|
return completion;
|
||||||
|
@ -344,21 +341,21 @@ JS::Completion invoke_callback(WebIDL::CallbackType& callback, Optional<JS::Valu
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
JS::Completion invoke_callback(WebIDL::CallbackType& callback, Optional<JS::Value> this_argument, GC::RootVector<JS::Value> args)
|
JS::Completion invoke_callback(CallbackType& callback, Optional<JS::Value> this_argument, ReadonlySpan<JS::Value> 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,
|
// 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.
|
// and the caller needs a WebIDL::Promise rather than a JS::Promise.
|
||||||
GC::Ref<WebIDL::Promise> invoke_promise_callback(WebIDL::CallbackType& callback, Optional<JS::Value> this_argument, GC::RootVector<JS::Value> args)
|
GC::Ref<Promise> invoke_promise_callback(CallbackType& callback, Optional<JS::Value> this_argument, ReadonlySpan<JS::Value> args)
|
||||||
{
|
{
|
||||||
VERIFY(callback.operation_returns_promise == OperationReturnsPromise::Yes);
|
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<WebIDL::Promise> {
|
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.
|
// 3. If completion is an IDL value, return completion.
|
||||||
if (!completion.is_abrupt())
|
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.
|
// 4. Assert: completion is an abrupt completion.
|
||||||
VERIFY(completion.is_abrupt());
|
VERIFY(completion.is_abrupt());
|
||||||
|
@ -371,7 +368,7 @@ GC::Ref<WebIDL::Promise> invoke_promise_callback(WebIDL::CallbackType& callback,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
JS::Completion construct(WebIDL::CallbackType& callback, GC::RootVector<JS::Value> args)
|
JS::Completion construct(CallbackType& callback, ReadonlySpan<JS::Value> args)
|
||||||
{
|
{
|
||||||
// 1. Let completion be an uninitialized variable.
|
// 1. Let completion be an uninitialized variable.
|
||||||
JS::Completion completion;
|
JS::Completion completion;
|
||||||
|
@ -399,8 +396,7 @@ JS::Completion construct(WebIDL::CallbackType& callback, GC::RootVector<JS::Valu
|
||||||
// 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.
|
// 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.
|
||||||
|
|
||||||
// 8. Let callResult be Completion(Construct(F, esArgs)).
|
// 8. Let callResult be Completion(Construct(F, esArgs)).
|
||||||
auto& vm = function_object->vm();
|
auto call_result = JS::construct(function_object->vm(), as<JS::FunctionObject>(*function_object), args);
|
||||||
auto call_result = JS::construct(vm, as<JS::FunctionObject>(*function_object), args.span());
|
|
||||||
|
|
||||||
// 9. If callResult is an abrupt completion, set completion to callResult and jump to the step labeled return.
|
// 9. If callResult is an abrupt completion, set completion to callResult and jump to the step labeled return.
|
||||||
if (call_result.is_throw_completion()) {
|
if (call_result.is_throw_completion()) {
|
||||||
|
|
|
@ -9,11 +9,9 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <AK/Forward.h>
|
#include <AK/Forward.h>
|
||||||
|
#include <LibGC/Ptr.h>
|
||||||
#include <LibJS/Forward.h>
|
#include <LibJS/Forward.h>
|
||||||
#include <LibJS/Runtime/AbstractOperations.h>
|
#include <LibWeb/Forward.h>
|
||||||
#include <LibJS/Runtime/FunctionObject.h>
|
|
||||||
#include <LibWeb/HTML/Scripting/Environments.h>
|
|
||||||
#include <LibWeb/WebIDL/CallbackType.h>
|
|
||||||
|
|
||||||
namespace Web::WebIDL {
|
namespace Web::WebIDL {
|
||||||
|
|
||||||
|
@ -21,77 +19,23 @@ bool is_buffer_source_type(JS::Value);
|
||||||
GC::Ptr<JS::ArrayBuffer> underlying_buffer_source(JS::Object& buffer_source);
|
GC::Ptr<JS::ArrayBuffer> underlying_buffer_source(JS::Object& buffer_source);
|
||||||
ErrorOr<ByteBuffer> get_buffer_source_copy(JS::Object const& buffer_source);
|
ErrorOr<ByteBuffer> get_buffer_source_copy(JS::Object const& buffer_source);
|
||||||
|
|
||||||
JS::Completion call_user_object_operation(WebIDL::CallbackType& callback, String const& operation_name, Optional<JS::Value> this_argument, GC::RootVector<JS::Value> args);
|
JS::Completion call_user_object_operation(CallbackType& callback, String const& operation_name, Optional<JS::Value> this_argument, ReadonlySpan<JS::Value> args);
|
||||||
|
|
||||||
JS::ThrowCompletionOr<String> to_string(JS::VM&, JS::Value);
|
JS::ThrowCompletionOr<String> to_string(JS::VM&, JS::Value);
|
||||||
JS::ThrowCompletionOr<String> to_usv_string(JS::VM&, JS::Value);
|
JS::ThrowCompletionOr<String> to_usv_string(JS::VM&, JS::Value);
|
||||||
JS::ThrowCompletionOr<String> to_byte_string(JS::VM&, JS::Value);
|
JS::ThrowCompletionOr<String> to_byte_string(JS::VM&, JS::Value);
|
||||||
|
|
||||||
// https://webidl.spec.whatwg.org/#call-a-user-objects-operation
|
|
||||||
template<typename... Args>
|
|
||||||
JS::Completion call_user_object_operation(WebIDL::CallbackType& callback, String const& operation_name, Optional<JS::Value> this_argument, Args&&... args)
|
|
||||||
{
|
|
||||||
auto& function_object = callback.callback;
|
|
||||||
|
|
||||||
GC::RootVector<JS::Value> arguments_list { function_object->heap() };
|
|
||||||
(arguments_list.append(forward<Args>(args)), ...);
|
|
||||||
|
|
||||||
return call_user_object_operation(callback, operation_name, move(this_argument), move(arguments_list));
|
|
||||||
}
|
|
||||||
|
|
||||||
enum class ExceptionBehavior {
|
enum class ExceptionBehavior {
|
||||||
NotSpecified,
|
NotSpecified,
|
||||||
Report,
|
Report,
|
||||||
Rethrow,
|
Rethrow,
|
||||||
};
|
};
|
||||||
|
JS::Completion invoke_callback(CallbackType& callback, Optional<JS::Value> this_argument, ExceptionBehavior exception_behavior, ReadonlySpan<JS::Value> args);
|
||||||
|
JS::Completion invoke_callback(CallbackType& callback, Optional<JS::Value> this_argument, ReadonlySpan<JS::Value> args);
|
||||||
|
|
||||||
JS::Completion invoke_callback(WebIDL::CallbackType& callback, Optional<JS::Value> this_argument, ExceptionBehavior exception_behavior, GC::RootVector<JS::Value> args);
|
GC::Ref<Promise> invoke_promise_callback(CallbackType& callback, Optional<JS::Value> this_argument, ReadonlySpan<JS::Value> args);
|
||||||
JS::Completion invoke_callback(WebIDL::CallbackType& callback, Optional<JS::Value> this_argument, GC::RootVector<JS::Value> args);
|
|
||||||
|
|
||||||
// https://webidl.spec.whatwg.org/#invoke-a-callback-function
|
JS::Completion construct(CallbackType& callback, ReadonlySpan<JS::Value> args);
|
||||||
template<typename... Args>
|
|
||||||
JS::Completion invoke_callback(WebIDL::CallbackType& callback, Optional<JS::Value> this_argument, ExceptionBehavior exception_behavior, Args&&... args)
|
|
||||||
{
|
|
||||||
auto& function_object = callback.callback;
|
|
||||||
|
|
||||||
GC::RootVector<JS::Value> arguments_list { function_object->heap() };
|
|
||||||
(arguments_list.append(forward<Args>(args)), ...);
|
|
||||||
|
|
||||||
return invoke_callback(callback, move(this_argument), exception_behavior, move(arguments_list));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename... Args>
|
|
||||||
JS::Completion invoke_callback(WebIDL::CallbackType& callback, Optional<JS::Value> this_argument, Args&&... args)
|
|
||||||
{
|
|
||||||
return invoke_callback(callback, move(this_argument), ExceptionBehavior::NotSpecified, forward<Args>(args)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
GC::Ref<WebIDL::Promise> invoke_promise_callback(WebIDL::CallbackType& callback, Optional<JS::Value> this_argument, GC::RootVector<JS::Value> args);
|
|
||||||
|
|
||||||
template<typename... Args>
|
|
||||||
GC::Ref<WebIDL::Promise> invoke_promise_callback(WebIDL::CallbackType& callback, Optional<JS::Value> this_argument, Args&&... args)
|
|
||||||
{
|
|
||||||
auto& function_object = callback.callback;
|
|
||||||
|
|
||||||
GC::RootVector<JS::Value> arguments_list { function_object->heap() };
|
|
||||||
(arguments_list.append(forward<Args>(args)), ...);
|
|
||||||
|
|
||||||
return invoke_promise_callback(callback, move(this_argument), move(arguments_list));
|
|
||||||
}
|
|
||||||
|
|
||||||
JS::Completion construct(WebIDL::CallbackType& callback, GC::RootVector<JS::Value> args);
|
|
||||||
|
|
||||||
// https://webidl.spec.whatwg.org/#construct-a-callback-function
|
|
||||||
template<typename... Args>
|
|
||||||
JS::Completion construct(WebIDL::CallbackType& callback, Args&&... args)
|
|
||||||
{
|
|
||||||
auto& function_object = callback.callback;
|
|
||||||
|
|
||||||
GC::RootVector<JS::Value> arguments_list { function_object->heap() };
|
|
||||||
(arguments_list.append(forward<Args>(args)), ...);
|
|
||||||
|
|
||||||
return construct(callback, move(arguments_list));
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://webidl.spec.whatwg.org/#abstract-opdef-integerpart
|
// https://webidl.spec.whatwg.org/#abstract-opdef-integerpart
|
||||||
double integer_part(double n);
|
double integer_part(double n);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue