LibGC: Default-construct RootVector from the global heap

Similar to GC::Root<T>, make GC::RootVector<T> constructible without
explicitly passing a Heap.

This is implemented by having RootVectorBase use GC::Heap::the() for
heap-free construction.
This commit is contained in:
Shannon Booth 2026-05-19 20:40:15 +02:00 committed by Shannon Booth
parent 3897f6efb9
commit 387cd6e2e2
92 changed files with 198 additions and 227 deletions

View file

@ -10,6 +10,11 @@
namespace GC {
RootVectorBase::RootVectorBase()
: RootVectorBase(Heap::the())
{
}
RootVectorBase::RootVectorBase(Heap& heap)
: m_heap(&heap)
{

View file

@ -21,6 +21,7 @@ public:
virtual void gather_roots(HashMap<Cell*, GC::HeapRoot>&) const = 0;
protected:
RootVectorBase();
explicit RootVectorBase(Heap&);
~RootVectorBase();
@ -41,15 +42,15 @@ class RootVector final
using VectorBase = Vector<T, inline_capacity>;
public:
explicit RootVector(Heap& heap)
: RootVectorBase(heap)
RootVector()
: RootVectorBase()
{
}
~RootVector() = default;
RootVector(Heap& heap, ReadonlySpan<T> other)
: RootVectorBase(heap)
RootVector(ReadonlySpan<T> other)
: RootVectorBase()
, Vector<T, inline_capacity>(other)
{
}
@ -99,12 +100,12 @@ public:
};
template<typename T>
RootVector(Heap&, ReadonlySpan<T> const&) -> RootVector<T>;
RootVector(ReadonlySpan<T> const&) -> RootVector<T>;
template<typename T>
RootVector(Heap&, Span<T> const&) -> RootVector<T>;
RootVector(Span<T> const&) -> RootVector<T>;
template<typename T>
RootVector(Heap&, Vector<T> const&) -> RootVector<T>;
RootVector(Vector<T> const&) -> RootVector<T>;
}

View file

