ES6: Map and Set needs to normalize minus zero

BUG=v8:3069
LOG=Y
R=rossberg@chromium.org

Review URL: https://codereview.chromium.org/147143003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18892 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 1e7bbbc9
......@@ -40,6 +40,22 @@ var $WeakSet = global.WeakSet;
// supported internally but required for Harmony sets and maps.
var undefined_sentinel = {};
// Map and Set uses SameValueZero which means that +0 and -0 should be treated
// as the same value.
function NormalizeKey(key) {
if (IS_UNDEFINED(key)) {
return undefined_sentinel;
}
if (key === 0) {
return 0;
}
return key;
}
// -------------------------------------------------------------------
// Harmony Set
......@@ -57,10 +73,7 @@ function SetAdd(key) {
throw MakeTypeError('incompatible_method_receiver',
['Set.prototype.add', this]);
}
if (IS_UNDEFINED(key)) {
key = undefined_sentinel;
}
return %SetAdd(this, key);
return %SetAdd(this, NormalizeKey(key));
}
......@@ -69,10 +82,7 @@ function SetHas(key) {
throw MakeTypeError('incompatible_method_receiver',
['Set.prototype.has', this]);
}
if (IS_UNDEFINED(key)) {
key = undefined_sentinel;
}
return %SetHas(this, key);
return %SetHas(this, NormalizeKey(key));
}
......@@ -81,9 +91,7 @@ function SetDelete(key) {
throw MakeTypeError('incompatible_method_receiver',
['Set.prototype.delete', this]);
}
if (IS_UNDEFINED(key)) {
key = undefined_sentinel;
}
key = NormalizeKey(key);
if (%SetHas(this, key)) {
%SetDelete(this, key);
return true;
......@@ -151,10 +159,7 @@ function MapGet(key) {
throw MakeTypeError('incompatible_method_receiver',
['Map.prototype.get', this]);
}
if (IS_UNDEFINED(key)) {
key = undefined_sentinel;
}
return %MapGet(this, key);
return %MapGet(this, NormalizeKey(key));
}
......@@ -163,10 +168,7 @@ function MapSet(key, value) {
throw MakeTypeError('incompatible_method_receiver',
['Map.prototype.set', this]);
}
if (IS_UNDEFINED(key)) {
key = undefined_sentinel;
}
return %MapSet(this, key, value);
return %MapSet(this, NormalizeKey(key), value);
}
......@@ -175,10 +177,7 @@ function MapHas(key) {
throw MakeTypeError('incompatible_method_receiver',
['Map.prototype.has', this]);
}
if (IS_UNDEFINED(key)) {
key = undefined_sentinel;
}
return %MapHas(this, key);
return %MapHas(this, NormalizeKey(key));
}
......@@ -187,10 +186,7 @@ function MapDelete(key) {
throw MakeTypeError('incompatible_method_receiver',
['Map.prototype.delete', this]);
}
if (IS_UNDEFINED(key)) {
key = undefined_sentinel;
}
return %MapDelete(this, key);
return %MapDelete(this, NormalizeKey(key));
}
......
......@@ -484,3 +484,25 @@ for (var i = 9; i >= 0; i--) {
w.clear();
assertFalse(w.has(k));
})();
(function TestMinusZeroSet() {
var m = new Set();
m.add(0);
m.add(-0);
assertEquals(1, m.size);
assertTrue(m.has(0));
assertTrue(m.has(-0));
})();
(function TestMinusZeroMap() {
var m = new Map();
m.set(0, 'plus');
m.set(-0, 'minus');
assertEquals(1, m.size);
assertTrue(m.has(0));
assertTrue(m.has(-0));
assertEquals('minus', m.get(0));
assertEquals('minus', m.get(-0));
})();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment