Adjust key behaviour for weak collections
R=dslomov@chromium.org BUG=460083,v8:3970,v8:3971 LOG=Y Review URL: https://codereview.chromium.org/1018923002 Cr-Commit-Position: refs/heads/master@{#27272}
This commit is contained in:
parent
0880d4da26
commit
7875a89122
@ -42,9 +42,7 @@ function WeakMapGet(key) {
|
|||||||
throw MakeTypeError('incompatible_method_receiver',
|
throw MakeTypeError('incompatible_method_receiver',
|
||||||
['WeakMap.prototype.get', this]);
|
['WeakMap.prototype.get', this]);
|
||||||
}
|
}
|
||||||
if (!(IS_SPEC_OBJECT(key) || IS_SYMBOL(key))) {
|
if (!IS_SPEC_OBJECT(key)) return UNDEFINED;
|
||||||
throw %MakeTypeError('invalid_weakmap_key', [this, key]);
|
|
||||||
}
|
|
||||||
return %WeakCollectionGet(this, key);
|
return %WeakCollectionGet(this, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,7 +52,7 @@ function WeakMapSet(key, value) {
|
|||||||
throw MakeTypeError('incompatible_method_receiver',
|
throw MakeTypeError('incompatible_method_receiver',
|
||||||
['WeakMap.prototype.set', this]);
|
['WeakMap.prototype.set', this]);
|
||||||
}
|
}
|
||||||
if (!(IS_SPEC_OBJECT(key) || IS_SYMBOL(key))) {
|
if (!IS_SPEC_OBJECT(key)) {
|
||||||
throw %MakeTypeError('invalid_weakmap_key', [this, key]);
|
throw %MakeTypeError('invalid_weakmap_key', [this, key]);
|
||||||
}
|
}
|
||||||
return %WeakCollectionSet(this, key, value);
|
return %WeakCollectionSet(this, key, value);
|
||||||
@ -66,9 +64,7 @@ function WeakMapHas(key) {
|
|||||||
throw MakeTypeError('incompatible_method_receiver',
|
throw MakeTypeError('incompatible_method_receiver',
|
||||||
['WeakMap.prototype.has', this]);
|
['WeakMap.prototype.has', this]);
|
||||||
}
|
}
|
||||||
if (!(IS_SPEC_OBJECT(key) || IS_SYMBOL(key))) {
|
if (!IS_SPEC_OBJECT(key)) return false;
|
||||||
throw %MakeTypeError('invalid_weakmap_key', [this, key]);
|
|
||||||
}
|
|
||||||
return %WeakCollectionHas(this, key);
|
return %WeakCollectionHas(this, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,9 +74,7 @@ function WeakMapDelete(key) {
|
|||||||
throw MakeTypeError('incompatible_method_receiver',
|
throw MakeTypeError('incompatible_method_receiver',
|
||||||
['WeakMap.prototype.delete', this]);
|
['WeakMap.prototype.delete', this]);
|
||||||
}
|
}
|
||||||
if (!(IS_SPEC_OBJECT(key) || IS_SYMBOL(key))) {
|
if (!IS_SPEC_OBJECT(key)) return false;
|
||||||
throw %MakeTypeError('invalid_weakmap_key', [this, key]);
|
|
||||||
}
|
|
||||||
return %WeakCollectionDelete(this, key);
|
return %WeakCollectionDelete(this, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,7 +129,7 @@ function WeakSetAdd(value) {
|
|||||||
throw MakeTypeError('incompatible_method_receiver',
|
throw MakeTypeError('incompatible_method_receiver',
|
||||||
['WeakSet.prototype.add', this]);
|
['WeakSet.prototype.add', this]);
|
||||||
}
|
}
|
||||||
if (!(IS_SPEC_OBJECT(value) || IS_SYMBOL(value))) {
|
if (!IS_SPEC_OBJECT(value)) {
|
||||||
throw %MakeTypeError('invalid_weakset_value', [this, value]);
|
throw %MakeTypeError('invalid_weakset_value', [this, value]);
|
||||||
}
|
}
|
||||||
return %WeakCollectionSet(this, value, true);
|
return %WeakCollectionSet(this, value, true);
|
||||||
@ -147,9 +141,7 @@ function WeakSetHas(value) {
|
|||||||
throw MakeTypeError('incompatible_method_receiver',
|
throw MakeTypeError('incompatible_method_receiver',
|
||||||
['WeakSet.prototype.has', this]);
|
['WeakSet.prototype.has', this]);
|
||||||
}
|
}
|
||||||
if (!(IS_SPEC_OBJECT(value) || IS_SYMBOL(value))) {
|
if (!IS_SPEC_OBJECT(value)) return false;
|
||||||
throw %MakeTypeError('invalid_weakset_value', [this, value]);
|
|
||||||
}
|
|
||||||
return %WeakCollectionHas(this, value);
|
return %WeakCollectionHas(this, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,9 +151,7 @@ function WeakSetDelete(value) {
|
|||||||
throw MakeTypeError('incompatible_method_receiver',
|
throw MakeTypeError('incompatible_method_receiver',
|
||||||
['WeakSet.prototype.delete', this]);
|
['WeakSet.prototype.delete', this]);
|
||||||
}
|
}
|
||||||
if (!(IS_SPEC_OBJECT(value) || IS_SYMBOL(value))) {
|
if (!IS_SPEC_OBJECT(value)) return false;
|
||||||
throw %MakeTypeError('invalid_weakset_value', [this, value]);
|
|
||||||
}
|
|
||||||
return %WeakCollectionDelete(this, value);
|
return %WeakCollectionDelete(this, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,6 +51,21 @@ function TestValidMapCalls(m) {
|
|||||||
assertDoesNotThrow(function () { m.set(new Object) });
|
assertDoesNotThrow(function () { m.set(new Object) });
|
||||||
assertDoesNotThrow(function () { m.has(new Object) });
|
assertDoesNotThrow(function () { m.has(new Object) });
|
||||||
assertDoesNotThrow(function () { m.delete(new Object) });
|
assertDoesNotThrow(function () { m.delete(new Object) });
|
||||||
|
assertDoesNotThrow(function () { m.get(undefined) });
|
||||||
|
assertDoesNotThrow(function () { m.get(null) });
|
||||||
|
assertDoesNotThrow(function () { m.get(0) });
|
||||||
|
assertDoesNotThrow(function () { m.get('a-key') });
|
||||||
|
assertDoesNotThrow(function () { m.get(Symbol()) });
|
||||||
|
assertDoesNotThrow(function () { m.has(undefined) });
|
||||||
|
assertDoesNotThrow(function () { m.has(null) });
|
||||||
|
assertDoesNotThrow(function () { m.has(0) });
|
||||||
|
assertDoesNotThrow(function () { m.has('a-key') });
|
||||||
|
assertDoesNotThrow(function () { m.has(Symbol()) });
|
||||||
|
assertDoesNotThrow(function () { m.delete(undefined) });
|
||||||
|
assertDoesNotThrow(function () { m.delete(null) });
|
||||||
|
assertDoesNotThrow(function () { m.delete(0) });
|
||||||
|
assertDoesNotThrow(function () { m.delete('a-key') });
|
||||||
|
assertDoesNotThrow(function () { m.delete(Symbol()) });
|
||||||
}
|
}
|
||||||
TestValidMapCalls(new Map);
|
TestValidMapCalls(new Map);
|
||||||
TestValidMapCalls(new WeakMap);
|
TestValidMapCalls(new WeakMap);
|
||||||
@ -58,14 +73,11 @@ TestValidMapCalls(new WeakMap);
|
|||||||
|
|
||||||
// Test invalid getter and setter calls for WeakMap only
|
// Test invalid getter and setter calls for WeakMap only
|
||||||
function TestInvalidCalls(m) {
|
function TestInvalidCalls(m) {
|
||||||
assertThrows(function () { m.get(undefined) }, TypeError);
|
|
||||||
assertThrows(function () { m.set(undefined, 0) }, TypeError);
|
assertThrows(function () { m.set(undefined, 0) }, TypeError);
|
||||||
assertThrows(function () { m.get(null) }, TypeError);
|
|
||||||
assertThrows(function () { m.set(null, 0) }, TypeError);
|
assertThrows(function () { m.set(null, 0) }, TypeError);
|
||||||
assertThrows(function () { m.get(0) }, TypeError);
|
|
||||||
assertThrows(function () { m.set(0, 0) }, TypeError);
|
assertThrows(function () { m.set(0, 0) }, TypeError);
|
||||||
assertThrows(function () { m.get('a-key') }, TypeError);
|
|
||||||
assertThrows(function () { m.set('a-key', 0) }, TypeError);
|
assertThrows(function () { m.set('a-key', 0) }, TypeError);
|
||||||
|
assertThrows(function () { m.set(Symbol(), 0) }, TypeError);
|
||||||
}
|
}
|
||||||
TestInvalidCalls(new WeakMap);
|
TestInvalidCalls(new WeakMap);
|
||||||
|
|
||||||
@ -73,57 +85,79 @@ TestInvalidCalls(new WeakMap);
|
|||||||
// Test expected behavior for Sets and WeakSets
|
// Test expected behavior for Sets and WeakSets
|
||||||
function TestSet(set, key) {
|
function TestSet(set, key) {
|
||||||
assertFalse(set.has(key));
|
assertFalse(set.has(key));
|
||||||
assertSame(set, set.add(key));
|
assertFalse(set.delete(key));
|
||||||
assertTrue(set.has(key));
|
if (typeof key === 'object' && !(set instanceof WeakSet)) {
|
||||||
assertTrue(set.delete(key));
|
assertSame(set, set.add(key));
|
||||||
|
assertTrue(set.has(key));
|
||||||
|
assertTrue(set.delete(key));
|
||||||
|
}
|
||||||
assertFalse(set.has(key));
|
assertFalse(set.has(key));
|
||||||
assertFalse(set.delete(key));
|
assertFalse(set.delete(key));
|
||||||
assertFalse(set.has(key));
|
assertFalse(set.has(key));
|
||||||
}
|
}
|
||||||
function TestSetBehavior(set) {
|
function TestSetBehavior(set) {
|
||||||
|
// Fill
|
||||||
for (var i = 0; i < 20; i++) {
|
for (var i = 0; i < 20; i++) {
|
||||||
TestSet(set, new Object);
|
TestSet(set, new Object);
|
||||||
TestSet(set, i);
|
TestSet(set, i);
|
||||||
TestSet(set, i / 100);
|
TestSet(set, i / 100);
|
||||||
TestSet(set, 'key-' + i);
|
TestSet(set, 'key-' + i);
|
||||||
|
TestSet(set, Symbol(i));
|
||||||
}
|
}
|
||||||
var keys = [ +0, -0, +Infinity, -Infinity, true, false, null, undefined ];
|
|
||||||
|
var keys = [
|
||||||
|
-0, +0, 1, 1/3, 10, +Infinity, -Infinity, NaN, true, false, null, undefined,
|
||||||
|
'x', Symbol(), {}, function(){}
|
||||||
|
];
|
||||||
for (var i = 0; i < keys.length; i++) {
|
for (var i = 0; i < keys.length; i++) {
|
||||||
TestSet(set, keys[i]);
|
TestSet(set, keys[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TestSetBehavior(new Set);
|
TestSetBehavior(new Set);
|
||||||
TestSet(new WeakSet, new Object);
|
TestSetBehavior(new WeakSet);
|
||||||
|
|
||||||
|
|
||||||
// Test expected mapping behavior for Maps and WeakMaps
|
// Test expected mapping behavior for Maps and WeakMaps
|
||||||
function TestMapping(map, key, value) {
|
function TestMapping(map, key, value) {
|
||||||
assertSame(map, map.set(key, value));
|
assertFalse(map.has(key));
|
||||||
assertSame(value, map.get(key));
|
assertSame(undefined, map.get(key));
|
||||||
|
assertFalse(map.delete(key));
|
||||||
|
if (typeof key === 'object' && !(map instanceof WeakMap)) {
|
||||||
|
assertSame(map, map.set(key, value));
|
||||||
|
assertSame(value, map.get(key));
|
||||||
|
assertTrue(map.has(key));
|
||||||
|
assertTrue(map.delete(key));
|
||||||
|
}
|
||||||
|
assertFalse(map.has(key));
|
||||||
|
assertSame(undefined, map.get(key));
|
||||||
|
assertFalse(map.delete(key));
|
||||||
|
assertFalse(map.has(key));
|
||||||
|
assertSame(undefined, map.get(key));
|
||||||
}
|
}
|
||||||
function TestMapBehavior1(m) {
|
function TestMapBehavior(m) {
|
||||||
|
// Fill
|
||||||
TestMapping(m, new Object, 23);
|
TestMapping(m, new Object, 23);
|
||||||
TestMapping(m, new Object, 'the-value');
|
TestMapping(m, new Object, 'the-value');
|
||||||
TestMapping(m, new Object, new Object);
|
TestMapping(m, new Object, new Object);
|
||||||
}
|
|
||||||
TestMapBehavior1(new Map);
|
|
||||||
TestMapBehavior1(new WeakMap);
|
|
||||||
|
|
||||||
|
|
||||||
// Test expected mapping behavior for Maps only
|
|
||||||
function TestMapBehavior2(m) {
|
|
||||||
for (var i = 0; i < 20; i++) {
|
for (var i = 0; i < 20; i++) {
|
||||||
TestMapping(m, i, new Object);
|
TestMapping(m, i, new Object);
|
||||||
TestMapping(m, i / 10, new Object);
|
TestMapping(m, i / 10, new Object);
|
||||||
TestMapping(m, 'key-' + i, new Object);
|
TestMapping(m, 'key-' + i, new Object);
|
||||||
|
TestMapping(m, Symbol(i), new Object);
|
||||||
}
|
}
|
||||||
// -0 is handled in TestMinusZeroMap
|
|
||||||
var keys = [ 0, +Infinity, -Infinity, true, false, null, undefined ];
|
var keys = [
|
||||||
|
-0, +0, 1, 1/3, 10, +Infinity, -Infinity, NaN, true, false, null, undefined,
|
||||||
|
'x', Symbol(), {}, function(){}
|
||||||
|
];
|
||||||
for (var i = 0; i < keys.length; i++) {
|
for (var i = 0; i < keys.length; i++) {
|
||||||
|
TestMapping(m, keys[i], 23);
|
||||||
|
TestMapping(m, keys[i], 'the-value');
|
||||||
TestMapping(m, keys[i], new Object);
|
TestMapping(m, keys[i], new Object);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TestMapBehavior2(new Map);
|
TestMapBehavior(new Map);
|
||||||
|
TestMapBehavior(new WeakMap);
|
||||||
|
|
||||||
|
|
||||||
// Test expected querying behavior of Maps and WeakMaps
|
// Test expected querying behavior of Maps and WeakMaps
|
||||||
@ -132,8 +166,6 @@ function TestQuery(m) {
|
|||||||
var values = [ 'x', 0, +Infinity, -Infinity, true, false, null, undefined ];
|
var values = [ 'x', 0, +Infinity, -Infinity, true, false, null, undefined ];
|
||||||
for (var i = 0; i < values.length; i++) {
|
for (var i = 0; i < values.length; i++) {
|
||||||
TestMapping(m, key, values[i]);
|
TestMapping(m, key, values[i]);
|
||||||
assertTrue(m.has(key));
|
|
||||||
assertFalse(m.has(new Object));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TestQuery(new Map);
|
TestQuery(new Map);
|
||||||
@ -144,7 +176,6 @@ TestQuery(new WeakMap);
|
|||||||
function TestDelete(m) {
|
function TestDelete(m) {
|
||||||
var key = new Object;
|
var key = new Object;
|
||||||
TestMapping(m, key, 'to-be-deleted');
|
TestMapping(m, key, 'to-be-deleted');
|
||||||
assertTrue(m.delete(key));
|
|
||||||
assertFalse(m.delete(key));
|
assertFalse(m.delete(key));
|
||||||
assertFalse(m.delete(new Object));
|
assertFalse(m.delete(new Object));
|
||||||
assertSame(m.get(key), undefined);
|
assertSame(m.get(key), undefined);
|
||||||
|
@ -245,25 +245,20 @@ TestCall()
|
|||||||
function TestCollections() {
|
function TestCollections() {
|
||||||
var set = new Set
|
var set = new Set
|
||||||
var map = new Map
|
var map = new Map
|
||||||
var weakmap = new WeakMap
|
|
||||||
for (var i in symbols) {
|
for (var i in symbols) {
|
||||||
set.add(symbols[i])
|
set.add(symbols[i])
|
||||||
map.set(symbols[i], i)
|
map.set(symbols[i], i)
|
||||||
weakmap.set(symbols[i], i)
|
|
||||||
}
|
}
|
||||||
assertEquals(symbols.length, set.size)
|
assertEquals(symbols.length, set.size)
|
||||||
assertEquals(symbols.length, map.size)
|
assertEquals(symbols.length, map.size)
|
||||||
for (var i in symbols) {
|
for (var i in symbols) {
|
||||||
assertTrue(set.has(symbols[i]))
|
assertTrue(set.has(symbols[i]))
|
||||||
assertTrue(map.has(symbols[i]))
|
assertTrue(map.has(symbols[i]))
|
||||||
assertTrue(weakmap.has(symbols[i]))
|
|
||||||
assertEquals(i, map.get(symbols[i]))
|
assertEquals(i, map.get(symbols[i]))
|
||||||
assertEquals(i, weakmap.get(symbols[i]))
|
|
||||||
}
|
}
|
||||||
for (var i in symbols) {
|
for (var i in symbols) {
|
||||||
assertTrue(set.delete(symbols[i]))
|
assertTrue(set.delete(symbols[i]))
|
||||||
assertTrue(map.delete(symbols[i]))
|
assertTrue(map.delete(symbols[i]))
|
||||||
assertTrue(weakmap.delete(symbols[i]))
|
|
||||||
}
|
}
|
||||||
assertEquals(0, set.size)
|
assertEquals(0, set.size)
|
||||||
assertEquals(0, map.size)
|
assertEquals(0, map.size)
|
||||||
|
@ -196,25 +196,20 @@ TestSet()
|
|||||||
function TestCollections() {
|
function TestCollections() {
|
||||||
var set = new Set
|
var set = new Set
|
||||||
var map = new Map
|
var map = new Map
|
||||||
var weakmap = new WeakMap
|
|
||||||
for (var i in symbols) {
|
for (var i in symbols) {
|
||||||
set.add(symbols[i])
|
set.add(symbols[i])
|
||||||
map.set(symbols[i], i)
|
map.set(symbols[i], i)
|
||||||
weakmap.set(symbols[i], i)
|
|
||||||
}
|
}
|
||||||
assertEquals(symbols.length, set.size)
|
assertEquals(symbols.length, set.size)
|
||||||
assertEquals(symbols.length, map.size)
|
assertEquals(symbols.length, map.size)
|
||||||
for (var i in symbols) {
|
for (var i in symbols) {
|
||||||
assertTrue(set.has(symbols[i]))
|
assertTrue(set.has(symbols[i]))
|
||||||
assertTrue(map.has(symbols[i]))
|
assertTrue(map.has(symbols[i]))
|
||||||
assertTrue(weakmap.has(symbols[i]))
|
|
||||||
assertEquals(i, map.get(symbols[i]))
|
assertEquals(i, map.get(symbols[i]))
|
||||||
assertEquals(i, weakmap.get(symbols[i]))
|
|
||||||
}
|
}
|
||||||
for (var i in symbols) {
|
for (var i in symbols) {
|
||||||
assertTrue(set.delete(symbols[i]))
|
assertTrue(set.delete(symbols[i]))
|
||||||
assertTrue(map.delete(symbols[i]))
|
assertTrue(map.delete(symbols[i]))
|
||||||
assertTrue(weakmap.delete(symbols[i]))
|
|
||||||
}
|
}
|
||||||
assertEquals(0, set.size)
|
assertEquals(0, set.size)
|
||||||
assertEquals(0, map.size)
|
assertEquals(0, map.size)
|
||||||
|
Loading…
Reference in New Issue
Block a user