Bug 1081978 - Make WeakSet closer to the spec. r=till
authorTom Schuster <evilpies@gmail.com>
Fri, 17 Oct 2014 11:13:41 +0200
changeset 211006 88b3e8b81de8f6a7387d79138c51b02f20580bbe
parent 211005 21ea52a1c31dbdbaa068f790005c2f1f61a73dad
child 211007 5dd335d13677a2124fdbe0db7973987d42bd1abc
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewerstill
bugs1081978
milestone36.0a1
Bug 1081978 - Make WeakSet closer to the spec. r=till
js/src/builtin/WeakSet.js
js/src/jit-test/tests/collections/WeakSet-delete.js
js/src/jit-test/tests/collections/WeakSet-error.js
--- a/js/src/builtin/WeakSet.js
+++ b/js/src/builtin/WeakSet.js
@@ -1,72 +1,85 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // 23.4.3.1
 function WeakSet_add(value) {
-    // Steps 1-4.
+    // Steps 1-3.
     var S = this;
     if (!IsObject(S) || !IsWeakSet(S))
         ThrowError(JSMSG_INCOMPATIBLE_PROTO, "WeakSet", "add", typeof S);
 
+    // Step 4.,6.
+    let entries = UnsafeGetReservedSlot(this, WEAKSET_MAP_SLOT);
+    if (!entries)
+        ThrowError(JSMSG_INCOMPATIBLE_PROTO, "WeakSet", "add", typeof S);
+
     // Step 5.
     if (!IsObject(value))
         ThrowError(JSMSG_NOT_NONNULL_OBJECT);
 
-    // Step 6.
-    let entries = UnsafeGetReservedSlot(this, WEAKSET_MAP_SLOT);
     // Steps 7-8.
     callFunction(std_WeakMap_set, entries, value, true);
 
     // Step 8.
     return S;
 }
 
 // 23.4.3.2
 function WeakSet_clear() {
-    // Step 1-4.
+    // Step 1-3.
     var S = this;
     if (!IsObject(S) || !IsWeakSet(S))
         ThrowError(JSMSG_INCOMPATIBLE_PROTO, "WeakSet", "clear", typeof S);
 
+    // Step 4.
+    let entries = UnsafeGetReservedSlot(this, WEAKSET_MAP_SLOT);
+    if (!entries)
+        ThrowError(JSMSG_INCOMPATIBLE_PROTO, "WeakSet", "clear", typeof S);
+
     // Step 5.
-    let entries = UnsafeGetReservedSlot(this, WEAKSET_MAP_SLOT);
     callFunction(std_WeakMap_clear, entries);
 
     // Step 6.
     return undefined;
 }
 
 // 23.4.3.4
 function WeakSet_delete(value) {
-    // Steps 1-2.
+    // Steps 1-3.
     var S = this;
     if (!IsObject(S) || !IsWeakSet(S))
         ThrowError(JSMSG_INCOMPATIBLE_PROTO, "WeakSet", "delete", typeof S);
 
+    // Step 4.,6.
+    let entries = UnsafeGetReservedSlot(this, WEAKSET_MAP_SLOT);
+    if (!entries)
+        ThrowError(JSMSG_INCOMPATIBLE_PROTO, "WeakSet", "delete", typeof S);
+
     // Step 5.
     if (!IsObject(value))
-        ThrowError(JSMSG_NOT_NONNULL_OBJECT);
+        return false;
 
-    // Step 6.
-    let entries = UnsafeGetReservedSlot(this, WEAKSET_MAP_SLOT);
     // Steps 7-8.
     return callFunction(std_WeakMap_delete, entries, value);
 }
 
 // 23.4.3.5
 function WeakSet_has(value) {
-    // Steps 1-4.
+    // Steps 1-3.
     var S = this;
     if (!IsObject(S) || !IsWeakSet(S))
         ThrowError(JSMSG_INCOMPATIBLE_PROTO, "WeakSet", "has", typeof S);
 
-    // Step 5.
-    if (!IsObject(value))
-        ThrowError(JSMSG_NOT_NONNULL_OBJECT);
+    // Step 4-5.
+    let entries = UnsafeGetReservedSlot(this, WEAKSET_MAP_SLOT);
+    if (!entries)
+        ThrowError(JSMSG_INCOMPATIBLE_PROTO, "WeakSet", "has", typeof S);
 
     // Step 6.
-    let entries = UnsafeGetReservedSlot(this, WEAKSET_MAP_SLOT);
+    if (!IsObject(value))
+        return false;
+
     // Steps 7-8.
     return callFunction(std_WeakMap_has, entries, value);
 }
--- a/js/src/jit-test/tests/collections/WeakSet-delete.js
+++ b/js/src/jit-test/tests/collections/WeakSet-delete.js
@@ -21,8 +21,11 @@ assertEq(ws.has(value), false);
 for (var i = 0; i < 10; i++)
     ws.add({});
 assertEq(ws.add(value), ws);
 assertEq(ws.has(value), true);
 assertEq(ws.delete(value), true);
 assertEq(ws.has(value), false);
 assertEq(ws.delete(value), false);
 assertEq(ws.has(value), false);
+
+// Delete primitive
+assertEq(ws.delete(15), false);
--- a/js/src/jit-test/tests/collections/WeakSet-error.js
+++ b/js/src/jit-test/tests/collections/WeakSet-error.js
@@ -1,25 +1,21 @@
 load(libdir + "asserts.js");
 
-function testMethod(name, hasArg = true) {
+function testMethod(name) {
     var method = WeakSet.prototype[name];
 
     assertThrowsInstanceOf(function() { method.call(1); }, TypeError);
     assertThrowsInstanceOf(function() { method.call({}); }, TypeError);
     assertThrowsInstanceOf(function() { method.call(new WeakMap); }, TypeError);
     assertThrowsInstanceOf(function() { method.call(WeakSet.prototype); }, TypeError);
-
-    if (hasArg) {
-        assertThrowsInstanceOf(function() { method.call(new WeakSet, 1); }, TypeError);
-        assertThrowsInstanceOf(function() { method.call(WeakSet.prototype, 1); }, TypeError);
-    }
 }
 
 testMethod("has");
 testMethod("add");
 testMethod("delete");
-testMethod("clear", false);
+testMethod("clear");
 
+assertThrowsInstanceOf(function() { var ws = new WeakSet(); ws.add(1); }, TypeError);
 assertThrowsInstanceOf(function() { new WeakSet({"@@iterator": 2}) }, TypeError);
 assertEq(typeof []["@@iterator"], "function"); // Make sure we fail when @@iterator is removed
 
 assertThrowsInstanceOf(function() { WeakSet(); }, TypeError);