-
-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
LibJS: Implement the Array Grouping proposal #11412
Conversation
65c1e40
to
cf9912f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Vector<Handle<Value>>
should be MarkedValueList
.
Ah, I forgot to mention I already tried that. |
It is moveable 🤔 |
See here:
If I change the code to look like this: diff --git a/Userland/Libraries/LibJS/Runtime/ArrayPrototype.cpp b/Userland/Libraries/LibJS/Runtime/ArrayPrototype.cpp
index d9fc772623..bf42088331 100644
--- a/Userland/Libraries/LibJS/Runtime/ArrayPrototype.cpp
+++ b/Userland/Libraries/LibJS/Runtime/ArrayPrototype.cpp
@@ -1670,7 +1670,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::at)
// 2.3 AddValueToKeyedGroup ( groups, key, value ), https://tc39.es/proposal-array-grouping/#sec-add-value-to-keyed-group
template<typename GroupsType, typename KeyType>
-static void add_value_to_keyed_group(GroupsType& groups, KeyType key, Handle<Value> value)
+static void add_value_to_keyed_group(GlobalObject& global_object, 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
@@ -1688,7 +1688,7 @@ static void add_value_to_keyed_group(GroupsType& groups, KeyType key, Handle<Val
}
// 2. Let group be the Record { [[Key]]: key, [[Elements]]: « value » }.
- Vector<Handle<Value>> new_elements;
+ MarkedValueList new_elements { global_object.heap() };
new_elements.append(value);
// 3. Append group as the last element of groups.
@@ -1713,7 +1713,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::group_by)
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAFunction, callback_function.to_string_without_side_effects());
// 5. Let groups be a new empty List.
- OrderedHashMap<PropertyKey, Vector<Handle<Value>>> groups;
+ OrderedHashMap<PropertyKey, MarkedValueList> groups;
// 4. Let k be 0.
// 6. Repeat, while k < len
@@ -1729,7 +1729,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::group_by)
auto property_key = TRY(property_key_value.to_property_key(global_object));
// d. Perform ! AddValueToKeyedGroup(groups, propertyKey, kValue).
- add_value_to_keyed_group(groups, property_key, make_handle(k_value));
+ add_value_to_keyed_group(global_object, groups, property_key, k_value);
// e. Set k to k + 1.
}
@@ -1740,7 +1740,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::group_by)
// 8. For each Record { [[Key]], [[Elements]] } g of groups, do
for (auto& group : groups) {
// a. Let elements be ! CreateArrayFromList(g.[[Elements]]).
- auto* elements = Array::create_from<Handle<Value>>(global_object, group.value, [](auto& handle) { return handle.value(); });
+ auto* elements = Array::create_from(global_object, group.value);
// b. Perform ! CreateDataPropertyOrThrow(obj, g.[[Key]], elements).
MUST(object->create_data_property_or_throw(group.key, elements));
@@ -1780,7 +1780,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::group_by_to_map)
};
// 5. Let groups be a new empty List.
- OrderedHashMap<Handle<Value>, Vector<Handle<Value>>, KeyedGroupTraits> groups;
+ OrderedHashMap<Handle<Value>, MarkedValueList, KeyedGroupTraits> groups;
// 4. Let k be 0.
// 6. Repeat, while k < len
@@ -1799,7 +1799,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::group_by_to_map)
key = Value(0);
// e. Perform ! AddValueToKeyedGroup(groups, key, kValue).
- add_value_to_keyed_group(groups, make_handle(key), make_handle(k_value));
+ add_value_to_keyed_group(global_object, groups, make_handle(key), k_value);
// f. Set k to k + 1.
}
@@ -1810,7 +1810,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::group_by_to_map)
// 8. For each Record { [[Key]], [[Elements]] } g of groups, do
for (auto& group : groups) {
// a. Let elements be ! CreateArrayFromList(g.[[Elements]]).
- auto* elements = Array::create_from<Handle<Value>>(global_object, group.value, [](auto& handle) { return handle.value(); });
+ auto* elements = Array::create_from(global_object, group.value);
// b. Let entry be the Record { [[Key]]: g.[[Key]], [[Value]]: elements }.
// c. Append entry as the last element of map.[[MapData]]. It seems I can move it as the
|
Ah sorry for the misunderstanding, I meant it's not move-assignable :P (Thanks Andreas on Discord!) |
1f90a9d
to
bff98d1
Compare
This allows you to keep an arbitrary JS::Value alive without having to hook visit_edges somewhere, e.g. by being a NativeFunction that overrides visit_edges. For example, this allows you to store JS::Handle<JS::Value> as the key of a HashMap. This will be used to keep arbitrary Values alive in the key of a temporary HashMap in Array.prototype.groupByToMap. Co-authored-by: Ali Mohammad Pur <mpfard@serenityos.org>
This is required to store a MarkedValueList as the value of a HashMap.
bff98d1
to
6d153d1
Compare
This proposal went to stage 3 five days ago: tc39/proposal-array-grouping@1e3ae1a
This allows you to group together a bunch of elements in an array into a single named array. These groups are determined by user code in a custom callback function. The resulting groups are then stored into either a plain object or a Map depending on the function you use.
Example from their repo: