Reviewers: rossberg,

Description:
Fix handling of bogus receivers for Harmony collections.

[email protected]
BUG=v8:1884
TEST=mjsunit/harmony/collections


Please review this at http://codereview.chromium.org/9074003/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files:
  M src/collection.js
  M src/macros.py
  M test/mjsunit/harmony/collections.js


Index: src/collection.js
diff --git a/src/collection.js b/src/collection.js
index d11612681e918c56f7205af23470995eddbf0e5b..fcf4d38d94f80683d276db2efdc6b047cd0aac5e 100644
--- a/src/collection.js
+++ b/src/collection.js
@@ -47,6 +47,10 @@ function SetConstructor() {


 function SetAdd(key) {
+  if (!IS_SET(this)) {
+    throw MakeTypeError('incompatible_method_receiver',
+                        ['Set.prototype.add', this]);
+  }
   if (IS_UNDEFINED(key)) {
     key = undefined_sentinel;
   }
@@ -55,6 +59,10 @@ function SetAdd(key) {


 function SetHas(key) {
+  if (!IS_SET(this)) {
+    throw MakeTypeError('incompatible_method_receiver',
+                        ['Set.prototype.has', this]);
+  }
   if (IS_UNDEFINED(key)) {
     key = undefined_sentinel;
   }
@@ -63,6 +71,10 @@ function SetHas(key) {


 function SetDelete(key) {
+  if (!IS_SET(this)) {
+    throw MakeTypeError('incompatible_method_receiver',
+                        ['Set.prototype.delete', this]);
+  }
   if (IS_UNDEFINED(key)) {
     key = undefined_sentinel;
   }
@@ -80,6 +92,10 @@ function MapConstructor() {


 function MapGet(key) {
+  if (!IS_MAP(this)) {
+    throw MakeTypeError('incompatible_method_receiver',
+                        ['Map.prototype.get', this]);
+  }
   if (IS_UNDEFINED(key)) {
     key = undefined_sentinel;
   }
@@ -88,6 +104,10 @@ function MapGet(key) {


 function MapSet(key, value) {
+  if (!IS_MAP(this)) {
+    throw MakeTypeError('incompatible_method_receiver',
+                        ['Map.prototype.set', this]);
+  }
   if (IS_UNDEFINED(key)) {
     key = undefined_sentinel;
   }
@@ -96,6 +116,10 @@ function MapSet(key, value) {


 function MapHas(key) {
+  if (!IS_MAP(this)) {
+    throw MakeTypeError('incompatible_method_receiver',
+                        ['Map.prototype.has', this]);
+  }
   if (IS_UNDEFINED(key)) {
     key = undefined_sentinel;
   }
@@ -104,6 +128,10 @@ function MapHas(key) {


 function MapDelete(key) {
+  if (!IS_MAP(this)) {
+    throw MakeTypeError('incompatible_method_receiver',
+                        ['Map.prototype.delete', this]);
+  }
   if (IS_UNDEFINED(key)) {
     key = undefined_sentinel;
   }
@@ -126,6 +154,10 @@ function WeakMapConstructor() {


 function WeakMapGet(key) {
+  if (!IS_WEAKMAP(this)) {
+    throw MakeTypeError('incompatible_method_receiver',
+                        ['WeakMap.prototype.get', this]);
+  }
   if (!IS_SPEC_OBJECT(key)) {
     throw %MakeTypeError('invalid_weakmap_key', [this, key]);
   }
@@ -134,6 +166,10 @@ function WeakMapGet(key) {


 function WeakMapSet(key, value) {
+  if (!IS_WEAKMAP(this)) {
+    throw MakeTypeError('incompatible_method_receiver',
+                        ['WeakMap.prototype.set', this]);
+  }
   if (!IS_SPEC_OBJECT(key)) {
     throw %MakeTypeError('invalid_weakmap_key', [this, key]);
   }
@@ -142,6 +178,10 @@ function WeakMapSet(key, value) {


 function WeakMapHas(key) {
+  if (!IS_WEAKMAP(this)) {
+    throw MakeTypeError('incompatible_method_receiver',
+                        ['WeakMap.prototype.has', this]);
+  }
   if (!IS_SPEC_OBJECT(key)) {
     throw %MakeTypeError('invalid_weakmap_key', [this, key]);
   }
@@ -150,6 +190,10 @@ function WeakMapHas(key) {


 function WeakMapDelete(key) {
+  if (!IS_WEAKMAP(this)) {
+    throw MakeTypeError('incompatible_method_receiver',
+                        ['WeakMap.prototype.delete', this]);
+  }
   if (!IS_SPEC_OBJECT(key)) {
     throw %MakeTypeError('invalid_weakmap_key', [this, key]);
   }
Index: src/macros.py
diff --git a/src/macros.py b/src/macros.py
index bf7119feaa9ab2cc71b888265ca039efda5c94f4..34b07ab235172509d51afb4dd676b29eea63bd69 100644
--- a/src/macros.py
+++ b/src/macros.py
@@ -101,6 +101,9 @@ macro IS_OBJECT(arg)            = (%_IsObject(arg));
 macro IS_ARRAY(arg)             = (%_IsArray(arg));
 macro IS_FUNCTION(arg)          = (%_IsFunction(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_NUMBER_WRAPPER(arg)    = (%_ClassOf(arg) === 'Number');
 macro IS_STRING_WRAPPER(arg)    = (%_ClassOf(arg) === 'String');
Index: test/mjsunit/harmony/collections.js
diff --git a/test/mjsunit/harmony/collections.js b/test/mjsunit/harmony/collections.js index 4b435c16141b01c50bb3ca7233b053261d9ef919..52df11f97445a889bc58da658ac112bf33b4bad2 100644
--- a/test/mjsunit/harmony/collections.js
+++ b/test/mjsunit/harmony/collections.js
@@ -274,6 +274,30 @@ var o = Object.create({}, { 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.
+function TestBogusReceivers(func) {
+  assertThrows(function () { func.call(undefined, {}) }, TypeError);
+  assertThrows(function () { func.call(null, {}) }, TypeError);
+  assertThrows(function () { func.call(true, {}) }, TypeError);
+  assertThrows(function () { func.call("x", {}) }, TypeError);
+  assertThrows(function () { func.call(23, {}) }, TypeError);
+  assertThrows(function () { func.call({}, {}) }, TypeError);
+}
+TestBogusReceivers(Set.prototype.add);
+TestBogusReceivers(Set.prototype.has);
+TestBogusReceivers(Set.prototype.delete);
+TestBogusReceivers(Map.prototype.get);
+TestBogusReceivers(Map.prototype.set);
+TestBogusReceivers(Map.prototype.has);
+TestBogusReceivers(Map.prototype.delete);
+TestBogusReceivers(WeakMap.prototype.get);
+TestBogusReceivers(WeakMap.prototype.set);
+TestBogusReceivers(WeakMap.prototype.has);
+TestBogusReceivers(WeakMap.prototype.delete);
+
+
 // Stress Test
 // 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:


--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to