Reviewers: adamk, Dmitry Lomov (chromium),
Message:
PTAL
Description:
ES6: Make Map/Set constructors support iterable values
Same for WeakMap/WeakSet
https://bugs.ecmascript.org/show_bug.cgi?id=3111
The change from the reverted version is that LoadIC_Miss now uses Name
instead of String.
BUG=v8:3508
LOG=Y
[email protected],[email protected]
Please review this at https://codereview.chromium.org/464093002/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files (+68, -5 lines):
M src/collection.js
M src/ic.cc
M src/weak_collection.js
M test/mjsunit/es6/collections.js
Index: src/collection.js
diff --git a/src/collection.js b/src/collection.js
index
5e4421eb1072448a186f47eb85f909cb60bdf6bb..20887dd8f7adf5f4ae61c0919c8afbd09469e341
100644
--- a/src/collection.js
+++ b/src/collection.js
@@ -23,7 +23,7 @@ function SetConstructor(iterable) {
var iter, adder;
if (!IS_NULL_OR_UNDEFINED(iterable)) {
- iter = GetIterator(iterable);
+ iter = GetIterator(ToObject(iterable));
adder = this.add;
if (!IS_SPEC_FUNCTION(adder)) {
throw MakeTypeError('property_not_function', ['add', this]);
@@ -147,7 +147,7 @@ function MapConstructor(iterable) {
var iter, adder;
if (!IS_NULL_OR_UNDEFINED(iterable)) {
- iter = GetIterator(iterable);
+ iter = GetIterator(ToObject(iterable));
adder = this.set;
if (!IS_SPEC_FUNCTION(adder)) {
throw MakeTypeError('property_not_function', ['set', this]);
Index: src/ic.cc
diff --git a/src/ic.cc b/src/ic.cc
index
db82bf52388f689c0ce1d12c854a42316c955a16..ea8c368172f4f32421e95e7bb2989b5524dfd3b4
100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -2105,7 +2105,7 @@ RUNTIME_FUNCTION(LoadIC_Miss) {
DCHECK(args.length() == 2);
LoadIC ic(IC::NO_EXTRA_FRAME, isolate);
Handle<Object> receiver = args.at<Object>(0);
- Handle<String> key = args.at<String>(1);
+ Handle<Name> key = args.at<Name>(1);
ic.UpdateState(receiver, key);
Handle<Object> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver,
key));
Index: src/weak_collection.js
diff --git a/src/weak_collection.js b/src/weak_collection.js
index
73dd9de6ba9aa5c48d16596ffde2c015e1764673..1160176d66f6c34b8cf8acb59d0841d832055aae
100644
--- a/src/weak_collection.js
+++ b/src/weak_collection.js
@@ -23,7 +23,7 @@ function WeakMapConstructor(iterable) {
var iter, adder;
if (!IS_NULL_OR_UNDEFINED(iterable)) {
- iter = GetIterator(iterable);
+ iter = GetIterator(ToObject(iterable));
adder = this.set;
if (!IS_SPEC_FUNCTION(adder)) {
throw MakeTypeError('property_not_function', ['set', this]);
@@ -139,7 +139,7 @@ function WeakSetConstructor(iterable) {
var iter, adder;
if (!IS_NULL_OR_UNDEFINED(iterable)) {
- iter = GetIterator(iterable);
+ iter = GetIterator(ToObject(iterable));
adder = this.add;
if (!IS_SPEC_FUNCTION(adder)) {
throw MakeTypeError('property_not_function', ['add', this]);
Index: test/mjsunit/es6/collections.js
diff --git a/test/mjsunit/es6/collections.js
b/test/mjsunit/es6/collections.js
index
c58571950c9545861dfa9d99e8ac25ebde8913d4..911b748ed9de632d7da903f203d744fea2cfaa44
100644
--- a/test/mjsunit/es6/collections.js
+++ b/test/mjsunit/es6/collections.js
@@ -1015,6 +1015,9 @@ function TestSetConstructor(ctor) {
assertThrows(function() {
new ctor({});
}, TypeError);
+ assertThrows(function() {
+ new ctor(true);
+ }, TypeError);
// @@iterator not callable
assertThrows(function() {
@@ -1148,6 +1151,39 @@ TestSetConstructorNextNotAnObject(WeakSet);
})();
+function TestSetConstructorIterableValue(ctor) {
+ 'use strict';
+ // Strict mode is required to prevent implicit wrapping in the getter.
+ Object.defineProperty(Number.prototype, Symbol.iterator, {
+ get: function() {
+ assertEquals('object', typeof this);
+ return function() {
+ return oneAndTwo.keys();
+ };
+ },
+ configurable: true
+ });
+
+ var set = new ctor(42);
+ assertSize(2, set);
+ assertTrue(set.has(k1));
+ assertTrue(set.has(k2));
+
+ delete Number.prototype[Symbol.iterator];
+}
+TestSetConstructorIterableValue(Set);
+TestSetConstructorIterableValue(WeakSet);
+
+
+(function TestSetConstructorStringValue() {
+ var s = new Set('abc');
+ assertSize(3, s);
+ assertTrue(s.has('a'));
+ assertTrue(s.has('b'));
+ assertTrue(s.has('c'));
+})();
+
+
function TestMapConstructor(ctor) {
var m = new ctor(null);
assertSize(0, m);
@@ -1159,6 +1195,9 @@ function TestMapConstructor(ctor) {
assertThrows(function() {
new ctor({});
}, TypeError);
+ assertThrows(function() {
+ new ctor(true);
+ }, TypeError);
// @@iterator not callable
assertThrows(function() {
@@ -1300,3 +1339,27 @@ TestMapConstructorIteratorNotObjectValues(WeakMap);
new WeakMap([[1, 2]])
}, TypeError);
})();
+
+
+function TestMapConstructorIterableValue(ctor) {
+ 'use strict';
+ // Strict mode is required to prevent implicit wrapping in the getter.
+ Object.defineProperty(Number.prototype, Symbol.iterator, {
+ get: function() {
+ assertEquals('object', typeof this);
+ return function() {
+ return oneAndTwo.entries();
+ };
+ },
+ configurable: true
+ });
+
+ var map = new ctor(42);
+ assertSize(2, map);
+ assertEquals(1, map.get(k1));
+ assertEquals(2, map.get(k2));
+
+ delete Number.prototype[Symbol.iterator];
+}
+TestMapConstructorIterableValue(Map);
+TestMapConstructorIterableValue(WeakMap);
--
--
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.