Reviewers: jochen, arv,
https://codereview.chromium.org/1155893003/diff/1/include/v8.h
File include/v8.h (right):
https://codereview.chromium.org/1155893003/diff/1/include/v8.h#newcode2986
include/v8.h:2986: * Guaranteed to be side-effect free if the array
contains no holes.
On 2015/05/26 16:37:40, arv wrote:
If the main use case is structured clone we could do an array where
the keys and
values are interleaved.
[k0, v0, k1, v1, ... kn, vn]
Let's leave this for a later round where we optimize the performance.
For now I'd rather leave this symmetric with AsArray().
https://codereview.chromium.org/1155893003/diff/1/src/collection.js
File src/collection.js (right):
https://codereview.chromium.org/1155893003/diff/1/src/collection.js#newcode451
src/collection.js:451: }
On 2015/05/26 16:37:40, arv wrote:
;
Done.
https://codereview.chromium.org/1155893003/diff/1/src/collection.js#newcode460
src/collection.js:460: }
On 2015/05/26 16:37:40, arv wrote:
;
Done.
Description:
Add {Map,Set}::FromArray to the API
Depends on https://codereview.chromium.org/1148383007/.
These are similar to the Map/Set constructors when called with an array,
except that they are guaranteed to be side-effect free if called with
a packed array.
This will be useful in implementing structured clone which, as
specified in HTML, speaks in terms of the internal [[MapData]]
and [[SetData]] slots without going through the exposed iteration
ES semantics.
BUG=v8:3340
LOG=y
Please review this at https://codereview.chromium.org/1155893003/
Base URL: https://chromium.googlesource.com/v8/v8.git@master
Affected files (+77, -2 lines):
M include/v8.h
M src/api.cc
M src/bootstrapper.cc
M src/collection.js
M src/contexts.h
M test/cctest/test-api.cc
Index: include/v8.h
diff --git a/include/v8.h b/include/v8.h
index
00bc3364bb8edbaef662039533c5432c52e6ba56..a7390555d565fe683d5d9001a90cb25b0c05c7f9
100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -2976,10 +2976,18 @@ class V8_EXPORT Map : public Object {
Local<Array> AsArray() const;
/**
- * Creates a new Map.
+ * Creates a new empty Map.
*/
static Local<Map> New(Isolate* isolate);
+ /**
+ * Creates a new Map containing the elements of array, which must be
comprised
+ * of [key, value] arrays.
+ * Guaranteed to be side-effect free if the array contains no holes.
+ */
+ static V8_WARN_UNUSED_RESULT MaybeLocal<Map> FromArray(Local<Context>
context,
+ Local<Array>
array);
+
V8_INLINE static Map* Cast(Value* obj);
private:
@@ -3001,10 +3009,17 @@ class V8_EXPORT Set : public Object {
Local<Array> AsArray() const;
/**
- * Creates a new Set.
+ * Creates a new empty Set.
*/
static Local<Set> New(Isolate* isolate);
+ /**
+ * Creates a new Set containing the items in array.
+ * Guaranteed to be side-effect free if the array contains no holes.
+ */
+ static V8_WARN_UNUSED_RESULT MaybeLocal<Set> FromArray(Local<Context>
context,
+ Local<Array>
array);
+
V8_INLINE static Set* Cast(Value* obj);
private:
Index: src/api.cc
diff --git a/src/api.cc b/src/api.cc
index
d469917be6a9ae6f2924f69ac3240eeed33fff47..147b9f0242e3898def561185eaccbd36a67179d7
100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -6154,6 +6154,19 @@ Local<Array> Map::AsArray() const {
}
+MaybeLocal<Map> Map::FromArray(Local<Context> context, Local<Array> array)
{
+ PREPARE_FOR_EXECUTION(context, "Map::FromArray", Map);
+ i::Handle<i::Object> result;
+ i::Handle<i::Object> argv[] = {Utils::OpenHandle(*array)};
+ has_pending_exception =
+ !i::Execution::Call(isolate, isolate->map_from_array(),
+ isolate->factory()->undefined_value(),
+ arraysize(argv), argv, false).ToHandle(&result);
+ RETURN_ON_FAILED_EXECUTION(Map);
+ RETURN_ESCAPED(Local<Map>::Cast(Utils::ToLocal(result)));
+}
+
+
Local<v8::Set> v8::Set::New(Isolate* isolate) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
LOG_API(i_isolate, "Set::New");
@@ -6190,6 +6203,19 @@ Local<Array> Set::AsArray() const {
}
+MaybeLocal<Set> Set::FromArray(Local<Context> context, Local<Array> array)
{
+ PREPARE_FOR_EXECUTION(context, "Set::FromArray", Set);
+ i::Handle<i::Object> result;
+ i::Handle<i::Object> argv[] = {Utils::OpenHandle(*array)};
+ has_pending_exception =
+ !i::Execution::Call(isolate, isolate->set_from_array(),
+ isolate->factory()->undefined_value(),
+ arraysize(argv), argv, false).ToHandle(&result);
+ RETURN_ON_FAILED_EXECUTION(Set);
+ RETURN_ESCAPED(Local<Set>::Cast(Utils::ToLocal(result)));
+}
+
+
bool Value::IsPromise() const {
auto self = Utils::OpenHandle(this);
return i::Object::IsPromise(self);
Index: src/bootstrapper.cc
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
index
597c1d1a53565f2c4316fb26dc0142d15c3bebdf..e32ce41cf5aef1fb5dfd89c045101c219bfdc837
100644
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -1647,6 +1647,8 @@ void Genesis::InstallNativeFunctions() {
INSTALL_NATIVE(JSFunction, "$observeNativeObjectNotifierPerformChange",
native_object_notifier_perform_change);
INSTALL_NATIVE(JSFunction, "$arrayValues", array_values_iterator);
+ INSTALL_NATIVE(JSFunction, "$mapFromArray", map_from_array);
+ INSTALL_NATIVE(JSFunction, "$setFromArray", set_from_array);
}
Index: src/collection.js
diff --git a/src/collection.js b/src/collection.js
index
eddf0f32655f1ed0be27c2a496c2a803e09d4391..00a14aa77c1347592d0f8481da4c5b0d4b410f6f
100644
--- a/src/collection.js
+++ b/src/collection.js
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+var $mapFromArray;
+var $setFromArray;
+
(function(global, shared, exports) {
"use strict";
@@ -437,4 +440,23 @@ $installFunctions(GlobalMap.prototype, DONT_ENUM, [
"forEach", MapForEach
]);
+$mapFromArray = function(array) {
+ var map = new GlobalMap;
+ var length = array.length;
+ for (var i = 0; i < length; ++i) {
+ var entry = array[i];
+ %_CallFunction(map, entry[0], entry[1], MapSet);
+ }
+ return map;
+}
+
+$setFromArray = function(array) {
+ var set = new GlobalSet;
+ var length = array.length;
+ for (var i = 0; i < length; ++i) {
+ %_CallFunction(set, array[i], SetAdd);
+ }
+ return set;
+}
+
})
Index: src/contexts.h
diff --git a/src/contexts.h b/src/contexts.h
index
b1461f7cd87dd6d930851acc3eb813ebe52a5476..0e7e14a33fb46c44235d7f4d411bb699c7ea7ed6
100644
--- a/src/contexts.h
+++ b/src/contexts.h
@@ -186,6 +186,8 @@ enum BindingFlags {
V(ITERATOR_RESULT_MAP_INDEX, Map,
iterator_result_map) \
V(JS_MAP_MAP_INDEX, Map,
js_map_map) \
V(JS_SET_MAP_INDEX, Map,
js_set_map) \
+ V(MAP_FROM_ARRAY_INDEX, JSFunction,
map_from_array) \
+ V(SET_FROM_ARRAY_INDEX, JSFunction,
set_from_array) \
V(MAP_ITERATOR_MAP_INDEX, Map,
map_iterator_map) \
V(SET_ITERATOR_MAP_INDEX, Map,
set_iterator_map) \
V(ARRAY_VALUES_ITERATOR_INDEX, JSFunction,
array_values_iterator) \
@@ -426,6 +428,8 @@ class Context: public FixedArray {
ITERATOR_RESULT_MAP_INDEX,
JS_MAP_MAP_INDEX,
JS_SET_MAP_INDEX,
+ MAP_FROM_ARRAY_INDEX,
+ SET_FROM_ARRAY_INDEX,
MAP_ITERATOR_MAP_INDEX,
SET_ITERATOR_MAP_INDEX,
ARRAY_VALUES_ITERATOR_INDEX,
Index: test/cctest/test-api.cc
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index
983586071574641910207e932ec88206ed414a84..c4748a11908c5914a341099718da3911f2f8cbe2
100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -21151,6 +21151,9 @@ TEST(Map) {
CHECK_EQ(2, entry->Length());
CHECK_EQ(3, entry->Get(0).As<v8::Int32>()->Value());
CHECK_EQ(4, entry->Get(1).As<v8::Int32>()->Value());
+
+ map = v8::Map::FromArray(env.local(), entries).ToLocalChecked();
+ CHECK_EQ(2, map->Size());
}
@@ -21173,4 +21176,7 @@ TEST(Set) {
CHECK_EQ(2, keys->Length());
CHECK_EQ(1, keys->Get(0).As<v8::Int32>()->Value());
CHECK_EQ(2, keys->Get(1).As<v8::Int32>()->Value());
+
+ set = v8::Set::FromArray(env.local(), keys).ToLocalChecked();
+ CHECK_EQ(2, set->Size());
}
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.