@ -3480,7 +3480,7 @@ NEVER_INLINE ThrowCompletionOr<void> NewClass::execute_impl(VM& vm) const
Value super_class;
if (m_super_class.has_value())
super_class = vm.get(m_super_class.value());
GC::RootVector<Value> element_keys(vm.heap());
GC::RootVector<Value> element_keys;
element_keys.ensure_capacity(m_element_keys_count);
for (size_t i = 0; i < m_element_keys_count; ++i) {
Value element_key;

View file

@ -54,7 +54,7 @@ ThrowCompletionOr<Value> Console::assert_()
auto message = PrimitiveString::create(vm, "Assertion failed"_string);
// NOTE: Assemble `data` from the function arguments.
GC::RootVector<Value> data { vm.heap() };
GC::RootVector<Value> data;
if (vm.argument_count() > 1) {
data.ensure_capacity(vm.argument_count() - 1);
for (size_t i = 1; i < vm.argument_count(); ++i) {
@ -266,10 +266,10 @@ ThrowCompletionOr<Value> Console::table()
}
// 1. Let `finalRows` be the new list, initially empty
GC::RootVector<Value> final_rows(vm.heap());
GC::RootVector<Value> final_rows;
// 2. Let `finalColumns` be the new list, initially empty
GC::RootVector<Value> final_columns(vm.heap());
GC::RootVector<Value> final_columns;
HashMap<PropertyKey, bool> visited_columns;
@ -327,7 +327,7 @@ ThrowCompletionOr<Value> Console::table()
TRY(final_data->set(vm.names.columns, table_cols, Object::ShouldThrowExceptions::No));
// 5.4. Perform `Printer("table", finalData)`
GC::RootVector<Value> args(vm.heap());
GC::RootVector<Value> args;
args.append(Value(final_data));
return m_client->printer(LogLevel::Table, args);
}
@ -404,7 +404,7 @@ ThrowCompletionOr<Value> Console::dir()
// 2. Perform Printer("dir", « object », options).
if (m_client) {
GC::RootVector<Value> printer_arguments { vm.heap() };
GC::RootVector<Value> printer_arguments;
TRY_OR_THROW_OOM(vm, printer_arguments.try_append(object));
return m_client->printer(LogLevel::Dir, move(printer_arguments));
@ -419,7 +419,7 @@ ThrowCompletionOr<Value> Console::dirxml()
auto& vm = realm().vm();
// 1. Let finalList be a new list, initially empty.
GC::RootVector<Value> final_list(vm.heap());
GC::RootVector<Value> final_list;
// 2. For each item of data:
for (size_t i = 0; i < vm.argument_count(); ++i) {
@ -472,7 +472,7 @@ ThrowCompletionOr<Value> Console::count()
auto concat = TRY_OR_THROW_OOM(vm, String::formatted("{}: {}", label, map.get(label).value()));
// 5. Perform Logger("count", « concat »).
GC::RootVector<Value> concat_as_vector { vm.heap() };
GC::RootVector<Value> concat_as_vector;
concat_as_vector.append(PrimitiveString::create(vm, move(concat)));
if (m_client)
TRY(m_client->logger(LogLevel::Count, concat_as_vector));
@ -500,7 +500,7 @@ ThrowCompletionOr<Value> Console::count_reset()
// that the given label does not have an associated count.
auto message = TRY_OR_THROW_OOM(vm, String::formatted("\"{}\" doesn't have a count", label));
// 2. Perform Logger("countReset", « message »);
GC::RootVector<Value> message_as_vector { vm.heap() };
GC::RootVector<Value> message_as_vector;
message_as_vector.append(PrimitiveString::create(vm, move(message)));
if (m_client)
TRY(m_client->logger(LogLevel::CountReset, message_as_vector));
@ -611,7 +611,7 @@ ThrowCompletionOr<Value> Console::time()
// a warning to the console indicating that a timer with label `label` has already been started.
if (m_timer_table.contains(label)) {
if (m_client) {
GC::RootVector<Value> timer_already_exists_warning_message_as_vector { vm.heap() };
GC::RootVector<Value> timer_already_exists_warning_message_as_vector;
auto message = TRY_OR_THROW_OOM(vm, String::formatted("Timer '{}' already exists.", label));
timer_already_exists_warning_message_as_vector.append(PrimitiveString::create(vm, move(message)));
@ -642,7 +642,7 @@ ThrowCompletionOr<Value> Console::time_log()
// NOTE: Warn if the timer doesn't exist. Not part of the spec yet, but discussed here: https://github.com/whatwg/console/issues/134
if (maybe_start_time == m_timer_table.end()) {
if (m_client) {
GC::RootVector<Value> timer_does_not_exist_warning_message_as_vector { vm.heap() };
GC::RootVector<Value> timer_does_not_exist_warning_message_as_vector;
auto message = TRY_OR_THROW_OOM(vm, String::formatted("Timer '{}' does not exist.", label));
timer_does_not_exist_warning_message_as_vector.append(PrimitiveString::create(vm, move(message)));
@ -660,7 +660,7 @@ ThrowCompletionOr<Value> Console::time_log()
auto concat = TRY_OR_THROW_OOM(vm, String::formatted("{}: {}", label, duration));
// 5. Prepend concat to data.
GC::RootVector<Value> data { vm.heap() };
GC::RootVector<Value> data;
data.ensure_capacity(vm.argument_count());
data.append(PrimitiveString::create(vm, move(concat)));
for (size_t i = 1; i < vm.argument_count(); ++i)
@ -688,7 +688,7 @@ ThrowCompletionOr<Value> Console::time_end()
// NOTE: Warn if the timer doesn't exist. Not part of the spec yet, but discussed here: https://github.com/whatwg/console/issues/134
if (maybe_start_time == m_timer_table.end()) {
if (m_client) {
GC::RootVector<Value> timer_does_not_exist_warning_message_as_vector { vm.heap() };
GC::RootVector<Value> timer_does_not_exist_warning_message_as_vector;
auto message = TRY_OR_THROW_OOM(vm, String::formatted("Timer '{}' does not exist.", label));
timer_does_not_exist_warning_message_as_vector.append(PrimitiveString::create(vm, move(message)));
@ -710,7 +710,7 @@ ThrowCompletionOr<Value> Console::time_end()
// 6. Perform Printer("timeEnd", « concat »).
if (m_client) {
GC::RootVector<Value> concat_as_vector { vm.heap() };
GC::RootVector<Value> concat_as_vector;
concat_as_vector.append(PrimitiveString::create(vm, move(concat)));
TRY(m_client->printer(LogLevel::TimeEnd, move(concat_as_vector)));
}
@ -721,7 +721,7 @@ GC::RootVector<Value> Console::vm_arguments()
{
auto& vm = realm().vm();
GC::RootVector<Value> arguments { vm.heap() };
GC::RootVector<Value> arguments;
arguments.ensure_capacity(vm.argument_count());
for (size_t i = 0; i < vm.argument_count(); ++i) {
arguments.append(vm.argument(i));
@ -790,8 +790,6 @@ void ConsoleClient::visit_edges(Visitor& visitor)
// 2.1. Logger(logLevel, args), https://console.spec.whatwg.org/#logger
ThrowCompletionOr<Value> ConsoleClient::logger(Console::LogLevel log_level, GC::RootVector<Value> const& args)
{
auto& vm = m_console->realm().vm();
// 1. If args is empty, return.
if (args.is_empty())
return js_undefined();
@ -804,11 +802,10 @@ ThrowCompletionOr<Value> ConsoleClient::logger(Console::LogLevel log_level, GC::
// 4. If rest is empty, perform Printer(logLevel, « first ») and return.
if (rest_size == 0) {
GC::RootVector<Value> first_as_vector { vm.heap() };
GC::RootVector<Value> first_as_vector;
first_as_vector.append(first);
return printer(log_level, move(first_as_vector));
}
// 5. Otherwise, perform Printer(logLevel, Formatter(args)).
else {
auto formatted = TRY(formatter(args));
@ -922,7 +919,7 @@ ThrowCompletionOr<GC::RootVector<Value>> ConsoleClient::formatter(GC::RootVector
}
// 7. Let result be a list containing target together with the elements of args starting from the third onward.
GC::RootVector<Value> result { vm.heap() };
GC::RootVector<Value> result;
result.ensure_capacity(args.size() - 1);
result.empend(PrimitiveString::create(vm, move(target)));
for (size_t i = 2; i < args.size(); ++i)

View file

@ -222,7 +222,7 @@ ThrowCompletionOr<void> CyclicModule::link(VM& vm)
// 1. Assert: module.[[Status]] is one of unlinked, linked, evaluating-async, or evaluated.
VERIFY(m_status == ModuleStatus::Unlinked || m_status == ModuleStatus::Linked || m_status == ModuleStatus::EvaluatingAsync || m_status == ModuleStatus::Evaluated);
// 2. Let stack be a new empty List.
GC::RootVector<GC::Ref<Module>> stack(vm.heap());
GC::RootVector<GC::Ref<Module>> stack;
// 3. Let result be Completion(InnerModuleLinking(module, stack, 0)).
auto result = inner_module_linking(vm, stack, 0);
@ -398,7 +398,7 @@ ThrowCompletionOr<GC::Ref<PromiseCapability>> CyclicModule::evaluate(VM& vm)
}
// 5. Let stack be a new empty List.
GC::RootVector<GC::Ref<Module>> stack(vm.heap());
GC::RootVector<GC::Ref<Module>> stack;
auto& realm = *vm.current_realm();
@ -757,7 +757,7 @@ void CyclicModule::async_module_execution_fulfilled(VM& vm)
}
// 8. Let execList be a new empty List.
GC::RootVector<GC::Ptr<CyclicModule>> exec_list(vm.heap());
GC::RootVector<GC::Ptr<CyclicModule>> exec_list;
// 9. Perform GatherAvailableAncestors(module, execList).
gather_available_ancestors(exec_list);

View file

@ -174,7 +174,7 @@ ThrowCompletionOr<GC::RootVector<Value>> create_list_from_array_like(VM& vm, Val
auto length = TRY(length_of_array_like(vm, array_like));
// 4. Let list be a new empty List.
auto list = GC::RootVector<Value> { vm.heap() };
GC::RootVector<Value> list;
list.ensure_capacity(length);
// 5. Let index be 0.

View file

@ -199,7 +199,7 @@ ALWAYS_INLINE ThrowCompletionOr<GC::Ref<T>> ordinary_create_from_constructor(VM&
// 7.3.35 AddValueToKeyedGroup ( groups, key, value ), https://tc39.es/ecma262/#sec-add-value-to-keyed-group
template<typename GroupsType, typename KeyType>
void add_value_to_keyed_group(VM& vm, GroupsType& groups, KeyType key, Value value)
void add_value_to_keyed_group(GroupsType& groups, KeyType key, Value value)
{
// 1. For each Record { [[Key]], [[Elements]] } g of groups, do
// a. If SameValue(g.[[Key]], key) is true, then
@ -217,7 +217,7 @@ void add_value_to_keyed_group(VM& vm, GroupsType& groups, KeyType key, Value val
}
// 2. Let group be the Record { [[Key]]: key, [[Elements]]: « value » }.
GC::RootVector<Value> new_elements { vm.heap() };
GC::RootVector<Value> new_elements;
new_elements.append(value);
// 3. Append group as the last element of groups.
@ -280,7 +280,7 @@ ThrowCompletionOr<GroupsType> group_by(VM& vm, Value items, Value callback_funct
// ii. IfAbruptCloseIterator(key, iteratorRecord).
auto property_key = TRY_OR_CLOSE_ITERATOR(vm, iterator_record, key.to_property_key(vm));
add_value_to_keyed_group(vm, groups, move(property_key), value);
add_value_to_keyed_group(groups, move(property_key), value);
}
// h. Else,
else {
@ -290,7 +290,7 @@ ThrowCompletionOr<GroupsType> group_by(VM& vm, Value items, Value callback_funct
// ii. Set key to CanonicalizeKeyedCollectionKey(key).
key = canonicalize_keyed_collection_key(key);
add_value_to_keyed_group(vm, groups, make_root(key), value);
add_value_to_keyed_group(groups, make_root(key), value);
}
// i. Perform AddValueToKeyedGroup(groups, key, value).

View file

@ -172,7 +172,7 @@ ThrowCompletionOr<bool> Array::set_length(PropertyDescriptor const& property_des
ThrowCompletionOr<GC::RootVector<Value>> sort_indexed_properties(VM& vm, Object const& object, size_t length, Function<ThrowCompletionOr<double>(Value, Value)> const& sort_compare, Holes holes)
{
// 1. Let items be a new empty List.
auto items = GC::RootVector<Value> { vm.heap() };
GC::RootVector<Value> items;
// 2. Let k be 0.
// 3. Repeat, while k < len,

View file

@ -38,7 +38,7 @@ public:
template<typename T>
static GC::Ref<Array> create_from(Realm& realm, ReadonlySpan<T> elements, Function<Value(T const&)> map_fn)
{
auto values = GC::RootVector<Value> { realm.heap() };
GC::RootVector<Value> values;
values.ensure_capacity(elements.size());
for (auto const& element : elements)
values.append(map_fn(element));

View file

@ -1483,8 +1483,8 @@ ThrowCompletionOr<void> array_merge_sort(VM& vm, Function<ThrowCompletionOr<doub
if (arr_to_sort.size() <= 1)
return {};
GC::RootVector<Value> left(vm.heap());
GC::RootVector<Value> right(vm.heap());
GC::RootVector<Value> left;
GC::RootVector<Value> right;
left.ensure_capacity(arr_to_sort.size() / 2);
right.ensure_capacity(arr_to_sort.size() / 2 + (arr_to_sort.size() & 1));

View file

@ -104,7 +104,7 @@ ThrowCompletionOr<void> FinalizationRegistry::cleanup(GC::Ptr<JobCallback> callb
break;
// b. Remove cell from finalizationRegistry.[[Cells]].
GC::RootVector<Value> arguments(vm.heap());
GC::RootVector<Value> arguments;
arguments.append(it->held_value);
it = m_records.remove(it);

View file

@ -51,7 +51,7 @@ template<typename... Args>
[[nodiscard]] ALWAYS_INLINE ThrowCompletionOr<Value> Value::invoke(VM& vm, PropertyKey const& property_key, Args... args)
{
if constexpr (sizeof...(Args) > 0) {
GC::RootVector<Value> arglist { vm.heap() };
GC::RootVector<Value> arglist;
(..., arglist.append(move(args)));
return invoke_internal(vm, property_key, move(arglist));
}

View file

@ -72,7 +72,7 @@ JS_DEFINE_NATIVE_FUNCTION(Intl::get_canonical_locales)
// 1. Let ll be ? CanonicalizeLocaleList(locales).
auto locale_list = TRY(canonicalize_locale_list(vm, locales));
GC::RootVector<Value> marked_locale_list { vm.heap() };
GC::RootVector<Value> marked_locale_list;
marked_locale_list.ensure_capacity(locale_list.size());
for (auto& locale : locale_list)

View file

@ -400,7 +400,7 @@ GC::Ref<Object> create_iterator_result_object(VM& vm, Value value, bool done)
ThrowCompletionOr<GC::RootVector<Value>> iterator_to_list(VM& vm, IteratorRecord& iterator_record)
{
// 1. Let values be a new empty List.
GC::RootVector<Value> values(vm.heap());
GC::RootVector<Value> values;
// 2. Repeat,
while (true) {

View file

@ -261,7 +261,7 @@ public:
// b. Repeat,
// i. Let results be a new empty List.
GC::RootVector<Value> results { vm.heap() };
GC::RootVector<Value> results;
// ii. Assert: openIters is not empty.
VERIFY(!m_open_iterators.is_empty());

View file

@ -774,7 +774,7 @@ JS_DEFINE_NATIVE_FUNCTION(IteratorPrototype::to_array)
auto iterated = TRY(get_iterator_direct(vm, object));
// 4. Let items be a new empty List.
GC::RootVector<Value> items(realm.heap());
GC::RootVector<Value> items;
// 5. Repeat,
while (true) {

View file

@ -219,7 +219,7 @@ ThrowCompletionOr<GC::RootVector<Value>> ModuleNamespaceObject::internal_own_pro
{
// 1. Let exports be O.[[Exports]].
// NOTE: We only add the exports after we know the size of symbolKeys
GC::RootVector<Value> exports { vm().heap() };
GC::RootVector<Value> exports;
// 2. Let symbolKeys be OrdinaryOwnPropertyKeys(O).
auto symbol_keys = MUST(Object::internal_own_property_keys());

View file

@ -484,7 +484,7 @@ ThrowCompletionOr<GC::RootVector<Value>> Object::enumerable_own_property_names(P
// 1. Let ownKeys be ? O.[[OwnPropertyKeys]]().
// 2. Let properties be a new empty List.
auto properties = GC::RootVector<Value> { heap() };
GC::RootVector<Value> properties;
properties.ensure_capacity(own_properties_count());
auto& pre_iteration_shape = shape();
@ -1230,7 +1230,7 @@ ThrowCompletionOr<GC::RootVector<Value>> Object::internal_own_property_keys() co
auto& vm = this->vm();
// 1. Let keys be a new empty List.
GC::RootVector<Value> keys { heap() };
GC::RootVector<Value> keys;
// 2. For each own property key P of O such that P is an array index, in ascending numeric index order, do
{

View file

@ -103,7 +103,7 @@ static ThrowCompletionOr<GC::RootVector<Value>> get_own_property_keys(VM& vm, Va
auto keys = TRY(object->internal_own_property_keys());
// 3. Let nameList be a new empty List.
auto name_list = GC::RootVector<Value> { vm.heap() };
GC::RootVector<Value> name_list;
// 4. For each element nextKey of keys, do
for (auto& next_key : keys) {

View file

@ -704,10 +704,10 @@ ThrowCompletionOr<GC::RootVector<Value>> ProxyObject::internal_own_property_keys
// 13. Assert: targetKeys contains no duplicate entries.
// 14. Let targetConfigurableKeys be a new empty List.
auto target_configurable_keys = GC::RootVector<Value> { heap() };
GC::RootVector<Value> target_configurable_keys;
// 15. Let targetNonconfigurableKeys be a new empty List.
auto target_nonconfigurable_keys = GC::RootVector<Value> { heap() };
GC::RootVector<Value> target_nonconfigurable_keys;
// 16. For each element key of targetKeys, do
for (auto& key : target_keys) {
@ -735,7 +735,7 @@ ThrowCompletionOr<GC::RootVector<Value>> ProxyObject::internal_own_property_keys
}
// 18. Let uncheckedResultKeys be a List whose elements are the elements of trapResult.
auto unchecked_result_keys = GC::RootVector<Value> { heap() };
GC::RootVector<Value> unchecked_result_keys;
unchecked_result_keys.extend(trap_result);
// 19. For each element key of targetNonconfigurableKeys, do

View file

@ -903,7 +903,7 @@ ThrowCompletionOr<Value> RegExpPrototype::symbol_replace_impl(VM& vm, Object& re
}
// 10. Let results be a new empty List.
GC::RootVector<Object*> results(vm.heap());
GC::RootVector<Object*> results;
// 11. Let done be false.
// 12. Repeat, while done is false,
@ -970,7 +970,7 @@ ThrowCompletionOr<Value> RegExpPrototype::symbol_replace_impl(VM& vm, Object& re
position = clamp(position, static_cast<double>(0), static_cast<double>(string->length_in_utf16_code_units()));
// g. Let captures be a new empty List.
GC::RootVector<Value> captures(vm.heap());
GC::RootVector<Value> captures;
// h. Let n be 1.
// i. Repeat, while n ≤ nCaptures,
@ -1000,7 +1000,7 @@ ThrowCompletionOr<Value> RegExpPrototype::symbol_replace_impl(VM& vm, Object& re
// k. If functionalReplace is true, then
if (replace_value.is_function()) {
// i. Let replacerArgs be the list-concatenation of « matched », captures, and « 𝔽(position), S ».
GC::RootVector<Value> replacer_args(vm.heap());
GC::RootVector<Value> replacer_args;
replacer_args.append(matched);
replacer_args.extend(move(captures));
replacer_args.append(Value(position));

View file

@ -536,7 +536,7 @@ void Shape::invalidate_all_prototype_chains_leading_to_this()
return;
GC::RootHashTable<Shape*> shapes_to_invalidate(heap());
GC::RootVector<Shape*> worklist(heap());
GC::RootVector<Shape*> worklist;
auto enqueue_children_of = [&](Shape& shape) {
if (!shape.m_child_prototype_shapes)
return;

View file

@ -134,7 +134,7 @@ ThrowCompletionOr<GC::RootVector<Value>> StringObject::internal_own_property_key
auto& vm = this->vm();
// 1. Let keys be a new empty List.
auto keys = GC::RootVector<Value> { heap() };
GC::RootVector<Value> keys;
// 2. Let str be O.[[StringData]].
// 3. Assert: str is a String.

View file

@ -462,7 +462,7 @@ public:
auto typed_array_record = make_typed_array_with_buffer_witness_record(*this, ArrayBuffer::Order::SeqCst);
// 2. Let keys be a new empty List.
auto keys = GC::RootVector<Value> { heap() };
GC::RootVector<Value> keys;
// 3. If IsTypedArrayOutOfBounds(taRecord) is false, then
if (!is_typed_array_out_of_bounds(typed_array_record)) {

View file

@ -93,7 +93,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayConstructor::from)
auto length = values.size();
// c. Let targetObj be ? TypedArrayCreate(C, « 𝔽(len) »).
GC::RootVector<Value> arguments(vm.heap());
GC::RootVector<Value> arguments;
arguments.empend(length);
auto* target_object = TRY(typed_array_create(vm, constructor.as_function(), move(arguments)));
@ -140,7 +140,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayConstructor::from)
auto length = TRY(length_of_array_like(vm, array_like));
// 10. Let targetObj be ? TypedArrayCreate(C, « 𝔽(len) »).
GC::RootVector<Value> arguments(vm.heap());
GC::RootVector<Value> arguments;
arguments.empend(length);
auto* target_object = TRY(typed_array_create(vm, constructor.as_function(), move(arguments)));
@ -189,7 +189,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayConstructor::of)
return vm.throw_completion<TypeError>(ErrorType::NotAConstructor, constructor);
// 4. Let newObj be ? TypedArrayCreate(C, « 𝔽(len) »).
GC::RootVector<Value> arguments(vm.heap());
GC::RootVector<Value> arguments;
arguments.append(Value(length));
auto* new_object = TRY(typed_array_create(vm, constructor.as_function(), move(arguments)));

View file

@ -653,7 +653,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::filter)
auto callback_function = TRY(callback_from_args(vm, "filter"sv));
// 5. Let kept be a new empty List.
GC::RootVector<Value> kept { vm.heap() };
GC::RootVector<Value> kept;
// 6. Let captured be 0.
size_t captured = 0;
@ -683,7 +683,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::filter)
}
// 9. Let A be ? TypedArraySpeciesCreate(O, « 𝔽(captured) »).
GC::RootVector<Value> arguments(vm.heap());
GC::RootVector<Value> arguments;
arguments.empend(captured);
auto& realm = *vm.current_realm();
auto* filter_array = TRY(typed_array_species_create(vm, *typed_array, [&]() -> ThrowCompletionOr<GC::Ref<TypedArrayBase>> { return TRY(typed_array->create_default(realm, captured)); }, move(arguments)));
@ -1206,7 +1206,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::map)
auto callback_function = TRY(callback_from_args(vm, "map"sv));
// 5. Let A be ? TypedArraySpeciesCreate(O, « 𝔽(len) »).
GC::RootVector<Value> arguments(vm.heap());
GC::RootVector<Value> arguments;
arguments.empend(length);
auto& realm = *vm.current_realm();
auto* array = TRY(typed_array_species_create(vm, *typed_array, [&]() -> ThrowCompletionOr<GC::Ref<TypedArrayBase>> { return TRY(typed_array->create_default(realm, length)); }, move(arguments)));
@ -1689,7 +1689,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::slice)
auto count = max(final - k, 0);
// 13. Let A be ? TypedArraySpeciesCreate(O, « 𝔽(count) »).
GC::RootVector<Value> arguments(vm.heap());
GC::RootVector<Value> arguments;
arguments.empend(count);
auto& realm = *vm.current_realm();
auto* array = TRY(typed_array_species_create(vm, *typed_array, [&]() -> ThrowCompletionOr<GC::Ref<TypedArrayBase>> { return TRY(typed_array->create_default(realm, count)); }, move(arguments)));
@ -1944,7 +1944,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::subarray)
return typed_array;
}
GC::RootVector<Value> arguments(vm.heap());
GC::RootVector<Value> arguments;
Optional<u32> new_length;
// 15. If O.[[ArrayLength]] is auto and end is undefined, then
@ -2058,7 +2058,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::to_reversed)
auto length = typed_array_length(typed_array_record);
// 4. Let A be ? TypedArrayCreateSameType(O, « 𝔽(length) »).
GC::RootVector<Value> arguments(vm.heap());
GC::RootVector<Value> arguments;
arguments.empend(length);
auto* array = TRY(typed_array_create_same_type(vm, *typed_array, move(arguments)));
@ -2103,7 +2103,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::to_sorted)
auto length = typed_array_length(typed_array_record);
// 5. Let A be ? TypedArrayCreateSameType(O, « 𝔽(len) »).
GC::RootVector<Value> arguments(vm.heap());
GC::RootVector<Value> arguments;
arguments.empend(length);
auto* array = TRY(typed_array_create_same_type(vm, *typed_array, move(arguments)));
@ -2183,7 +2183,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::with)
return vm.throw_completion<RangeError>(ErrorType::TypedArrayInvalidIntegerIndex, actual_index);
// 10. Let A be ? TypedArrayCreateSameType(O, « 𝔽(len) »).
GC::RootVector<Value> arguments(vm.heap());
GC::RootVector<Value> arguments;
arguments.empend(length);
auto* array = TRY(typed_array_create_same_type(vm, *typed_array, move(arguments)));

View file

@ -45,7 +45,7 @@ void AnimationTimeline::update_associated_animations_and_dispatch_events()
for (auto& animation : m_associated_animations)
animation.update();
auto animations = GC::RootVector<GC::Ref<Animations::Animation>> { heap() };
GC::RootVector<GC::Ref<Animations::Animation>> animations;
for (auto& animation : m_associated_animations)
animations.append(animation);
for (auto& animation : animations)

View file

@ -872,7 +872,7 @@ WebIDL::ExceptionOr<GC::RootVector<JS::Object*>> KeyframeEffect::get_keyframes()
}
}
GC::RootVector<JS::Object*> keyframes { heap() };
GC::RootVector<JS::Object*> keyframes;
for (auto const& keyframe : m_keyframe_objects)
keyframes.append(keyframe);
return keyframes;

View file

@ -410,7 +410,7 @@ JS::ThrowCompletionOr<GC::RootVector<JS::Value>> PlatformObject::internal_own_pr
auto& vm = this->vm();
// 1. Let keys be a new empty list of ECMAScript String and Symbol values.
GC::RootVector<JS::Value> keys { heap() };
GC::RootVector<JS::Value> keys;
// 2. If O supports indexed properties, then for each index of Os supported property indices, in ascending numerical order, append ! ToString(index) to keys.
if (m_legacy_platform_object_flags->supports_indexed_properties) {

View file

@ -50,7 +50,7 @@ WebIDL::ExceptionOr<GC::Ref<CSSMathMax>> CSSMathMax::construct_impl(JS::Realm& r
// NB: So, the steps below are a modification of the CSSMathSum steps.
// 1. Replace each item of args with the result of rectifying a numberish value for the item.
GC::RootVector<GC::Ref<CSSNumericValue>> converted_values { realm.heap() };
GC::RootVector<GC::Ref<CSSNumericValue>> converted_values;
converted_values.ensure_capacity(values.size());
for (auto const& value : values) {
converted_values.append(rectify_a_numberish_value(realm, value));

View file

@ -51,7 +51,7 @@ WebIDL::ExceptionOr<GC::Ref<CSSMathMin>> CSSMathMin::construct_impl(JS::Realm& r
// NB: So, the steps below are a modification of the CSSMathSum steps.
// 1. Replace each item of args with the result of rectifying a numberish value for the item.
GC::RootVector<GC::Ref<CSSNumericValue>> converted_values { realm.heap() };
GC::RootVector<GC::Ref<CSSNumericValue>> converted_values;
converted_values.ensure_capacity(values.size());
for (auto const& value : values) {
converted_values.append(rectify_a_numberish_value(realm, value));

View file

@ -50,7 +50,7 @@ WebIDL::ExceptionOr<GC::Ref<CSSMathProduct>> CSSMathProduct::construct_impl(JS::
// NB: So, the steps below are a modification of the CSSMathSum steps.
// 1. Replace each item of args with the result of rectifying a numberish value for the item.
GC::RootVector<GC::Ref<CSSNumericValue>> converted_values { realm.heap() };
GC::RootVector<GC::Ref<CSSNumericValue>> converted_values;
converted_values.ensure_capacity(values.size());
for (auto const& value : values) {
converted_values.append(rectify_a_numberish_value(realm, value));

View file

@ -48,7 +48,7 @@ WebIDL::ExceptionOr<GC::Ref<CSSMathSum>> CSSMathSum::construct_impl(JS::Realm& r
// The CSSMathSum(...args) constructor must, when called, perform the following steps:
// 1. Replace each item of args with the result of rectifying a numberish value for the item.
GC::RootVector<GC::Ref<CSSNumericValue>> converted_values { realm.heap() };
GC::RootVector<GC::Ref<CSSNumericValue>> converted_values;
converted_values.ensure_capacity(values.size());
for (auto const& value : values) {
converted_values.append(rectify_a_numberish_value(realm, value));

View file

@ -95,7 +95,7 @@ WebIDL::ExceptionOr<GC::Ref<CSSNumericValue>> CSSNumericValue::add(Vector<CSSNum
// Otherwise, prepend this to values.
// NB: We reorder the steps a little to avoid the awkward prepending.
GC::RootVector<GC::Ref<CSSNumericValue>> values { heap() };
GC::RootVector<GC::Ref<CSSNumericValue>> values;
if (auto const* math_sum = as_if<CSSMathSum>(*this))
values.extend(math_sum->values()->values());
else
@ -156,7 +156,7 @@ WebIDL::ExceptionOr<GC::Ref<CSSNumericValue>> CSSNumericValue::mul(Vector<CSSNum
// Otherwise, prepend this to values.
// NB: We reorder the steps a little to avoid the awkward prepending.
GC::RootVector<GC::Ref<CSSNumericValue>> values { heap() };
GC::RootVector<GC::Ref<CSSNumericValue>> values;
if (auto const* math_product = as_if<CSSMathProduct>(*this))
values.extend(math_product->values()->values());
else
@ -254,7 +254,7 @@ WebIDL::ExceptionOr<GC::Ref<CSSNumericValue>> CSSNumericValue::min(Vector<CSSNum
// Otherwise, prepend this to values.
// NB: We reorder the steps a little to avoid the awkward prepending.
GC::RootVector<GC::Ref<CSSNumericValue>> values { heap() };
GC::RootVector<GC::Ref<CSSNumericValue>> values;
if (auto const* math_product = as_if<CSSMathMin>(*this))
values.extend(math_product->values()->values());
else
@ -284,7 +284,7 @@ WebIDL::ExceptionOr<GC::Ref<CSSNumericValue>> CSSNumericValue::max(Vector<CSSNum
// Otherwise, prepend this to values.
// NB: We reorder the steps a little to avoid the awkward prepending.
GC::RootVector<GC::Ref<CSSNumericValue>> values { heap() };
GC::RootVector<GC::Ref<CSSNumericValue>> values;
if (auto const* math_product = as_if<CSSMathMax>(*this))
values.extend(math_product->values()->values());
else

View file

@ -245,7 +245,7 @@ GC::Ref<WebIDL::Promise> CSSStyleSheet::replace(String text)
auto rules = CSS::Parser::Parser::create(make_parsing_params(), text).parse_as_stylesheet_contents();
// 2. If rules contains one or more @import rules, remove those rules from rules.
GC::RootVector<GC::Ref<CSSRule>> rules_without_import(realm.heap());
GC::RootVector<GC::Ref<CSSRule>> rules_without_import;
for (auto rule : rules) {
if (rule->type() != CSSRule::Type::Import)
rules_without_import.append(rule);
@ -283,7 +283,7 @@ WebIDL::ExceptionOr<void> CSSStyleSheet::replace_sync(StringView text)
auto rules = CSS::Parser::Parser::create(make_parsing_params(), text).parse_as_stylesheet_contents();
// 3. If rules contains one or more @import rules, remove those rules from rules.
GC::RootVector<GC::Ref<CSSRule>> rules_without_import(realm().heap());
GC::RootVector<GC::Ref<CSSRule>> rules_without_import;
for (auto rule : rules) {
if (rule->type() != CSSRule::Type::Import)
rules_without_import.append(rule);

View file

@ -90,7 +90,7 @@ WebIDL::ExceptionOr<Variant<GC::Ref<CSSStyleValue>, GC::RootVector<GC::Ref<CSSSt
auto values = whole_value->subdivide_into_iterations(property.value());
// 5. For each value in values, replace it with the result of reifying value for property.
GC::RootVector<GC::Ref<CSSStyleValue>> reified_values { vm.heap() };
GC::RootVector<GC::Ref<CSSStyleValue>> reified_values;
for (auto const& value : values) {
reified_values.append(value->reify(*vm.current_realm(), property->name()));
}

View file

@ -253,7 +253,7 @@ static WebIDL::ExceptionOr<GC::Ref<JS::Set>> find_matching_font_faces(JS::Realm&
// 8. For each font face in matched font faces, if its defined unicode-range does not include the codepoint of at
// least one character in text, remove it from the list.
auto faces_to_remove = GC::RootVector<JS::Value> { realm.heap() };
GC::RootVector<JS::Value> faces_to_remove;
for (auto entry : *matched_font_faces) {
auto& font_face = as<FontFace>(entry.key.as_object());
bool includes_at_least_one_text_code_point = false;
@ -301,7 +301,7 @@ JS::ThrowCompletionOr<GC::Ref<WebIDL::Promise>> FontFaceSet::load(String const&
// 4. Queue a task to run the following steps synchronously:
HTML::queue_a_task(HTML::Task::Source::FontLoading, nullptr, nullptr, GC::create_function(realm.heap(), [&realm, promise, matched_font_faces] {
GC::RootVector<GC::Ref<WebIDL::Promise>> promises(realm.heap());
GC::RootVector<GC::Ref<WebIDL::Promise>> promises;
// 1. For all of the font faces in the font face list, call their load() method.
for (auto font_face_value : *matched_font_faces) {

View file

@ -344,7 +344,7 @@ static void invalidate_style_of_elements_affected_by_pending_has_mutations(Style
bool should_scan_ancestor_siblings = style_scope.have_has_selectors_with_relative_selector_that_has_sibling_combinator();
for (auto& [node, mutation_features] : pending_has_invalidations) {
GC::RootHashTable<GC::Ref<DOM::Element>> elements_skipped_by_has_feature_filter { style_scope.node().heap() };
GC::RootVector<GC::Ref<DOM::Element>, 16> has_scope_ancestors { style_scope.node().heap() };
GC::RootVector<GC::Ref<DOM::Element>, 16> has_scope_ancestors;
bool should_delay_ancestor_sibling_scans = false;
for (GC::Ptr<DOM::Node> ancestor = node; ancestor; ancestor = ancestor->parent_or_shadow_host()) {
if (!ancestor->is_element())

View file

@ -684,7 +684,7 @@ GC::Ptr<CSSMediaRule> Parser::convert_to_media_rule(AtRule const& rule, Nested n
auto media_query_list = parse_a_media_query_list(media_query_tokens);
auto media_list = MediaList::create(realm(), move(media_query_list));
GC::RootVector<GC::Ref<CSSRule>> child_rules { realm().heap() };
GC::RootVector<GC::Ref<CSSRule>> child_rules;
for (auto const& child : rule.child_rules_and_lists_of_declarations) {
child.visit(
[&](Rule const& rule) {

View file

@ -130,7 +130,7 @@ GC::RootVector<GC::Ref<CSSRule>> Parser::convert_rules(Vector<Rule> const& raw_r
bool namespace_rules_valid = true;
// Interpret all of the resulting top-level qualified rules as style rules, defined below.
GC::RootVector<GC::Ref<CSSRule>> rules(realm().heap());
GC::RootVector<GC::Ref<CSSRule>> rules;
for (auto const& raw_rule : raw_rules) {
auto rule = convert_to_rule<CSSNestedDeclarations>(raw_rule, Nested::No);
// If any style rule is invalid, or any at-rule is not recognized or is invalid according to its grammar or context, its a parse error.

View file

@ -189,7 +189,7 @@ GC::Ptr<CSSStyleRule> Parser::convert_to_style_rule(QualifiedRule const& qualifi
auto declaration = convert_to_style_declaration(qualified_rule.declarations);
GC::RootVector<GC::Ref<CSSRule>> child_rules { realm().heap() };
GC::RootVector<GC::Ref<CSSRule>> child_rules;
for (auto& child : qualified_rule.child_rules) {
child.visit(
[&](Rule const& rule) {
@ -389,7 +389,7 @@ GC::Ptr<CSSRule> Parser::convert_to_layer_rule(AtRule const& rule, Nested nested
}
// Then the rules
GC::RootVector<GC::Ref<CSSRule>> child_rules { realm().heap() };
GC::RootVector<GC::Ref<CSSRule>> child_rules;
for (auto const& child : rule.child_rules_and_lists_of_declarations) {
child.visit(
[&](Rule const& rule) {
@ -519,7 +519,7 @@ GC::Ptr<CSSKeyframesRule> Parser::convert_to_keyframes_rule(AtRule const& rule)
// animation-name: "foo" compare on the same value.
auto name = name_token.is(Token::Type::String) ? name_token.string() : name_token.ident();
GC::RootVector<GC::Ref<CSSRule>> keyframes(realm().heap());
GC::RootVector<GC::Ref<CSSRule>> keyframes;
rule.for_each_as_qualified_rule_list([&](auto& qualified_rule) {
if (!qualified_rule.child_rules.is_empty()) {
for (auto const& child_rule : qualified_rule.child_rules) {
@ -691,7 +691,7 @@ GC::Ptr<CSSSupportsRule> Parser::convert_to_supports_rule(AtRule const& rule, Ne
return {};
}
GC::RootVector<GC::Ref<CSSRule>> child_rules { realm().heap() };
GC::RootVector<GC::Ref<CSSRule>> child_rules;
for (auto const& child : rule.child_rules_and_lists_of_declarations) {
child.visit(
[&](Rule const& rule) {
@ -902,7 +902,7 @@ GC::Ptr<CSSContainerRule> Parser::convert_to_container_rule(AtRule const& rule,
conditions.unchecked_empend(move(container_name), move(container_query));
}
GC::RootVector<GC::Ref<CSSRule>> child_rules { realm().heap() };
GC::RootVector<GC::Ref<CSSRule>> child_rules;
for (auto const& child : rule.child_rules_and_lists_of_declarations) {
child.visit(
[&](Rule const& child_rule) {
@ -1437,7 +1437,7 @@ GC::Ptr<CSSPageRule> Parser::convert_to_page_rule(AtRule const& page_rule)
if (page_selectors.is_error())
return nullptr;
GC::RootVector<GC::Ref<CSSRule>> child_rules { realm().heap() };
GC::RootVector<GC::Ref<CSSRule>> child_rules;
DescriptorList descriptors { AtRuleID::Page };
page_rule.for_each_as_declaration_rule_list(
[&](auto& at_rule) {

View file

@ -85,7 +85,7 @@ WebIDL::ExceptionOr<GC::RootVector<GC::Ref<CSSStyleValue>>> StylePropertyMapRead
// 3. Let props be the value of thiss [[declarations]] internal slot.
auto& props = m_declarations;
GC::RootVector<GC::Ref<CSSStyleValue>> results { heap() };
GC::RootVector<GC::Ref<CSSStyleValue>> results;
// 4. If props[property] exists, subdivide into iterations props[property], then reify each item of the result, and return the list.
if (auto property_value = get_style_value(props, property.value())) {

View file

@ -216,7 +216,7 @@ static CalculationNode::NumericValue clamp_and_censor_numeric_value(NumericCalcu
static GC::Ptr<CSSNumericArray> reify_children(JS::Realm& realm, ReadonlySpan<NonnullRefPtr<CalculationNode const>> children)
{
GC::RootVector<GC::Ref<CSSNumericValue>> reified_children { realm.heap() };
GC::RootVector<GC::Ref<CSSNumericValue>> reified_children;
for (auto const& child : children) {
auto reified_child = child->reify(realm);
if (!reified_child)

View file

@ -108,7 +108,7 @@ Vector<Parser::ComponentValue> StyleValueList::tokenize() const
// https://drafts.css-houdini.org/css-typed-om-1/#reify-a-transform-list
static ErrorOr<GC::Ref<CSSStyleValue>> reify_a_transform_list(JS::Realm& realm, StyleValueVector const& values)
{
GC::RootVector<GC::Ref<CSSTransformComponent>> transform_components { realm.heap() };
GC::RootVector<GC::Ref<CSSTransformComponent>> transform_components;
for (auto const& transform : values) {
// NB: Not all transform functions are reifiable, in which case we give up reifying as a transform list.
transform_components.append(TRY(transform->as_transformation().reify_a_transform_function(realm)));

View file

@ -208,7 +208,7 @@ GC::Ref<WebIDL::Promise> Clipboard::read(Bindings::ClipboardUnsanitizedFormats f
HTML::TemporaryExecutionContext execution_context { realm };
// 4. Let items be a sequence<clipboard item>.
GC::RootVector<JS::Value> items(realm.heap());
GC::RootVector<JS::Value> items;
// 5. For each systemClipboardItem in data:
for (auto const& system_clipboard_item : data) {
@ -441,8 +441,8 @@ GC::Ref<WebIDL::Promise> Clipboard::write(Vector<GC::Root<ClipboardItem>> const&
// 4. For each clipboardItem in dataList:
for (auto const& clipboard_item : data_list) {
IGNORE_USE_IN_ESCAPING_LAMBDA GC::RootVector<GC::Ref<FileAPI::Blob>> item_list(realm.heap());
GC::RootVector<GC::Ref<FileAPI::Blob>> clean_item_list(realm.heap());
IGNORE_USE_IN_ESCAPING_LAMBDA GC::RootVector<GC::Ref<FileAPI::Blob>> item_list;
GC::RootVector<GC::Ref<FileAPI::Blob>> clean_item_list;
// 1. For each representation in clipboardItems clipboard item's list of representations:
for (auto const& representation : clipboard_item->representations()) {
@ -567,7 +567,7 @@ GC::Ref<WebIDL::Promise> Clipboard::write_text(String data)
// 3. Queue a global task on the clipboard task source, given realms global object, to perform the below steps:
queue_global_task(HTML::Task::Source::Clipboard, realm.global_object(), GC::create_function(realm.heap(), [&realm, promise, data = move(data)]() mutable {
// 1. Let itemList be an empty sequence<Blob>.
GC::RootVector<GC::Ref<FileAPI::Blob>> item_list(realm.heap());
GC::RootVector<GC::Ref<FileAPI::Blob>> item_list;
// 2. Let textBlob be a new Blob created with: type attribute set to "text/plain;charset=utf-8", and its
// underlying byte sequence set to the UTF-8 encoding of data.

View file

@ -96,7 +96,7 @@ GC::Ref<PolicyList> Policy::parse_a_responses_content_security_policies(GC::Heap
// the returned list will be empty.
// 1. Let policies be an empty list.
GC::RootVector<GC::Ref<Policy>> policies(heap);
GC::RootVector<GC::Ref<Policy>> policies;
// 2. For each token returned by extracting header list values given Content-Security-Policy and responses header
// list:

View file

@ -126,7 +126,7 @@ void Attr::handle_attribute_changes(Element& element, Optional<String> const& ol
if (element.is_custom()) {
auto& vm = this->vm();
GC::RootVector<JS::Value> arguments { vm.heap() };
GC::RootVector<JS::Value> arguments;
arguments.append(JS::PrimitiveString::create(vm, local_name()));
arguments.append(!old_value.has_value() ? JS::js_null() : JS::PrimitiveString::create(vm, old_value.value()));
arguments.append(!new_value.has_value() ? JS::js_null() : JS::PrimitiveString::create(vm, new_value.value()));

View file

@ -2073,7 +2073,7 @@ void Document::update_style_for_element(AbstractElement const& abstract_element)
// Single walk up the inheritance chain: collect each ancestor and remember the index of the topmost display:none
// entry seen. Pseudo-element styles are refreshed when the originating element is recomputed, so don't put the
// pseudo on the path.
GC::RootVector<GC::Ref<Element>> inheritance_chain { heap() };
GC::RootVector<GC::Ref<Element>> inheritance_chain;
if (!abstract_element.pseudo_element().has_value())
inheritance_chain.append(const_cast<Element&>(abstract_element.element()));
@ -2092,7 +2092,7 @@ void Document::update_style_for_element(AbstractElement const& abstract_element)
// element's DOM ancestors, so that descendant-combinator selectors match correctly. The filter is empty at this
// point because the normal top-down `update_style` traversal skipped the display:none subtree, so we have to seed
// it ourselves.
GC::RootVector<GC::Ref<Element>> ancestor_chain { heap() };
GC::RootVector<GC::Ref<Element>> ancestor_chain;
for (auto* cursor = inheritance_chain[*topmost_display_none_index].ptr(); cursor; cursor = cursor->parent_or_shadow_host_element())
ancestor_chain.append(*cursor);
@ -3133,9 +3133,7 @@ void Document::adopt_node(Node& node)
// « oldDocument, document ».
node.for_each_shadow_including_inclusive_descendant([&](DOM::Node& inclusive_descendant) {
if (auto* element = as_if<Element>(inclusive_descendant); element && element->is_custom()) {
auto& vm = this->vm();
GC::RootVector<JS::Value> arguments { vm.heap() };
GC::RootVector<JS::Value> arguments;
arguments.append(&old_document);
arguments.append(this);
@ -3367,7 +3365,7 @@ void Document::flush_autofocus_candidates()
candidates.take_first();
// 7. Let inclusiveAncestorDocuments be a list consisting of the active document of doc's inclusive ancestor navigables.
GC::RootVector<GC::Ref<Document>> inclusive_ancestor_documents(heap());
GC::RootVector<GC::Ref<Document>> inclusive_ancestor_documents;
inclusive_ancestor_documents.append(doc);
auto ancestor_navigable = doc_navigable->parent();
while (ancestor_navigable) {
@ -5716,7 +5714,7 @@ void Document::queue_intersection_observer_task()
m_intersection_observer_task_queued = false;
// 2. Let notify list be a list of all IntersectionObservers whose root is in the DOM tree of document.
auto notify_list = GC::RootVector { heap(), m_intersection_observers.values() };
auto notify_list = GC::RootVector { m_intersection_observers.values() };
// 3. For each IntersectionObserver object observer in notify list, run these steps:
for (auto& observer : notify_list) {
@ -5830,7 +5828,7 @@ void Document::run_the_update_intersection_observations_steps(HighResolutionTime
// 2. For each observer in observer list:
// NOTE: We make a copy of the intersection observers list to avoid modifying it while iterating.
auto intersection_observers = GC::RootVector { heap(), m_intersection_observers.values() };
auto intersection_observers = GC::RootVector { m_intersection_observers.values() };
update_paint_and_hit_testing_properties_if_needed();
@ -6470,7 +6468,7 @@ void Document::append_pending_animation_event(Web::DOM::Document::PendingAnimati
void Document::update_animations_and_send_events(double timestamp)
{
m_last_animation_frame_timestamp = timestamp;
auto timelines_to_update = GC::RootVector { heap(), m_associated_animation_timelines.values() };
auto timelines_to_update = GC::RootVector { m_associated_animation_timelines.values() };
{
HTML::TemporaryExecutionContext temporary_execution_context { realm() };
@ -6856,7 +6854,7 @@ Element const* Document::element_from_point(double x, double y)
GC::RootVector<GC::Ref<Element>> Document::elements_from_point(double x, double y)
{
// 1. Let sequence be a new empty sequence.
GC::RootVector<GC::Ref<Element>> sequence(heap());
GC::RootVector<GC::Ref<Element>> sequence;
// 2. If either argument is negative, x is greater than the viewport width excluding the size of a rendered scroll bar (if any),
// or y is greater than the viewport height excluding the size of a rendered scroll bar (if any),
@ -7054,7 +7052,7 @@ void Document::gather_active_observations_at_depth(size_t depth)
// 1. Let depth be the depth passed in.
// 2. For each observer in [[resizeObservers]] run these steps:
auto resize_observers = GC::RootVector<GC::Ref<ResizeObserver::ResizeObserver>> { heap() };
GC::RootVector<GC::Ref<ResizeObserver::ResizeObserver>> resize_observers;
for (auto& observer : m_resize_observers)
resize_observers.append(observer);
@ -7096,12 +7094,12 @@ size_t Document::broadcast_active_resize_observations()
// 2. For each observer in document.[[resizeObservers]] run these steps:
// NOTE: We make a copy of the resize observers list to avoid modifying it while iterating.
auto resize_observers = GC::RootVector<GC::Ref<ResizeObserver::ResizeObserver>> { heap() };
GC::RootVector<GC::Ref<ResizeObserver::ResizeObserver>> resize_observers;
for (auto& observer : m_resize_observers)
resize_observers.append(observer);
// Keep all gathered targets alive while resize observer callbacks run.
auto active_targets = GC::RootVector<GC::Ref<Element>> { heap() };
GC::RootVector<GC::Ref<Element>> active_targets;
for (auto const& observer : resize_observers) {
for (auto const& observation : observer->active_targets()) {
if (auto target = observation->target())
@ -7116,7 +7114,7 @@ size_t Document::broadcast_active_resize_observations()
}
// 2. Let entries be an empty list of ResizeObserverEntryies.
GC::RootVector<GC::Ref<ResizeObserver::ResizeObserverEntry>> entries(heap());
GC::RootVector<GC::Ref<ResizeObserver::ResizeObserverEntry>> entries;
// 3. For each observation in [[activeTargets]] perform these steps:
for (auto const& observation : observer->active_targets()) {
@ -7396,7 +7394,7 @@ void Document::process_top_layer_removals()
{
// 1. For each element el in docs pending top layer removals: if els computed value of overlay is none, or el is
// not rendered, remove el from docs top layer and pending top layer removals.
GC::RootVector<GC::Ref<Element>> elements_to_remove(heap());
GC::RootVector<GC::Ref<Element>> elements_to_remove;
// NB: Called during top layer processing.
for (auto& element : m_top_layer_pending_removals) {
// FIXME: Implement overlay property
@ -7671,7 +7669,7 @@ void Document::fully_exit_fullscreen()
return;
// 2. Unfullscreen elements whose fullscreen flag is set, within documents top layer, except for documents fullscreen element.
GC::RootVector<GC::Ref<Element>, 8> fullscreen_elements { heap() };
GC::RootVector<GC::Ref<Element>, 8> fullscreen_elements;
for (auto const& element : top_layer_elements()) {
if (element->is_fullscreen_element() && element != fullscreened_element)
fullscreen_elements.append(element);

View file

@ -742,7 +742,7 @@ GC::Ptr<DOM::Element> Element::get_the_attribute_associated_element(FlyString co
Optional<GC::RootVector<GC::Ref<DOM::Element>>> Element::get_the_attribute_associated_elements(FlyString const& content_attribute, Optional<Vector<GC::Weak<DOM::Element>> const&> explicitly_set_attribute_elements) const
{
// 1. Let elements be an empty list.
GC::RootVector<GC::Ref<DOM::Element>> elements(heap());
GC::RootVector<GC::Ref<DOM::Element>> elements;
// 2. Let element be the result of running reflectedTarget's get the element.
auto const& element = *this;
@ -3242,7 +3242,7 @@ void Element::enqueue_a_custom_element_callback_reaction(FlyString const& callba
// 4. Set callback to the following steps:
auto steps = JS::NativeFunction::create(realm(), [this, disconnected_callback, connected_callback](JS::VM&) {
GC::RootVector<JS::Value> no_arguments { heap() };
GC::RootVector<JS::Value> no_arguments;
// 1. If disconnectedCallback is not null, then call disconnectedCallback with no arguments.
if (disconnected_callback)
@ -3304,7 +3304,7 @@ JS::ThrowCompletionOr<void> Element::upgrade_element(GC::Ref<HTML::CustomElement
auto const* attribute = m_attributes->item(attribute_index);
VERIFY(attribute);
GC::RootVector<JS::Value> arguments { vm.heap() };
GC::RootVector<JS::Value> arguments;
arguments.append(JS::PrimitiveString::create(vm, attribute->local_name()));
arguments.append(JS::js_null());
@ -3317,7 +3317,7 @@ JS::ThrowCompletionOr<void> Element::upgrade_element(GC::Ref<HTML::CustomElement
// 5. If element is connected, then enqueue a custom element callback reaction with element, callback name
// "connectedCallback", and « ».
if (is_connected()) {
GC::RootVector<JS::Value> empty_arguments { vm.heap() };
GC::RootVector<JS::Value> empty_arguments;
enqueue_a_custom_element_callback_reaction(HTML::CustomElementReactionNames::connectedCallback, move(empty_arguments));
}

View file

@ -127,7 +127,7 @@ void HTMLCollection::update_cache_if_needed() const
GC::RootVector<GC::Ref<Element>> HTMLCollection::collect_matching_elements() const
{
update_cache_if_needed();
GC::RootVector<GC::Ref<Element>> elements(heap());
GC::RootVector<GC::Ref<Element>> elements;
for (auto& element : m_cached_elements)
elements.append(*element);
return elements;

View file

@ -37,7 +37,7 @@ void LiveNodeList::visit_edges(Cell::Visitor& visitor)
GC::RootVector<Node*> LiveNodeList::collection() const
{
GC::RootVector<Node*> nodes(heap());
GC::RootVector<Node*> nodes;
if (m_scope == Scope::Descendants) {
m_root->for_each_in_subtree([&](auto& node) {
if (m_filter(node))

View file

@ -688,7 +688,7 @@ void Node::insert_before(GC::Ref<Node> node, GC::Ptr<Node> child, bool suppress_
// 2. If inclusiveDescendant is custom, then enqueue a custom element callback reaction with
// inclusiveDescendant, callback name "connectedCallback", and « ».
if (element->is_custom()) {
GC::RootVector<JS::Value> empty_arguments { vm().heap() };
GC::RootVector<JS::Value> empty_arguments;
element->enqueue_a_custom_element_callback_reaction(HTML::CustomElementReactionNames::connectedCallback, move(empty_arguments));
}
@ -726,7 +726,7 @@ void Node::insert_before(GC::Ref<Node> node, GC::Ptr<Node> child, bool suppress_
// post-connection steps while were traversing the node tree. This is because the post-connection steps can
// modify the trees structure, making live traversal unsafe, possibly leading to the post-connection steps
// being called multiple times on the same node.
GC::RootVector<GC::Ref<Node>> static_node_list(heap());
GC::RootVector<GC::Ref<Node>> static_node_list;
// 11. For each node of nodes, in tree order:
for (auto& node : nodes) {
@ -942,7 +942,7 @@ void Node::remove(bool suppress_observers)
// This might change in the future if there is a need.
if (auto* element = as_if<DOM::Element>(*this)) {
if (element->is_custom() && is_parent_connected) {
GC::RootVector<JS::Value> empty_arguments { vm().heap() };
GC::RootVector<JS::Value> empty_arguments;
element->enqueue_a_custom_element_callback_reaction(HTML::CustomElementReactionNames::disconnectedCallback, move(empty_arguments));
}
}
@ -956,7 +956,7 @@ void Node::remove(bool suppress_observers)
// with descendant, callback name "disconnectedCallback", and « ».
if (auto* element = as_if<DOM::Element>(descendant)) {
if (element->is_custom() && is_parent_connected) {
GC::RootVector<JS::Value> empty_arguments { vm().heap() };
GC::RootVector<JS::Value> empty_arguments;
element->enqueue_a_custom_element_callback_reaction(HTML::CustomElementReactionNames::disconnectedCallback, move(empty_arguments));
}
}
@ -1344,7 +1344,7 @@ WebIDL::ExceptionOr<void> Node::move_node(Node& new_parent, Node* child)
// reaction with inclusiveDescendant, callback name "connectedMoveCallback", and « ».
if (auto* element = as_if<DOM::Element>(inclusive_descendant)) {
if (element->is_custom() && new_parent.is_connected()) {
GC::RootVector<JS::Value> empty_arguments { vm().heap() };
GC::RootVector<JS::Value> empty_arguments;
element->enqueue_a_custom_element_callback_reaction(HTML::CustomElementReactionNames::connectedMoveCallback, move(empty_arguments));
}
}

View file

@ -1111,7 +1111,7 @@ WebIDL::ExceptionOr<void> Range::delete_contents()
// 4. Let nodesToRemove be a list of all the nodes that are contained in this, in tree order, omitting any node
// whose parent is also contained in this.
GC::RootVector<Node*> nodes_to_remove(heap());
GC::RootVector<Node*> nodes_to_remove;
for (GC::Ptr<Node> node = start_container(); node != end_container()->next_sibling(); node = node->next_in_pre_order()) {
if (contains_node(*node) && (!node->parent_node() || !contains_node(*node->parent_node())))
nodes_to_remove.append(node);

View file

@ -1702,7 +1702,7 @@ GC::Ref<PendingResponse> http_network_or_cache_fetch(JS::Realm& realm, Infrastru
auto& group = http_request->client()->fetch_group();
// 3. Let inflightRecords be the set of fetch records in group whose requests keepalive is true and done flag is unset.
GC::RootVector<GC::Ref<Infrastructure::FetchRecord>> in_flight_records(vm.heap());
GC::RootVector<GC::Ref<Infrastructure::FetchRecord>> in_flight_records;
for (auto& fetch_record : group) {
if (fetch_record.request()->keepalive() && !fetch_record.request()->done())
in_flight_records.append(fetch_record);

View file

@ -24,14 +24,13 @@ WebIDL::ExceptionOr<GC::RootVector<GC::Ptr<Gamepad>>> NavigatorGamepadPartial::g
{
auto& navigator = as<HTML::Navigator>(*this);
auto& realm = navigator.realm();
auto& heap = realm.heap();
// 1. Let doc be the current global object's associated Document.
auto& window = as<HTML::Window>(HTML::current_global_object());
auto& document = window.associated_document();
// 2. If doc is null or doc is not fully active, then return an empty list.
GC::RootVector<GC::Ptr<Gamepad>> gamepads { heap };
GC::RootVector<GC::Ptr<Gamepad>> gamepads;
if (!document.is_fully_active())
return gamepads;
@ -251,9 +250,7 @@ void NavigatorGamepadPartial::set_has_gamepad_gesture(Badge<Gamepad>, bool value
GC::RootVector<GC::Ptr<Gamepad>> NavigatorGamepadPartial::gamepads(Badge<Gamepad>) const
{
auto& navigator = as<HTML::Navigator>(*this);
auto& realm = navigator.realm();
return { realm.heap(), m_gamepads };
return GC::RootVector<GC::Ptr<Gamepad>> { as<HTML::Navigator>(*this).m_gamepads };
}
}

View file

@ -169,7 +169,7 @@ void BroadcastChannel::deliver_message_locally(BroadcastChannelMessage const& me
auto& vm = Bindings::main_thread_vm();
// 6. Let destinations be a list of BroadcastChannel objects that match the following criteria:
GC::RootVector<GC::Ref<BroadcastChannel>> destinations(vm.heap());
GC::RootVector<GC::Ref<BroadcastChannel>> destinations;
// * The result of running obtain a storage key for non-storage purposes with their relevant settings object equals sourceStorageKey.
auto same_origin_broadcast_channels = s_broadcast_channel_repository.registered_channels_for_key(message.storage_key);

View file

@ -31,7 +31,7 @@ void CloseWatcherManager::add(GC::Ref<CloseWatcher> close_watcher)
// If manager's groups's size is less than manager's allowed number of groups
if (m_groups.size() < m_allowed_number_of_groups) {
// then append « closeWatcher » to manager's groups.
GC::RootVector<GC::Ref<CloseWatcher>> new_group(realm().heap());
GC::RootVector<GC::Ref<CloseWatcher>> new_group;
new_group.append(close_watcher);
m_groups.append(move(new_group));
} else {
@ -68,7 +68,7 @@ bool CloseWatcherManager::process_close_watchers()
auto& group = m_groups.last();
// Ambiguous spec wording. We copy the groups to avoid modifying the original while iterating.
// See https://github.com/whatwg/html/issues/10240
GC::RootVector<GC::Ref<CloseWatcher>> group_copy(realm().heap());
GC::RootVector<GC::Ref<CloseWatcher>> group_copy;
group_copy.ensure_capacity(group.size());
for (auto& close_watcher : group) {
group_copy.append(close_watcher);

View file

@ -246,7 +246,7 @@ GC::RootVector<JS::Value> cross_origin_own_property_keys(Variant<HTML::Location
auto& vm = event_loop.vm();
// 1. Let keys be a new empty List.
auto keys = GC::RootVector<JS::Value> { vm.heap() };
GC::RootVector<JS::Value> keys;
// 2. For each e of CrossOriginProperties(O), append e.[[Property]] to keys.
for (auto& entry : cross_origin_properties(object))

View file

@ -668,7 +668,7 @@ void EventLoop::perform_a_microtask_checkpoint()
}
// 4. For each environment settings object settingsObject whose responsible event loop is this event loop, notify about rejected promises given settingsObject's global object.
auto environments = GC::RootVector { heap(), m_related_environment_settings_objects };
auto environments = GC::RootVector { m_related_environment_settings_objects };
for (auto& environment_settings_object : environments) {
environment_settings_object->universal_global_scope().notify_about_rejected_promises({});
}

View file

@ -79,7 +79,7 @@ void FormAssociatedElement::reset_algorithm()
if (!html_element.is_form_associated_custom_element())
return;
GC::RootVector<JS::Value> empty_arguments { html_element.heap() };
GC::RootVector<JS::Value> empty_arguments;
html_element.enqueue_a_custom_element_callback_reaction(CustomElementReactionNames::formResetCallback, move(empty_arguments));
}
@ -254,7 +254,7 @@ void FormAssociatedElement::reset_form_owner()
// See the AD-HOC comment above.
if (m_form != old_form && html_element.is_form_associated_custom_element()) {
GC::RootVector<JS::Value> arguments { html_element.heap() };
GC::RootVector<JS::Value> arguments;
arguments.append(JS::Value(m_form.ptr()));
html_element.enqueue_a_custom_element_callback_reaction(CustomElementReactionNames::formAssociatedCallback, move(arguments));
}
@ -297,7 +297,7 @@ void FormAssociatedElement::update_face_disabled_state()
m_face_disabled_state = is_disabled;
GC::RootVector<JS::Value> arguments { html_element.heap() };
GC::RootVector<JS::Value> arguments;
arguments.append(JS::Value(is_disabled));
html_element.enqueue_a_custom_element_callback_reaction(CustomElementReactionNames::formDisabledCallback, move(arguments));
}

View file

@ -86,7 +86,7 @@ static bool is_all_named_element(DOM::Element const& element)
GC::RootVector<GC::Ref<DOM::Element>> HTMLAllCollection::collect_matching_elements() const
{
GC::RootVector<GC::Ref<DOM::Element>> elements(m_root->heap());
GC::RootVector<GC::Ref<DOM::Element>> elements;
if (m_scope == Scope::Descendants) {
m_root->for_each_in_subtree_of_type<DOM::Element>([&](auto& element) {
if (m_filter(element))

View file

@ -354,7 +354,7 @@ void HTMLFormElement::reset_form()
// 2. If reset is true, then invoke the reset algorithm of each resettable element whose form owner is form.
if (reset) {
GC::RootVector<GC::Ref<HTMLElement>> associated_elements_copy(heap(), m_associated_elements);
GC::RootVector<GC::Ref<HTMLElement>> associated_elements_copy { m_associated_elements };
for (auto element : associated_elements_copy) {
auto& form_associated_element = as<FormAssociatedElement>(*element);
if (form_associated_element.is_resettable())
@ -557,7 +557,7 @@ HTMLFormElement::StaticValidationResult HTMLFormElement::statically_validate_con
// 1. Let controls be a list of all the submittable elements whose form owner is form, in tree order.
auto controls = get_submittable_elements();
// 2. Let invalid controls be an initially empty list of elements.
GC::RootVector<GC::Ref<DOM::Element>> invalid_controls(realm().heap());
GC::RootVector<GC::Ref<DOM::Element>> invalid_controls;
// 3. For each element field in controls, in tree order:
for (auto& element : controls) {
auto& field = as<FormAssociatedElement>(*element);
@ -574,7 +574,7 @@ HTMLFormElement::StaticValidationResult HTMLFormElement::statically_validate_con
if (invalid_controls.is_empty())
return { true, invalid_controls };
// 5. Let unhandled invalid controls be an initially empty list of elements.
GC::RootVector<GC::Ref<DOM::Element>> unhandled_invalid_controls(realm().heap());
GC::RootVector<GC::Ref<DOM::Element>> unhandled_invalid_controls;
// 6. For each element field in invalid controls, if any, in tree order:
for (auto& field : invalid_controls) {
// 1. Let notCanceled be the result of firing an event named invalid at field, with the cancelable attribute

View file

@ -1203,7 +1203,7 @@ static void update_the_source_set(DOM::Element& element)
TODO();
// 2. Let elements be « el ».
GC::RootVector<DOM::Element*> elements(element.heap());
GC::RootVector<DOM::Element*> elements;
elements.append(&element);
// 3. If el is an img element whose parent node is a picture element,

View file

@ -2860,7 +2860,7 @@ GC::RootVector<GC::Ref<WebIDL::Promise>> HTMLMediaElement::take_pending_play_pro
// 1. Let promises be an empty list of promises.
// 2. Copy the media element's list of pending play promises to promises.
// 3. Clear the media element's list of pending play promises.
GC::RootVector<GC::Ref<WebIDL::Promise>> promises(heap());
GC::RootVector<GC::Ref<WebIDL::Promise>> promises;
promises.extend(move(m_pending_play_promises));
// 4. Return promises.

View file

@ -109,7 +109,7 @@ NullableMessageEventSource MessageEvent::source() const
GC::Ref<JS::Object> MessageEvent::ports() const
{
if (!m_ports_array) {
GC::RootVector<JS::Value> port_vector(heap());
GC::RootVector<JS::Value> port_vector;
for (auto const& port : m_ports)
port_vector.append(port);

View file

@ -1172,7 +1172,7 @@ bool Navigation::inner_navigate_event_firing_algorithm(
// 34. If endResultIsSameDocument is true:
if (end_result_is_same_document) {
// 1. Let promisesList be an empty list.
GC::RootVector<GC::Ref<WebIDL::Promise>> promises_list(realm.heap());
GC::RootVector<GC::Ref<WebIDL::Promise>> promises_list;
// 2. For each handler of event's navigation handler list:
for (auto const& handler : event->navigation_handler_list()) {

View file

@ -17,7 +17,7 @@ namespace Web::HTML {
NonnullOwnPtr<SimilarOriginWindowAgent> SimilarOriginWindowAgent::create(GC::Heap& heap)
{
// See 'creating an agent' step in: https://html.spec.whatwg.org/multipage/webappapis.html#obtain-similar-origin-window-agent
auto agent = adopt_own(*new SimilarOriginWindowAgent(heap, CanBlock::No));
auto agent = adopt_own(*new SimilarOriginWindowAgent(CanBlock::No));
agent->event_loop = heap.allocate<HTML::EventLoop>(HTML::EventLoop::Type::Window);
return agent;
}
@ -30,10 +30,8 @@ SimilarOriginWindowAgent& relevant_similar_origin_window_agent(JS::Object const&
return as<SimilarOriginWindowAgent>(*relevant_realm(object).vm().agent());
}
SimilarOriginWindowAgent::SimilarOriginWindowAgent(GC::Heap& heap, CanBlock can_block)
SimilarOriginWindowAgent::SimilarOriginWindowAgent(CanBlock can_block)
: Agent(can_block)
, pending_mutation_observers(heap)
, signal_slots(heap)
{
}

View file

@ -49,7 +49,7 @@ struct SimilarOriginWindowAgent : public Agent {
HashMap<GC::Ref<JS::FunctionObject>, GC::Root<CustomElementRegistry>> active_custom_element_constructor_map;
private:
SimilarOriginWindowAgent(GC::Heap&, CanBlock);
SimilarOriginWindowAgent(CanBlock);
};
WEB_API SimilarOriginWindowAgent& relevant_similar_origin_window_agent(JS::Object const&);

View file

@ -193,7 +193,7 @@ void Storage::broadcast(Optional<String> const& key, Optional<String> const& old
auto url = this_document.url().serialize();
// 3. Let remoteStorages be all Storage objects excluding storage whose:
GC::RootVector<GC::Ref<Storage>> remote_storages(heap());
GC::RootVector<GC::Ref<Storage>> remote_storages;
// AD-HOC: The specification defines this by iterating over created Storage objects. However, Storage objects are
// created lazily when accessed through window.localStorage or window.sessionStorage. This means that events

View file

@ -1163,7 +1163,7 @@ WebIDL::ExceptionOr<DeserializedTransferRecord> structured_deserialize_with_tran
auto& vm = target_realm.vm();
// 1. Let memory be an empty map.
auto memory = DeserializationMemory(vm.heap());
DeserializationMemory memory {};
// 2. Let transferredValues be a new empty List.
Vector<GC::Root<JS::Object>> transferred_values;
@ -1275,7 +1275,7 @@ WebIDL::ExceptionOr<JS::Value> structured_deserialize(JS::VM& vm, SerializationR
TemporaryExecutionContext execution_context { target_realm };
if (!memory.has_value())
memory = DeserializationMemory { vm.heap() };
memory = DeserializationMemory {};
TransferDataDecoder decoder { serialized };
return structured_deserialize_internal(vm, decoder, target_realm, *memory);

View file

@ -610,7 +610,7 @@ void Window::consume_history_action_user_activation()
auto navigables = top->active_document()->inclusive_descendant_navigables();
// 4. Let windows be the list of Window objects constructed by taking the active window of each item in navigables.
GC::RootVector<GC::Ptr<Window>> windows(heap());
GC::RootVector<GC::Ptr<Window>> windows;
for (auto& n : navigables)
windows.append(n->active_window());
@ -635,7 +635,7 @@ void Window::consume_user_activation()
auto navigables = top->active_document()->inclusive_descendant_navigables();
// 4. Let windows be the list of Window objects constructed by taking the active window of each item in navigables.
GC::RootVector<GC::Ptr<Window>> windows(heap());
GC::RootVector<GC::Ptr<Window>> windows;
for (auto& n : navigables)
windows.append(n->active_window());

View file

@ -1071,7 +1071,7 @@ void WindowOrWorkerGlobalScopeMixin::forcibly_close_all_event_sources()
void WindowOrWorkerGlobalScopeMixin::close_all_idb_connections()
{
IndexedDB::Database::for_each_database([&](IndexedDB::Database& database) {
for (auto& connection : database.associated_connections_as_root_vector(this_impl().heap())) {
for (auto& connection : database.associated_connections_as_root_vector()) {
if (connection->close_pending())
continue;
if (&as<WindowOrWorkerGlobalScopeMixin>(relevant_global_object(*connection)) == this)
@ -1181,7 +1181,7 @@ GC::Ref<JS::Object> WindowOrWorkerGlobalScopeMixin::supported_entry_types() cons
auto& realm = this_impl().realm();
if (!m_supported_entry_types_array) {
GC::RootVector<JS::Value> supported_entry_types(vm.heap());
GC::RootVector<JS::Value> supported_entry_types;
#define __ENUMERATE_SUPPORTED_PERFORMANCE_ENTRY_TYPES(entry_type, cpp_class) \
supported_entry_types.append(JS::PrimitiveString::create(vm, entry_type));

View file

@ -238,7 +238,7 @@ JS::ThrowCompletionOr<GC::RootVector<JS::Value>> WindowProxy::internal_own_prope
// 1. Let W be the value of the [[Window]] internal slot of this.
// 2. Let keys be a new empty List.
auto keys = GC::RootVector<JS::Value> { vm.heap() };
GC::RootVector<JS::Value> keys;
// 3. Let maxProperties be W's associated Document's document-tree child navigables's size.
auto max_properties = m_window->associated_document().document_tree_child_navigables().size();

View file

@ -2221,7 +2221,7 @@ bool cleanup_indexed_database_transactions(GC::Ref<HTML::EventLoop> event_loop)
bool has_matching_event_loop = false;
Database::for_each_database([&has_matching_event_loop, event_loop](Database& database) {
for (auto const& connection : database.associated_connections_as_root_vector(event_loop->heap())) {
for (auto const& connection : database.associated_connections_as_root_vector()) {
for (auto const& transaction : connection->transactions()) {
// 2. For each transaction transaction with cleanup event loop matching the current event loop:
if (transaction->cleanup_event_loop() == event_loop) {

View file

@ -144,9 +144,9 @@ GC::Ref<Database::AssociatedConnections> Database::associated_connections_as_hea
return connections;
}
GC::RootVector<GC::Ref<IDBDatabase>> Database::associated_connections_as_root_vector(GC::Heap& heap)
GC::RootVector<GC::Ref<IDBDatabase>> Database::associated_connections_as_root_vector()
{
GC::RootVector<GC::Ref<IDBDatabase>> connections(heap);
GC::RootVector<GC::Ref<IDBDatabase>> connections {};
for (auto& connection : m_associated_connections) {
if (connection)
connections.append(*connection);

View file

@ -35,7 +35,7 @@ public:
using AssociatedConnections = GC::HeapVector<GC::Ref<IDBDatabase>>;
GC::Ref<AssociatedConnections> associated_connections_as_heap_vector(GC::Heap&);
GC::Ref<AssociatedConnections> associated_connections_as_heap_vector_except(GC::Heap&, IDBDatabase& connection);
GC::RootVector<GC::Ref<IDBDatabase>> associated_connections_as_root_vector(GC::Heap&);
GC::RootVector<GC::Ref<IDBDatabase>> associated_connections_as_root_vector();
ReadonlySpan<GC::Ref<ObjectStore>> object_stores() { return m_object_stores; }
GC::Ptr<ObjectStore> object_store_with_name(String const& name) const;

View file

@ -146,7 +146,7 @@ void InternalGamepad::set_axis(int axis, short value)
GC::RootVector<JS::Object*> InternalGamepad::get_received_rumble_effects() const
{
GC::RootVector<JS::Object*> received_rumble_effects { realm().heap() };
GC::RootVector<JS::Object*> received_rumble_effects;
for (auto const received_rumble_effect : m_received_rumble_effects)
received_rumble_effects.append(received_rumble_effect);
return received_rumble_effects;
@ -154,7 +154,7 @@ GC::RootVector<JS::Object*> InternalGamepad::get_received_rumble_effects() const
GC::RootVector<JS::Object*> InternalGamepad::get_received_rumble_trigger_effects() const
{
GC::RootVector<JS::Object*> received_rumble_trigger_effects { realm().heap() };
GC::RootVector<JS::Object*> received_rumble_trigger_effects {};
for (auto const received_rumble_trigger_effect : m_received_rumble_trigger_effects)
received_rumble_trigger_effects.append(received_rumble_trigger_effect);
return received_rumble_trigger_effects;

View file

@ -375,12 +375,12 @@ GC::RootVector<GC::Ref<MediaDeviceInfo>> MediaDevices::create_list_of_device_inf
// To perform creating a list of device info objects, given mediaDevices and deviceList, run the following steps:
// 1. Let resultList be an empty list.
GC::RootVector<GC::Ref<MediaDeviceInfo>> result_list { heap() };
GC::RootVector<GC::Ref<MediaDeviceInfo>> result_list;
// 2. Let microphoneList, cameraList and otherDeviceList be empty lists.
GC::RootVector<GC::Ref<MediaDeviceInfo>> microphone_list { heap() };
GC::RootVector<GC::Ref<MediaDeviceInfo>> camera_list { heap() };
GC::RootVector<GC::Ref<MediaDeviceInfo>> other_device_list { heap() };
GC::RootVector<GC::Ref<MediaDeviceInfo>> microphone_list;
GC::RootVector<GC::Ref<MediaDeviceInfo>> camera_list;
GC::RootVector<GC::Ref<MediaDeviceInfo>> other_device_list;
// 3. Let document be mediaDevices's relevant global object's associated Document.
auto const& document = as<HTML::Window>(realm.global_object()).associated_document();

View file

@ -1114,7 +1114,7 @@ void EventHandler::process_auto_scroll()
static GC::RootVector<GC::Ref<DOM::StaticRange>> target_ranges_for_input_event(DOM::Document const& document)
{
GC::RootVector<GC::Ref<DOM::StaticRange>> target_ranges { document.heap() };
GC::RootVector<GC::Ref<DOM::StaticRange>> target_ranges;
if (auto selection = document.get_selection(); selection && !selection->is_collapsed()) {
if (auto range = selection->range()) {
auto static_range = document.realm().create<DOM::StaticRange>(range->start_container(), range->start_offset(), range->end_container(), range->end_offset());

View file

@ -80,7 +80,7 @@ void ResizeObserverEntry::visit_edges(JS::Cell::Visitor& visitor)
static GC::Ref<JS::Object> to_js_array(JS::Realm& realm, Vector<GC::Ref<ResizeObserverSize>> const& sizes)
{
GC::RootVector<JS::Value> vector(realm.heap());
GC::RootVector<JS::Value> vector;
for (auto const& size : sizes)
vector.append(JS::Value(size.ptr()));

View file

@ -611,8 +611,8 @@ void schedule_job(JS::VM& vm, GC::Ref<Job> job)
// 3. If scope to job queue map[jobScope] does not exist, set scope to job queue map[jobScope] to a new job queue.
// 4. Set jobQueue to scope to job queue map[jobScope].
auto& job_queue = scope_to_job_queue_map().ensure(job_scope, [&vm] {
return JobQueue(vm.heap());
auto& job_queue = scope_to_job_queue_map().ensure(job_scope, [] {
return JobQueue {};
});
// 5. If jobQueue is empty, then:

View file

@ -336,7 +336,7 @@ GC::Ref<WebIDL::Promise> readable_stream_pipe_to(ReadableStream& source, Writabl
// 5. Shutdown with an action consisting of getting a promise to wait for all of the actions in actions, and with error.
auto action = GC::create_function(realm.heap(), [&realm, abort_destination, cancel_source]() {
GC::RootVector<GC::Ref<WebIDL::Promise>> actions(realm.heap());
GC::RootVector<GC::Ref<WebIDL::Promise>> actions {};
if (abort_destination)
actions.append(abort_destination->function()());

View file

@ -187,7 +187,7 @@ WebIDL::ExceptionOr<JS::Value> TrustedTypePolicy::get_trusted_type_policy_value(
}
// 4. Let args be << value >>.
GC::RootVector<JS::Value> args(heap());
GC::RootVector<JS::Value> args;
args.append(JS::PrimitiveString::create(vm, value));
// 5. Append each item in arguments to args.
@ -227,7 +227,7 @@ WebIDL::ExceptionOr<Optional<TrustedType>> process_value_with_a_default_policy(T
// throwIfMissing:
// false
// 3. If the algorithm threw an error, rethrow the error and abort the following steps.
auto arguments = GC::RootVector<JS::Value>(vm.heap());
auto arguments = GC::RootVector<JS::Value> {};
arguments.append(JS::PrimitiveString::create(vm, to_string(trusted_type_name)));
arguments.append(JS::PrimitiveString::create(vm, to_string(sink)));
auto policy_value = TRY(default_policy->get_trusted_type_policy_value(

View file

@ -109,11 +109,11 @@ WebIDL::ExceptionOr<Vector<ModuleExportDescriptor>> Module::exports(JS::VM&, GC:
}
// https://webassembly.github.io/threads/js-api/index.html#dom-module-customsections
WebIDL::ExceptionOr<GC::RootVector<GC::Ref<JS::ArrayBuffer>>> Module::custom_sections(JS::VM& vm, GC::Ref<Module> module_object, String section_name)
WebIDL::ExceptionOr<GC::RootVector<GC::Ref<JS::ArrayBuffer>>> Module::custom_sections(JS::VM&, GC::Ref<Module> module_object, String section_name)
{
// 1. Let bytes be moduleObject.[[Bytes]].
// 2. Let customSections be « ».
GC::RootVector<GC::Ref<JS::ArrayBuffer>> array_buffers { vm.heap() };
GC::RootVector<GC::Ref<JS::ArrayBuffer>> array_buffers;
// 3. For each custom section customSection of bytes, interpreted according to the module grammar,
auto& custom_sections = module_object->m_compiled_module->module->custom_sections();

View file

@ -219,7 +219,7 @@ Wasm::HostFunction create_host_function(JS::VM& vm, JS::FunctionObject& function
{
return Wasm::HostFunction {
[&](auto&, auto arguments) -> Wasm::Result {
GC::RootVector<JS::Value> argument_values { vm.heap() };
GC::RootVector<JS::Value> argument_values;
size_t index = 0;
for (auto& entry : arguments) {
argument_values.append(to_js_value(vm, entry, type.parameters()[index]));
@ -637,7 +637,7 @@ JS::NativeFunction* create_native_function(JS::VM& vm, Wasm::FunctionAddress add
return to_js_value(vm, result.values().first(), type.results().first());
// Put result values into a JS::Array in reverse order.
auto js_result_values = GC::RootVector<JS::Value> { realm.heap() };
GC::RootVector<JS::Value> js_result_values;
js_result_values.ensure_capacity(result.values().size());
for (size_t i = result.values().size(); i > 0; i--) {

View file

@ -390,20 +390,20 @@ GC::RootVector<GC::Ref<Web::DOM::Element>> pointer_interactable_tree(Web::HTML::
{
// 1. If element is not in the same tree as session's current browsing context's active document, return an empty sequence.
if (!browsing_context.active_document()->contains(element))
return GC::RootVector<GC::Ref<Web::DOM::Element>>(browsing_context.heap());
return GC::RootVector<GC::Ref<Web::DOM::Element>> {};
// 2. Let rectangles be the DOMRect sequence returned by calling getClientRects().
auto rectangles = element.get_client_rects();
// 3. If rectangles has the length of 0, return an empty sequence.
if (rectangles.is_empty())
return GC::RootVector<GC::Ref<Web::DOM::Element>>(browsing_context.heap());
return GC::RootVector<GC::Ref<Web::DOM::Element>> {};
// 4. Let center point be the in-view center point of the first indexed element in rectangles.
auto viewport = browsing_context.page().top_level_traversable()->viewport_rect();
auto center_point_or_error = Web::WebDriver::in_view_center_point(element, viewport);
if (center_point_or_error.is_error())
return GC::RootVector<GC::Ref<Web::DOM::Element>>(browsing_context.heap());
return GC::RootVector<GC::Ref<Web::DOM::Element>> {};
auto center_point = center_point_or_error.release_value();
// 5. Return the elements from point given the coordinates center point.

View file

@ -46,7 +46,6 @@ Optional<String> resolve_named_html_entity(StringView entity_name)
XMLDocumentBuilder::XMLDocumentBuilder(DOM::Document& document, XMLScriptingSupport scripting_support)
: m_document(document)
, m_template_node_stack(document.realm().heap())
, m_current_node(m_document)
, m_scripting_support(scripting_support)
{

View file

@ -1070,17 +1070,9 @@ static void generate_variadic_to_cpp(SourceGenerator& generator, ParameterType&
variadic_generator.set("variadic.inner_cpp_name", inner_cpp_name);
variadic_generator.set("variadic.value_name", value_name);
if (variadic_cpp_type.sequence_storage_type == SequenceStorageType::RootVector) {
variadic_generator.append(R"~~~(
@variadic.storage_type@<@variadic.item_type@> @cpp_name@ { vm.heap() };
)~~~");
} else {
variadic_generator.append(R"~~~(
@variadic.storage_type@<@variadic.item_type@> @cpp_name@;
)~~~");
}
variadic_generator.append(R"~~~(
@variadic.storage_type@<@variadic.item_type@> @cpp_name@;
if (vm.argument_count() > @js_suffix@) {
@cpp_name@.ensure_capacity(vm.argument_count() - @js_suffix@);
@ -2164,19 +2156,9 @@ void IDL::ParameterizedType::generate_sequence_from_iterable(SourceGenerator& ge
// FIXME: The WebIDL spec is out of date - it should be using GetIteratorFromMethod.
sequence_generator.append(R"~~~(
auto @iterable_cpp_name@_iterator@recursion_depth@ = TRY(JS::get_iterator_from_method(vm, @iterable_cpp_name@, *@iterator_method_cpp_name@));
)~~~");
if (sequence_cpp_type.sequence_storage_type == SequenceStorageType::Vector) {
sequence_generator.append(R"~~~(
@sequence.storage_type@<@sequence.type@> @cpp_name@;
)~~~");
} else {
sequence_generator.append(R"~~~(
@sequence.storage_type@<@sequence.type@> @cpp_name@ { vm.heap() };
)~~~");
}
sequence_generator.append(R"~~~(
for (;;) {
auto next@recursion_depth@ = TRY(JS::iterator_step(vm, @iterable_cpp_name@_iterator@recursion_depth@));
if (!next@recursion_depth@.has<JS::IterationResult>())

View file

@ -2083,11 +2083,8 @@ Messages::WebDriverClient::GetSourceResponse WebDriverConnection::get_source()
// 13.2.1 Execute Script, https://w3c.github.io/webdriver/#dfn-execute-script
Messages::WebDriverClient::ExecuteScriptResponse WebDriverConnection::execute_script(JsonValue payload)
{
auto* window = current_browsing_context().active_window();
auto& vm = window->vm();
// 1. Let body and arguments be the result of trying to extract the script arguments from a request with argument parameters.
auto [body, arguments] = TRY(extract_the_script_arguments_from_a_request(vm, payload));
auto [body, arguments] = TRY(extract_the_script_arguments_from_a_request(payload));
// 2. If the current browsing context is no longer open, return error with error code no such window.
TRY(ensure_current_browsing_context_is_open());
@ -2113,11 +2110,8 @@ Messages::WebDriverClient::ExecuteScriptResponse WebDriverConnection::execute_sc
// 13.2.2 Execute Async Script, https://w3c.github.io/webdriver/#dfn-execute-async-script
Messages::WebDriverClient::ExecuteAsyncScriptResponse WebDriverConnection::execute_async_script(JsonValue payload)
{
auto* window = current_browsing_context().active_window();
auto& vm = window->vm();
// 1. Let body and arguments by the result of trying to extract the script arguments from a request with argument parameters.
auto [body, arguments] = TRY(extract_the_script_arguments_from_a_request(vm, payload));
auto [body, arguments] = TRY(extract_the_script_arguments_from_a_request(payload));
// 2. If the current browsing context is no longer open, return error with error code no such window.
TRY(ensure_current_browsing_context_is_open());
@ -3076,7 +3070,7 @@ void WebDriverConnection::find(Web::WebDriver::LocationStrategy location_strateg
}
// https://w3c.github.io/webdriver/#dfn-extract-the-script-arguments-from-a-request
ErrorOr<WebDriverConnection::ScriptArguments, Web::WebDriver::Error> WebDriverConnection::extract_the_script_arguments_from_a_request(JS::VM& vm, JsonValue const& payload)
ErrorOr<WebDriverConnection::ScriptArguments, Web::WebDriver::Error> WebDriverConnection::extract_the_script_arguments_from_a_request(JsonValue const& payload)
{
// Creating JSON objects below requires an execution context.
Web::HTML::TemporaryExecutionContext execution_context { current_browsing_context().active_document()->realm() };
@ -3090,7 +3084,7 @@ ErrorOr<WebDriverConnection::ScriptArguments, Web::WebDriver::Error> WebDriverCo
auto const& args = *TRY(Web::WebDriver::get_property<JsonArray const*>(payload, "args"sv));
// 5. Let arguments be the result of calling the JSON deserialize algorithm with arguments args.
GC::RootVector<JS::Value> arguments { vm.heap() };
GC::RootVector<JS::Value> arguments;
auto& browsing_context = current_browsing_context();
TRY(args.try_for_each([&](JsonValue const& arg) -> ErrorOr<void, Web::WebDriver::Error> {

View file

@ -147,7 +147,7 @@ private:
String script;
GC::RootVector<JS::Value> arguments;
};
ErrorOr<ScriptArguments, Web::WebDriver::Error> extract_the_script_arguments_from_a_request(JS::VM&, JsonValue const& payload);
ErrorOr<ScriptArguments, Web::WebDriver::Error> extract_the_script_arguments_from_a_request(JsonValue const& payload);
void handle_script_response(Web::WebDriver::ExecutionResult, size_t script_execution_id);
void delete_cookies(Optional<StringView> const& name = {});

View file

@ -15,7 +15,7 @@ void test_root_vector_non_gc_type(GC::Heap& heap)
{
// expected-error@*{{RootVector element type must be convertible to Cell const* or derive from NanBoxedValue}}
// expected-note@+1 {{in instantiation of member function}}
GC::RootVector<int> bad_vector(heap);
GC::RootVector<int> bad_vector;
}
// RootHashMap where neither key nor value is a GC type should fail.

View file

@ -60,7 +60,7 @@ static bool possible_values_contain(GC::ConservativeVectorBase const& container,
TEST_CASE(root_vector_reports_roots)
{
auto& heap = test_heap();
GC::RootVector<GC::Ref<TestCell>> vector(heap);
GC::RootVector<GC::Ref<TestCell>> vector;
auto cell = heap.allocate<TestCell>();
vector.append(cell);
@ -75,7 +75,7 @@ TEST_CASE(root_vector_reports_roots)
TEST_CASE(root_vector_ptr_reports_roots)
{
auto& heap = test_heap();
GC::RootVector<GC::Ptr<TestCell>> vector(heap);
GC::RootVector<GC::Ptr<TestCell>> vector;
auto cell = heap.allocate<TestCell>();
vector.append(cell);
@ -153,7 +153,7 @@ TEST_CASE(root_hash_map_non_gc_key_skipped)
TEST_CASE(cleared_container_reports_no_roots)
{
auto& heap = test_heap();
GC::RootVector<GC::Ref<TestCell>> vector(heap);
GC::RootVector<GC::Ref<TestCell>> vector;
auto cell = heap.allocate<TestCell>();
vector.append(cell);
@ -244,7 +244,7 @@ TEST_CASE(root_hash_table_reports_roots)
TEST_CASE(empty_containers_report_no_roots)
{
auto& heap = test_heap();
GC::RootVector<GC::Ref<TestCell>> vector(heap);
GC::RootVector<GC::Ref<TestCell>> vector;
GC::RootHashTable<GC::Ref<TestCell>> table(heap);
GC::RootHashMap<int, GC::Ref<TestCell>> map(heap);