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:
Timothy Flynn 2025-04-15 20:56:03 -04:00 committed by Tim Flynn
commit 6dd2a4c945
Notes: github-actions[bot] 2025-04-16 11:32:56 +00:00
20 changed files with 60 additions and 119 deletions

View file

@ -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() } });
}
}));
}

View file

@ -2517,7 +2517,7 @@ JS::ThrowCompletionOr<void> Element::upgrade_element(GC::Ref<HTML::CustomElement
set_custom_element_state(CustomElementState::Precustomized);
// 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.
if (!JS::same_value(construct_result, this))

View file

@ -578,7 +578,7 @@ WebIDL::ExceptionOr<GC::Ref<Element>> 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<HTML::HTMLElement>(result.as_object()))

View file

@ -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.
auto* this_value = event.current_target().ptr();
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 (result.is_error()) {

View file

@ -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.
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<void> 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.)

View file

@ -169,7 +169,7 @@ JS::ThrowCompletionOr<NodeFilter::Result> NodeIterator::filter(Node& node)
// 6. Let result be the return value of call a user objects operation with traversers filter, "acceptNode", and « node ».
// If this throws an exception, then unset traversers 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;

View file

@ -274,7 +274,7 @@ JS::ThrowCompletionOr<NodeFilter::Result> TreeWalker::filter(Node& node)
// 6. Let result be the return value of call a user objects operation with traversers filter, "acceptNode", and « node ».
// If this throws an exception, then unset traversers 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;