Fix handling of bogus receivers for Harmony collections.

R=rossberg@chromium.org
BUG=v8:1884
TEST=mjsunit/harmony/collections

Review URL: http://codereview.chromium.org/9074003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10342 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 5253363c
...@@ -47,6 +47,10 @@ function SetConstructor() { ...@@ -47,6 +47,10 @@ function SetConstructor() {
function SetAdd(key) { function SetAdd(key) {
if (!IS_SET(this)) {
throw MakeTypeError('incompatible_method_receiver',
['Set.prototype.add', this]);
}
if (IS_UNDEFINED(key)) { if (IS_UNDEFINED(key)) {
key = undefined_sentinel; key = undefined_sentinel;
} }
...@@ -55,6 +59,10 @@ function SetAdd(key) { ...@@ -55,6 +59,10 @@ function SetAdd(key) {
function SetHas(key) { function SetHas(key) {
if (!IS_SET(this)) {
throw MakeTypeError('incompatible_method_receiver',
['Set.prototype.has', this]);
}
if (IS_UNDEFINED(key)) { if (IS_UNDEFINED(key)) {
key = undefined_sentinel; key = undefined_sentinel;
} }
...@@ -63,6 +71,10 @@ function SetHas(key) { ...@@ -63,6 +71,10 @@ function SetHas(key) {
function SetDelete(key) { function SetDelete(key) {
if (!IS_SET(this)) {
throw MakeTypeError('incompatible_method_receiver',
['Set.prototype.delete', this]);
}
if (IS_UNDEFINED(key)) { if (IS_UNDEFINED(key)) {
key = undefined_sentinel; key = undefined_sentinel;
} }
...@@ -80,6 +92,10 @@ function MapConstructor() { ...@@ -80,6 +92,10 @@ function MapConstructor() {
function MapGet(key) { function MapGet(key) {
if (!IS_MAP(this)) {
throw MakeTypeError('incompatible_method_receiver',
['Map.prototype.get', this]);
}
if (IS_UNDEFINED(key)) { if (IS_UNDEFINED(key)) {
key = undefined_sentinel; key = undefined_sentinel;
} }
...@@ -88,6 +104,10 @@ function MapGet(key) { ...@@ -88,6 +104,10 @@ function MapGet(key) {
function MapSet(key, value) { function MapSet(key, value) {
if (!IS_MAP(this)) {
throw MakeTypeError('incompatible_method_receiver',
['Map.prototype.set', this]);
}
if (IS_UNDEFINED(key)) { if (IS_UNDEFINED(key)) {
key = undefined_sentinel; key = undefined_sentinel;
} }
...@@ -96,6 +116,10 @@ function MapSet(key, value) { ...@@ -96,6 +116,10 @@ function MapSet(key, value) {
function MapHas(key) { function MapHas(key) {
if (!IS_MAP(this)) {
throw MakeTypeError('incompatible_method_receiver',
['Map.prototype.has', this]);
}
if (IS_UNDEFINED(key)) { if (IS_UNDEFINED(key)) {
key = undefined_sentinel; key = undefined_sentinel;
} }
...@@ -104,6 +128,10 @@ function MapHas(key) { ...@@ -104,6 +128,10 @@ function MapHas(key) {
function MapDelete(key) { function MapDelete(key) {
if (!IS_MAP(this)) {
throw MakeTypeError('incompatible_method_receiver',
['Map.prototype.delete', this]);
}
if (IS_UNDEFINED(key)) { if (IS_UNDEFINED(key)) {
key = undefined_sentinel; key = undefined_sentinel;
} }
...@@ -126,6 +154,10 @@ function WeakMapConstructor() { ...@@ -126,6 +154,10 @@ function WeakMapConstructor() {
function WeakMapGet(key) { function WeakMapGet(key) {
if (!IS_WEAKMAP(this)) {
throw MakeTypeError('incompatible_method_receiver',
['WeakMap.prototype.get', this]);
}
if (!IS_SPEC_OBJECT(key)) { if (!IS_SPEC_OBJECT(key)) {
throw %MakeTypeError('invalid_weakmap_key', [this, key]); throw %MakeTypeError('invalid_weakmap_key', [this, key]);
} }
...@@ -134,6 +166,10 @@ function WeakMapGet(key) { ...@@ -134,6 +166,10 @@ function WeakMapGet(key) {
function WeakMapSet(key, value) { function WeakMapSet(key, value) {
if (!IS_WEAKMAP(this)) {
throw MakeTypeError('incompatible_method_receiver',
['WeakMap.prototype.set', this]);
}
if (!IS_SPEC_OBJECT(key)) { if (!IS_SPEC_OBJECT(key)) {
throw %MakeTypeError('invalid_weakmap_key', [this, key]); throw %MakeTypeError('invalid_weakmap_key', [this, key]);
} }
...@@ -142,6 +178,10 @@ function WeakMapSet(key, value) { ...@@ -142,6 +178,10 @@ function WeakMapSet(key, value) {
function WeakMapHas(key) { function WeakMapHas(key) {
if (!IS_WEAKMAP(this)) {
throw MakeTypeError('incompatible_method_receiver',
['WeakMap.prototype.has', this]);
}
if (!IS_SPEC_OBJECT(key)) { if (!IS_SPEC_OBJECT(key)) {
throw %MakeTypeError('invalid_weakmap_key', [this, key]); throw %MakeTypeError('invalid_weakmap_key', [this, key]);
} }
...@@ -150,6 +190,10 @@ function WeakMapHas(key) { ...@@ -150,6 +190,10 @@ function WeakMapHas(key) {
function WeakMapDelete(key) { function WeakMapDelete(key) {
if (!IS_WEAKMAP(this)) {
throw MakeTypeError('incompatible_method_receiver',
['WeakMap.prototype.delete', this]);
}
if (!IS_SPEC_OBJECT(key)) { if (!IS_SPEC_OBJECT(key)) {
throw %MakeTypeError('invalid_weakmap_key', [this, key]); throw %MakeTypeError('invalid_weakmap_key', [this, key]);
} }
......
...@@ -101,6 +101,9 @@ macro IS_OBJECT(arg) = (%_IsObject(arg)); ...@@ -101,6 +101,9 @@ macro IS_OBJECT(arg) = (%_IsObject(arg));
macro IS_ARRAY(arg) = (%_IsArray(arg)); macro IS_ARRAY(arg) = (%_IsArray(arg));
macro IS_FUNCTION(arg) = (%_IsFunction(arg)); macro IS_FUNCTION(arg) = (%_IsFunction(arg));
macro IS_REGEXP(arg) = (%_IsRegExp(arg)); macro IS_REGEXP(arg) = (%_IsRegExp(arg));
macro IS_SET(arg) = (%_ClassOf(arg) === 'Set');
macro IS_MAP(arg) = (%_ClassOf(arg) === 'Map');
macro IS_WEAKMAP(arg) = (%_ClassOf(arg) === 'WeakMap');
macro IS_DATE(arg) = (%_ClassOf(arg) === 'Date'); macro IS_DATE(arg) = (%_ClassOf(arg) === 'Date');
macro IS_NUMBER_WRAPPER(arg) = (%_ClassOf(arg) === 'Number'); macro IS_NUMBER_WRAPPER(arg) = (%_ClassOf(arg) === 'Number');
macro IS_STRING_WRAPPER(arg) = (%_ClassOf(arg) === 'String'); macro IS_STRING_WRAPPER(arg) = (%_ClassOf(arg) === 'String');
......
...@@ -274,6 +274,40 @@ var o = Object.create({}, { myValue: { ...@@ -274,6 +274,40 @@ var o = Object.create({}, { myValue: {
assertEquals(10, o.myValue); assertEquals(10, o.myValue);
// Regression test for issue 1884: Invoking any of the methods for Harmony
// maps, sets, or weak maps, with a wrong type of receiver should be throwing
// a proper TypeError.
var alwaysBogus = [ undefined, null, true, "x", 23, {} ];
var bogusReceiversTestSet = [
{ proto: Set.prototype,
funcs: [ 'add', 'has', 'delete' ],
receivers: alwaysBogus.concat([ new Map, new WeakMap ]),
},
{ proto: Map.prototype,
funcs: [ 'get', 'set', 'has', 'delete' ],
receivers: alwaysBogus.concat([ new Set, new WeakMap ]),
},
{ proto: WeakMap.prototype,
funcs: [ 'get', 'set', 'has', 'delete' ],
receivers: alwaysBogus.concat([ new Set, new Map ]),
},
];
function TestBogusReceivers(testSet) {
for (var i = 0; i < testSet.length; i++) {
var proto = testSet[i].proto;
var funcs = testSet[i].funcs;
var receivers = testSet[i].receivers;
for (var j = 0; j < funcs.length; j++) {
var func = proto[funcs[j]];
for (var k = 0; k < receivers.length; k++) {
assertThrows(function () { func.call(receivers[k], {}) }, TypeError);
}
}
}
}
TestBogusReceivers(bogusReceiversTestSet);
// Stress Test // Stress Test
// There is a proposed stress-test available at the es-discuss mailing list // There is a proposed stress-test available at the es-discuss mailing list
// which cannot be reasonably automated. Check it out by hand if you like: // which cannot be reasonably automated. Check it out by hand if you like:
......
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