From 9ebc4ea621c8b4c4e0a6d327b66be2824b96ffaf Mon Sep 17 00:00:00 2001 From: Tom Schuster Date: Wed, 10 Feb 2016 00:12:24 +0100 Subject: [PATCH] Bug 1246318 - Remove the enumerate trap from ES6 proxies. r=efaust --- .../source/lib/sdk/preferences/service.js | 3 -- .../tests/proxy/testDirectProxyEnumerate2.js | 16 ------- .../tests/proxy/testDirectProxyEnumerate3.js | 16 ------- .../tests/proxy/testDirectProxyEnumerate4.js | 15 ------ js/src/proxy/ScriptedDirectProxyHandler.cpp | 46 ------------------- js/src/proxy/ScriptedDirectProxyHandler.h | 1 - js/src/tests/ecma_6/Proxy/proxy-for-in.js | 37 +++++++++++++++ .../ecma_6/Proxy/revoke-as-side-effect.js | 10 ---- .../specialpowers/content/specialpowersAPI.js | 7 --- 9 files changed, 37 insertions(+), 114 deletions(-) delete mode 100644 js/src/jit-test/tests/proxy/testDirectProxyEnumerate2.js delete mode 100644 js/src/jit-test/tests/proxy/testDirectProxyEnumerate3.js delete mode 100644 js/src/jit-test/tests/proxy/testDirectProxyEnumerate4.js create mode 100644 js/src/tests/ecma_6/Proxy/proxy-for-in.js diff --git a/addon-sdk/source/lib/sdk/preferences/service.js b/addon-sdk/source/lib/sdk/preferences/service.js index 3e345c3d7f0..231cd8e1405 100644 --- a/addon-sdk/source/lib/sdk/preferences/service.js +++ b/addon-sdk/source/lib/sdk/preferences/service.js @@ -37,9 +37,6 @@ const Branch = function(branchName) { value: this.get(target, name, receiver) }; }, - enumerate(target) { - return branchKeys(branchName)[Symbol.iterator](); - }, ownKeys(target) { return branchKeys(branchName); }, diff --git a/js/src/jit-test/tests/proxy/testDirectProxyEnumerate2.js b/js/src/jit-test/tests/proxy/testDirectProxyEnumerate2.js deleted file mode 100644 index ceec6ff1de3..00000000000 --- a/js/src/jit-test/tests/proxy/testDirectProxyEnumerate2.js +++ /dev/null @@ -1,16 +0,0 @@ -// Throwing [[Enumerate]] handler -load(libdir + "asserts.js"); - -let handler = new Proxy({}, { - get: function(target, name) { - assertEq(name, "enumerate"); - throw new SyntaxError(); - } -}); - -let proxy = new Proxy({}, handler); - -assertThrowsInstanceOf(function() { - for (let x in proxy) - assertEq(true, false); -}, SyntaxError) diff --git a/js/src/jit-test/tests/proxy/testDirectProxyEnumerate3.js b/js/src/jit-test/tests/proxy/testDirectProxyEnumerate3.js deleted file mode 100644 index b74c13f0fa3..00000000000 --- a/js/src/jit-test/tests/proxy/testDirectProxyEnumerate3.js +++ /dev/null @@ -1,16 +0,0 @@ -// Basic [[Enumerate]] functionality test -let inner = []; -let handler = { - enumerate: function(target) { - assertEq(target, inner); - assertEq(arguments.length, 1); - assertEq(this, handler); - return (function*() { yield 'a'; })(); - } -}; - -let x; -for (let y in new Proxy(inner, handler)) { - x = y; -} -assertEq(x, 'a'); diff --git a/js/src/jit-test/tests/proxy/testDirectProxyEnumerate4.js b/js/src/jit-test/tests/proxy/testDirectProxyEnumerate4.js deleted file mode 100644 index dac1545d124..00000000000 --- a/js/src/jit-test/tests/proxy/testDirectProxyEnumerate4.js +++ /dev/null @@ -1,15 +0,0 @@ -// Returning primitive from [[Enumerate]] handler -load(libdir + "asserts.js"); - -let handler = { - enumerate: function() { - return undefined; - } -}; - -let proxy = new Proxy({}, handler); - -assertThrowsInstanceOf(function() { - for (let x in proxy) - assertEq(true, false); -}, TypeError) diff --git a/js/src/proxy/ScriptedDirectProxyHandler.cpp b/js/src/proxy/ScriptedDirectProxyHandler.cpp index 7344882c8d0..d3fb6824e42 100644 --- a/js/src/proxy/ScriptedDirectProxyHandler.cpp +++ b/js/src/proxy/ScriptedDirectProxyHandler.cpp @@ -724,52 +724,6 @@ ScriptedDirectProxyHandler::delete_(JSContext* cx, HandleObject proxy, HandleId return result.succeed(); } -// ES6 (14 October, 2014) 9.5.11 Proxy.[[Enumerate]] -bool -ScriptedDirectProxyHandler::enumerate(JSContext* cx, HandleObject proxy, - MutableHandleObject objp) const -{ - // step 1 - RootedObject handler(cx, GetDirectProxyHandlerObject(proxy)); - - // step 2 - if (!handler) { - JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_PROXY_REVOKED); - return false; - } - - // step 3: unnecessary assert - // step 4 - RootedObject target(cx, proxy->as().target()); - - // step 5-6 - RootedValue trap(cx); - if (!GetProperty(cx, handler, handler, cx->names().enumerate, &trap)) - return false; - - // step 7 - if (trap.isUndefined()) - return GetIterator(cx, target, 0, objp); - - // step 8-9 - Value argv[] = { - ObjectOrNullValue(target) - }; - RootedValue trapResult(cx); - if (!Invoke(cx, ObjectValue(*handler), trap, ArrayLength(argv), argv, &trapResult)) - return false; - - // step 10 - if (trapResult.isPrimitive()) { - ReportInvalidTrapResult(cx, proxy, cx->names().enumerate); - return false; - } - - // step 11 - objp.set(&trapResult.toObject()); - return true; -} - // ES6 (22 May, 2014) 9.5.7 Proxy.[[HasProperty]](P) bool ScriptedDirectProxyHandler::has(JSContext* cx, HandleObject proxy, HandleId id, bool* bp) const diff --git a/js/src/proxy/ScriptedDirectProxyHandler.h b/js/src/proxy/ScriptedDirectProxyHandler.h index 6c3744298da..840827572f8 100644 --- a/js/src/proxy/ScriptedDirectProxyHandler.h +++ b/js/src/proxy/ScriptedDirectProxyHandler.h @@ -28,7 +28,6 @@ class ScriptedDirectProxyHandler : public BaseProxyHandler { AutoIdVector& props) const override; virtual bool delete_(JSContext* cx, HandleObject proxy, HandleId id, ObjectOpResult& result) const override; - virtual bool enumerate(JSContext* cx, HandleObject proxy, MutableHandleObject objp) const override; /* These two are standard internal methods but aren't implemented to spec yet. */ virtual bool getPrototype(JSContext* cx, HandleObject proxy, diff --git a/js/src/tests/ecma_6/Proxy/proxy-for-in.js b/js/src/tests/ecma_6/Proxy/proxy-for-in.js new file mode 100644 index 00000000000..4332bfbbadd --- /dev/null +++ b/js/src/tests/ecma_6/Proxy/proxy-for-in.js @@ -0,0 +1,37 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ +"use strict"; + +let steps = []; + +const object = { + __proto__: { + "xyz": 42 + } +}; +const proxy = new Proxy(object, { + ownKeys(target) { + steps.push("ownKeys") + return ["a", "b"]; + }, + + getOwnPropertyDescriptor(target, property) { + steps.push("getOwn-" + property); + return { + value: undefined, + configurable: true, + writable: true, + enumerable: (property === "a") + }; + } +}); + +let iterated = []; +for (let x in proxy) + iterated.push(x); + +assertEq(iterated.toString(), "a,xyz"); +assertEq(steps.toString(), "ownKeys,getOwn-a,getOwn-b"); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/Proxy/revoke-as-side-effect.js b/js/src/tests/ecma_6/Proxy/revoke-as-side-effect.js index 21f8f8e20d3..25d4c9bf912 100644 --- a/js/src/tests/ecma_6/Proxy/revoke-as-side-effect.js +++ b/js/src/tests/ecma_6/Proxy/revoke-as-side-effect.js @@ -53,16 +53,6 @@ assertThrowsInstanceOf(() => createProxy({a: 5}).a = 0, TypeError); assertEq(delete createProxy({}).a, true); assertEq(delete createProxy(Object.defineProperty({}, "a", {configurable: false})).a, false); -// [[Enumerate]] -for (var k in createProxy({})) { - // No properties in object. - assertEq(true, false); -} -for (var k in createProxy({a: 5})) { - // Properties in object. - assertEq(k, "a"); -} - // [[OwnPropertyKeys]] assertEq(Object.getOwnPropertyNames(createProxy({})).length, 0); assertEq(Object.getOwnPropertyNames(createProxy({a: 5})).length, 1); diff --git a/testing/specialpowers/content/specialpowersAPI.js b/testing/specialpowers/content/specialpowersAPI.js index a8c86ac1637..e255ec360de 100644 --- a/testing/specialpowers/content/specialpowersAPI.js +++ b/testing/specialpowers/content/specialpowersAPI.js @@ -294,13 +294,6 @@ SpecialPowersHandler.prototype = { return props; }, - enumerate(target) { - return (function*() { - for (let property in this.wrappedObject) - yield property; - }).call(this); - }, - preventExtensions(target) { throw "Can't call preventExtensions on SpecialPowers wrapped object"; }