LibJS: Implement the Array Grouping proposal#11412
Merged
linusg merged 4 commits intoSerenityOS:masterfrom Jan 5, 2022
Merged
Conversation
65c1e40 to
cf9912f
Compare
linusg
suggested changes
Dec 25, 2021
Member
linusg
left a comment
There was a problem hiding this comment.
Vector<Handle<Value>> should be MarkedValueList.
Member
Author
|
Ah, I forgot to mention I already tried that. |
Member
It is moveable 🤔 |
Member
Author
|
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 |
Member
Author
|
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
10 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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:
