diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index f2117121efb3..58ab80995337 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -620,8 +620,6 @@ public: virtual bool delete_(JSContext *cx, JS::Handle proxy, JS::Handle id, bool *bp) const MOZ_OVERRIDE; - virtual bool enumerate(JSContext *cx, JS::Handle proxy, - JS::AutoIdVector &props) const MOZ_OVERRIDE; virtual bool preventExtensions(JSContext *cx, JS::Handle proxy, bool *succeeded) const MOZ_OVERRIDE; @@ -649,6 +647,8 @@ public: JS::Handle id, bool *bp) const MOZ_OVERRIDE; virtual bool getOwnEnumerablePropertyKeys(JSContext *cx, JS::Handle proxy, JS::AutoIdVector &props) const MOZ_OVERRIDE; + virtual bool getEnumerablePropertyKeys(JSContext *cx, JS::Handle proxy, + JS::AutoIdVector &props) const MOZ_OVERRIDE; virtual bool iterate(JSContext *cx, JS::Handle proxy, unsigned flags, JS::MutableHandle vp) const MOZ_OVERRIDE; @@ -829,22 +829,6 @@ nsOuterWindowProxy::delete_(JSContext *cx, JS::Handle proxy, return js::Wrapper::delete_(cx, proxy, id, bp); } -bool -nsOuterWindowProxy::enumerate(JSContext *cx, JS::Handle proxy, - JS::AutoIdVector &props) const -{ - // Just our indexed stuff followed by our "normal" own property names. - if (!AppendIndexedPropertyNames(cx, proxy, props)) { - return false; - } - - JS::AutoIdVector innerProps(cx); - if (!js::Wrapper::enumerate(cx, proxy, innerProps)) { - return false; - } - return js::AppendUnique(cx, props, innerProps); -} - bool nsOuterWindowProxy::preventExtensions(JSContext *cx, JS::Handle proxy, @@ -942,6 +926,23 @@ nsOuterWindowProxy::getOwnEnumerablePropertyKeys(JSContext *cx, JS::Handle proxy, + JS::AutoIdVector &props) const +{ + // Just our indexed stuff followed by our "normal" own property names. + if (!AppendIndexedPropertyNames(cx, proxy, props)) { + return false; + } + + JS::AutoIdVector innerProps(cx); + if (!js::Wrapper::getEnumerablePropertyKeys(cx, proxy, innerProps)) { + return false; + } + return js::AppendUnique(cx, props, innerProps); +} + + bool nsOuterWindowProxy::iterate(JSContext *cx, JS::Handle proxy, unsigned flags, JS::MutableHandle vp) const diff --git a/dom/bindings/DOMJSProxyHandler.cpp b/dom/bindings/DOMJSProxyHandler.cpp index 8327b516abed..4c424c445615 100644 --- a/dom/bindings/DOMJSProxyHandler.cpp +++ b/dom/bindings/DOMJSProxyHandler.cpp @@ -267,18 +267,6 @@ DOMProxyHandler::delete_(JSContext* cx, JS::Handle proxy, return true; } -bool -BaseDOMProxyHandler::enumerate(JSContext* cx, JS::Handle proxy, - AutoIdVector& props) const -{ - JS::Rooted proto(cx); - if (!JS_GetPrototype(cx, proxy, &proto)) { - return false; - } - return getOwnEnumerablePropertyKeys(cx, proxy, props) && - (!proto || js::GetPropertyKeys(cx, proto, 0, &props)); -} - bool BaseDOMProxyHandler::watch(JSContext* cx, JS::Handle proxy, JS::Handle id, JS::Handle callable) const @@ -308,6 +296,19 @@ BaseDOMProxyHandler::getOwnEnumerablePropertyKeys(JSContext* cx, return ownPropNames(cx, proxy, JSITER_OWNONLY, props); } +bool +BaseDOMProxyHandler::getEnumerablePropertyKeys(JSContext* cx, + JS::Handle proxy, + AutoIdVector& props) const +{ + JS::Rooted proto(cx); + if (!JS_GetPrototype(cx, proxy, &proto)) { + return false; + } + return getOwnEnumerablePropertyKeys(cx, proxy, props) && + (!proto || js::GetPropertyKeys(cx, proto, 0, &props)); +} + bool DOMProxyHandler::has(JSContext* cx, JS::Handle proxy, JS::Handle id, bool* bp) const { diff --git a/dom/bindings/DOMJSProxyHandler.h b/dom/bindings/DOMJSProxyHandler.h index 524970c9155a..4709ab18f73e 100644 --- a/dom/bindings/DOMJSProxyHandler.h +++ b/dom/bindings/DOMJSProxyHandler.h @@ -57,8 +57,6 @@ public: JS::MutableHandle desc) const MOZ_OVERRIDE; virtual bool ownPropertyKeys(JSContext* cx, JS::Handle proxy, JS::AutoIdVector &props) const MOZ_OVERRIDE; - bool enumerate(JSContext* cx, JS::Handle proxy, - JS::AutoIdVector& props) const MOZ_OVERRIDE; bool getPropertyDescriptor(JSContext* cx, JS::Handle proxy, JS::Handle id, @@ -71,6 +69,8 @@ public: // unnecessary work during enumeration. virtual bool getOwnEnumerablePropertyKeys(JSContext* cx, JS::Handle proxy, JS::AutoIdVector &props) const MOZ_OVERRIDE; + bool getEnumerablePropertyKeys(JSContext* cx, JS::Handle proxy, + JS::AutoIdVector& props) const MOZ_OVERRIDE; bool watch(JSContext* cx, JS::Handle proxy, JS::Handle id, JS::Handle callable) const MOZ_OVERRIDE; diff --git a/js/ipc/WrapperOwner.cpp b/js/ipc/WrapperOwner.cpp index f67a8d435958..74b712325018 100644 --- a/js/ipc/WrapperOwner.cpp +++ b/js/ipc/WrapperOwner.cpp @@ -93,7 +93,6 @@ class CPOWProxyHandler : public BaseProxyHandler virtual bool ownPropertyKeys(JSContext *cx, HandleObject proxy, AutoIdVector &props) const MOZ_OVERRIDE; virtual bool delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const MOZ_OVERRIDE; - virtual bool enumerate(JSContext *cx, HandleObject proxy, AutoIdVector &props) const MOZ_OVERRIDE; virtual bool preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded) const MOZ_OVERRIDE; virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) const MOZ_OVERRIDE; virtual bool has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const MOZ_OVERRIDE; @@ -109,6 +108,8 @@ class CPOWProxyHandler : public BaseProxyHandler virtual bool hasOwn(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const MOZ_OVERRIDE; virtual bool getOwnEnumerablePropertyKeys(JSContext *cx, HandleObject proxy, AutoIdVector &props) const MOZ_OVERRIDE; + virtual bool getEnumerablePropertyKeys(JSContext *cx, HandleObject proxy, + AutoIdVector &props) const MOZ_OVERRIDE; virtual bool hasInstance(JSContext *cx, HandleObject proxy, MutableHandleValue v, bool *bp) const MOZ_OVERRIDE; virtual bool objectClassIs(HandleObject obj, js::ESClassValue classValue, @@ -262,18 +263,6 @@ WrapperOwner::delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) return ok(cx, status); } -bool -CPOWProxyHandler::enumerate(JSContext *cx, HandleObject proxy, AutoIdVector &props) const -{ - FORWARD(enumerate, (cx, proxy, props)); -} - -bool -WrapperOwner::enumerate(JSContext *cx, HandleObject proxy, AutoIdVector &props) -{ - return getPropertyKeys(cx, proxy, 0, props); -} - bool CPOWProxyHandler::has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const { @@ -478,6 +467,18 @@ WrapperOwner::getOwnEnumerablePropertyKeys(JSContext *cx, HandleObject proxy, Au return getPropertyKeys(cx, proxy, JSITER_OWNONLY, props); } +bool +CPOWProxyHandler::getEnumerablePropertyKeys(JSContext *cx, HandleObject proxy, AutoIdVector &props) const +{ + FORWARD(getEnumerablePropertyKeys, (cx, proxy, props)); +} + +bool +WrapperOwner::getEnumerablePropertyKeys(JSContext *cx, HandleObject proxy, AutoIdVector &props) +{ + return getPropertyKeys(cx, proxy, 0, props); +} + bool CPOWProxyHandler::preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded) const { diff --git a/js/ipc/WrapperOwner.h b/js/ipc/WrapperOwner.h index 8c51f218c936..18f8b9939bae 100644 --- a/js/ipc/WrapperOwner.h +++ b/js/ipc/WrapperOwner.h @@ -39,7 +39,6 @@ class WrapperOwner : public virtual JavaScriptShared JS::MutableHandle desc); bool ownPropertyKeys(JSContext *cx, JS::HandleObject proxy, JS::AutoIdVector &props); bool delete_(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, bool *bp); - bool enumerate(JSContext *cx, JS::HandleObject proxy, JS::AutoIdVector &props); bool preventExtensions(JSContext *cx, JS::HandleObject proxy, bool *succeeded); bool isExtensible(JSContext *cx, JS::HandleObject proxy, bool *extensible); bool has(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, bool *bp); @@ -56,6 +55,8 @@ class WrapperOwner : public virtual JavaScriptShared bool hasOwn(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, bool *bp); bool getOwnEnumerablePropertyKeys(JSContext *cx, JS::HandleObject proxy, JS::AutoIdVector &props); + bool getEnumerablePropertyKeys(JSContext *cx, JS::HandleObject proxy, + JS::AutoIdVector &props); // We use "iterate" provided by the base class here. bool hasInstance(JSContext *cx, JS::HandleObject proxy, JS::MutableHandleValue v, bool *bp); bool objectClassIs(JSContext *cx, JS::HandleObject obj, js::ESClassValue classValue); diff --git a/js/src/jsiter.cpp b/js/src/jsiter.cpp index e32c642e26d4..ba1caf79e3ee 100644 --- a/js/src/jsiter.cpp +++ b/js/src/jsiter.cpp @@ -305,7 +305,7 @@ Snapshot(JSContext *cx, HandleObject pobj_, unsigned flags, AutoIdVector *props) return false; } } else { - if (!Proxy::enumerate(cx, pobj, proxyProps)) + if (!Proxy::getEnumerablePropertyKeys(cx, pobj, proxyProps)) return false; } diff --git a/js/src/jsproxy.h b/js/src/jsproxy.h index 2d122385609d..7ac34cff5c35 100644 --- a/js/src/jsproxy.h +++ b/js/src/jsproxy.h @@ -255,7 +255,6 @@ class JS_FRIEND_API(BaseProxyHandler) virtual bool ownPropertyKeys(JSContext *cx, HandleObject proxy, AutoIdVector &props) const = 0; virtual bool delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const = 0; - virtual bool enumerate(JSContext *cx, HandleObject proxy, AutoIdVector &props) const = 0; /* * These methods are standard, but the engine does not normally call them. @@ -306,6 +305,8 @@ class JS_FRIEND_API(BaseProxyHandler) virtual bool hasOwn(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const; virtual bool getOwnEnumerablePropertyKeys(JSContext *cx, HandleObject proxy, AutoIdVector &props) const; + virtual bool getEnumerablePropertyKeys(JSContext *cx, HandleObject proxy, + AutoIdVector &props) const = 0; virtual bool iterate(JSContext *cx, HandleObject proxy, unsigned flags, MutableHandleValue vp) const; virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, CallArgs args) const; @@ -367,8 +368,6 @@ class JS_PUBLIC_API(DirectProxyHandler) : public BaseProxyHandler AutoIdVector &props) const MOZ_OVERRIDE; virtual bool delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const MOZ_OVERRIDE; - virtual bool enumerate(JSContext *cx, HandleObject proxy, - AutoIdVector &props) const MOZ_OVERRIDE; virtual bool getPrototypeOf(JSContext *cx, HandleObject proxy, MutableHandleObject protop) const MOZ_OVERRIDE; virtual bool setPrototypeOf(JSContext *cx, HandleObject proxy, HandleObject proto, @@ -393,6 +392,8 @@ class JS_PUBLIC_API(DirectProxyHandler) : public BaseProxyHandler bool *bp) const MOZ_OVERRIDE; virtual bool getOwnEnumerablePropertyKeys(JSContext *cx, HandleObject proxy, AutoIdVector &props) const MOZ_OVERRIDE; + virtual bool getEnumerablePropertyKeys(JSContext *cx, HandleObject proxy, + AutoIdVector &props) const MOZ_OVERRIDE; virtual bool iterate(JSContext *cx, HandleObject proxy, unsigned flags, MutableHandleValue vp) const MOZ_OVERRIDE; virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, diff --git a/js/src/jswrapper.h b/js/src/jswrapper.h index f250f03b69f2..47c41d45884e 100644 --- a/js/src/jswrapper.h +++ b/js/src/jswrapper.h @@ -121,7 +121,6 @@ class JS_FRIEND_API(CrossCompartmentWrapper) : public Wrapper virtual bool ownPropertyKeys(JSContext *cx, HandleObject wrapper, AutoIdVector &props) const MOZ_OVERRIDE; virtual bool delete_(JSContext *cx, HandleObject wrapper, HandleId id, bool *bp) const MOZ_OVERRIDE; - virtual bool enumerate(JSContext *cx, HandleObject wrapper, AutoIdVector &props) const MOZ_OVERRIDE; virtual bool getPrototypeOf(JSContext *cx, HandleObject proxy, MutableHandleObject protop) const MOZ_OVERRIDE; virtual bool setPrototypeOf(JSContext *cx, HandleObject proxy, HandleObject proto, @@ -144,6 +143,8 @@ class JS_FRIEND_API(CrossCompartmentWrapper) : public Wrapper virtual bool hasOwn(JSContext *cx, HandleObject wrapper, HandleId id, bool *bp) const MOZ_OVERRIDE; virtual bool getOwnEnumerablePropertyKeys(JSContext *cx, HandleObject wrapper, AutoIdVector &props) const MOZ_OVERRIDE; + virtual bool getEnumerablePropertyKeys(JSContext *cx, HandleObject wrapper, + AutoIdVector &props) const MOZ_OVERRIDE; virtual bool iterate(JSContext *cx, HandleObject wrapper, unsigned flags, MutableHandleValue vp) const MOZ_OVERRIDE; virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, diff --git a/js/src/proxy/BaseProxyHandler.cpp b/js/src/proxy/BaseProxyHandler.cpp index 403e5f856f01..d218e90cc571 100644 --- a/js/src/proxy/BaseProxyHandler.cpp +++ b/js/src/proxy/BaseProxyHandler.cpp @@ -205,7 +205,7 @@ BaseProxyHandler::iterate(JSContext *cx, HandleObject proxy, unsigned flags, AutoIdVector props(cx); if ((flags & JSITER_OWNONLY) ? !getOwnEnumerablePropertyKeys(cx, proxy, props) - : !enumerate(cx, proxy, props)) { + : !getEnumerablePropertyKeys(cx, proxy, props)) { return false; } diff --git a/js/src/proxy/CrossCompartmentWrapper.cpp b/js/src/proxy/CrossCompartmentWrapper.cpp index 02ba513ba365..8254abecf518 100644 --- a/js/src/proxy/CrossCompartmentWrapper.cpp +++ b/js/src/proxy/CrossCompartmentWrapper.cpp @@ -77,15 +77,6 @@ CrossCompartmentWrapper::delete_(JSContext *cx, HandleObject wrapper, HandleId i NOTHING); } -bool -CrossCompartmentWrapper::enumerate(JSContext *cx, HandleObject wrapper, AutoIdVector &props) const -{ - PIERCE(cx, wrapper, - NOTHING, - Wrapper::enumerate(cx, wrapper, props), - NOTHING); -} - bool CrossCompartmentWrapper::getPrototypeOf(JSContext *cx, HandleObject wrapper, MutableHandleObject protop) const @@ -197,6 +188,16 @@ CrossCompartmentWrapper::getOwnEnumerablePropertyKeys(JSContext *cx, HandleObjec NOTHING); } +bool +CrossCompartmentWrapper::getEnumerablePropertyKeys(JSContext *cx, HandleObject wrapper, + AutoIdVector &props) const +{ + PIERCE(cx, wrapper, + NOTHING, + Wrapper::getEnumerablePropertyKeys(cx, wrapper, props), + NOTHING); +} + /* * We can reify non-escaping iterator objects instead of having to wrap them. This * allows fast iteration over objects across a compartment boundary. diff --git a/js/src/proxy/DeadObjectProxy.cpp b/js/src/proxy/DeadObjectProxy.cpp index 697f71fc5099..3e98f938de9a 100644 --- a/js/src/proxy/DeadObjectProxy.cpp +++ b/js/src/proxy/DeadObjectProxy.cpp @@ -54,7 +54,8 @@ DeadObjectProxy::delete_(JSContext *cx, HandleObject wrapper, HandleId id, bool } bool -DeadObjectProxy::enumerate(JSContext *cx, HandleObject wrapper, AutoIdVector &props) const +DeadObjectProxy::getEnumerablePropertyKeys(JSContext *cx, HandleObject wrapper, + AutoIdVector &props) const { JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_DEAD_OBJECT); return false; diff --git a/js/src/proxy/DeadObjectProxy.h b/js/src/proxy/DeadObjectProxy.h index ae477841ac82..2eeaf60937f7 100644 --- a/js/src/proxy/DeadObjectProxy.h +++ b/js/src/proxy/DeadObjectProxy.h @@ -26,7 +26,6 @@ class DeadObjectProxy : public BaseProxyHandler virtual bool ownPropertyKeys(JSContext *cx, HandleObject wrapper, AutoIdVector &props) const MOZ_OVERRIDE; virtual bool delete_(JSContext *cx, HandleObject wrapper, HandleId id, bool *bp) const MOZ_OVERRIDE; - virtual bool enumerate(JSContext *cx, HandleObject wrapper, AutoIdVector &props) const MOZ_OVERRIDE; virtual bool getPrototypeOf(JSContext *cx, HandleObject proxy, MutableHandleObject protop) const MOZ_OVERRIDE; virtual bool preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded) const MOZ_OVERRIDE; @@ -37,6 +36,8 @@ class DeadObjectProxy : public BaseProxyHandler /* SpiderMonkey extensions. */ virtual bool getPropertyDescriptor(JSContext *cx, HandleObject wrapper, HandleId id, MutableHandle desc) const MOZ_OVERRIDE; + virtual bool getEnumerablePropertyKeys(JSContext *cx, HandleObject wrapper, + AutoIdVector &props) const MOZ_OVERRIDE; virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, CallArgs args) const MOZ_OVERRIDE; virtual bool hasInstance(JSContext *cx, HandleObject proxy, MutableHandleValue v, diff --git a/js/src/proxy/DirectProxyHandler.cpp b/js/src/proxy/DirectProxyHandler.cpp index 9a292dd1445f..30106bb0294c 100644 --- a/js/src/proxy/DirectProxyHandler.cpp +++ b/js/src/proxy/DirectProxyHandler.cpp @@ -67,16 +67,6 @@ DirectProxyHandler::delete_(JSContext *cx, HandleObject proxy, HandleId id, bool return JSObject::deleteGeneric(cx, target, id, bp); } -bool -DirectProxyHandler::enumerate(JSContext *cx, HandleObject proxy, - AutoIdVector &props) const -{ - assertEnteredPolicy(cx, proxy, JSID_VOID, ENUMERATE); - MOZ_ASSERT(!hasPrototype()); // Should never be called if there's a prototype. - RootedObject target(cx, proxy->as().target()); - return GetPropertyKeys(cx, target, 0, &props); -} - bool DirectProxyHandler::call(JSContext *cx, HandleObject proxy, const CallArgs &args) const { @@ -252,6 +242,16 @@ DirectProxyHandler::getOwnEnumerablePropertyKeys(JSContext *cx, HandleObject pro return GetPropertyKeys(cx, target, JSITER_OWNONLY, &props); } +bool +DirectProxyHandler::getEnumerablePropertyKeys(JSContext *cx, HandleObject proxy, + AutoIdVector &props) const +{ + assertEnteredPolicy(cx, proxy, JSID_VOID, ENUMERATE); + MOZ_ASSERT(!hasPrototype()); // Should never be called if there's a prototype. + RootedObject target(cx, proxy->as().target()); + return GetPropertyKeys(cx, target, 0, &props); +} + bool DirectProxyHandler::iterate(JSContext *cx, HandleObject proxy, unsigned flags, MutableHandleValue vp) const diff --git a/js/src/proxy/Proxy.cpp b/js/src/proxy/Proxy.cpp index 505740fde96a..5e0781792d96 100644 --- a/js/src/proxy/Proxy.cpp +++ b/js/src/proxy/Proxy.cpp @@ -206,24 +206,6 @@ js::AppendUnique(JSContext *cx, AutoIdVector &base, AutoIdVector &others) return base.appendAll(uniqueOthers); } -bool -Proxy::enumerate(JSContext *cx, HandleObject proxy, AutoIdVector &props) -{ - JS_CHECK_RECURSION(cx, return false); - const BaseProxyHandler *handler = proxy->as().handler(); - AutoEnterPolicy policy(cx, handler, proxy, JSID_VOIDHANDLE, BaseProxyHandler::ENUMERATE, true); - if (!policy.allowed()) - return policy.returnValue(); - if (!handler->hasPrototype()) - return proxy->as().handler()->enumerate(cx, proxy, props); - if (!handler->getOwnEnumerablePropertyKeys(cx, proxy, props)) - return false; - AutoIdVector protoProps(cx); - INVOKE_ON_PROTOTYPE(cx, handler, proxy, - GetPropertyKeys(cx, proto, 0, &protoProps) && - AppendUnique(cx, props, protoProps)); -} - /* static */ bool Proxy::getPrototypeOf(JSContext *cx, HandleObject proxy, MutableHandleObject proto) { @@ -384,6 +366,24 @@ Proxy::getOwnEnumerablePropertyKeys(JSContext *cx, HandleObject proxy, AutoIdVec return handler->getOwnEnumerablePropertyKeys(cx, proxy, props); } +bool +Proxy::getEnumerablePropertyKeys(JSContext *cx, HandleObject proxy, AutoIdVector &props) +{ + JS_CHECK_RECURSION(cx, return false); + const BaseProxyHandler *handler = proxy->as().handler(); + AutoEnterPolicy policy(cx, handler, proxy, JSID_VOIDHANDLE, BaseProxyHandler::ENUMERATE, true); + if (!policy.allowed()) + return policy.returnValue(); + if (!handler->hasPrototype()) + return proxy->as().handler()->getEnumerablePropertyKeys(cx, proxy, props); + if (!handler->getOwnEnumerablePropertyKeys(cx, proxy, props)) + return false; + AutoIdVector protoProps(cx); + INVOKE_ON_PROTOTYPE(cx, handler, proxy, + GetPropertyKeys(cx, proto, 0, &protoProps) && + AppendUnique(cx, props, protoProps)); +} + bool Proxy::iterate(JSContext *cx, HandleObject proxy, unsigned flags, MutableHandleValue vp) { @@ -406,7 +406,7 @@ Proxy::iterate(JSContext *cx, HandleObject proxy, unsigned flags, MutableHandleV // The other Proxy::foo methods do the prototype-aware work for us here. if ((flags & JSITER_OWNONLY) ? !Proxy::getOwnEnumerablePropertyKeys(cx, proxy, props) - : !Proxy::enumerate(cx, proxy, props)) { + : !Proxy::getEnumerablePropertyKeys(cx, proxy, props)) { return false; } return EnumeratedIdVectorToIterator(cx, proxy, flags, props, vp); diff --git a/js/src/proxy/Proxy.h b/js/src/proxy/Proxy.h index c634a040a5fb..a48e62ebba3f 100644 --- a/js/src/proxy/Proxy.h +++ b/js/src/proxy/Proxy.h @@ -34,7 +34,6 @@ class Proxy MutableHandle desc); static bool ownPropertyKeys(JSContext *cx, HandleObject proxy, AutoIdVector &props); static bool delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp); - static bool enumerate(JSContext *cx, HandleObject proxy, AutoIdVector &props); static bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible); static bool preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded); static bool getPrototypeOf(JSContext *cx, HandleObject proxy, MutableHandleObject protop); @@ -56,6 +55,7 @@ class Proxy static bool hasOwn(JSContext *cx, HandleObject proxy, HandleId id, bool *bp); static bool getOwnEnumerablePropertyKeys(JSContext *cx, HandleObject proxy, AutoIdVector &props); + static bool getEnumerablePropertyKeys(JSContext *cx, HandleObject proxy, AutoIdVector &props); static bool iterate(JSContext *cx, HandleObject proxy, unsigned flags, MutableHandleValue vp); static bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, CallArgs args); static bool hasInstance(JSContext *cx, HandleObject proxy, MutableHandleValue v, bool *bp); diff --git a/js/src/proxy/ScriptedDirectProxyHandler.cpp b/js/src/proxy/ScriptedDirectProxyHandler.cpp index 1cd2bc4003d8..ab0fe134e3f0 100644 --- a/js/src/proxy/ScriptedDirectProxyHandler.cpp +++ b/js/src/proxy/ScriptedDirectProxyHandler.cpp @@ -761,7 +761,7 @@ ScriptedDirectProxyHandler::delete_(JSContext *cx, HandleObject proxy, HandleId // ES6 (22 May, 2014) 9.5.11 Proxy.[[Enumerate]] bool -ScriptedDirectProxyHandler::enumerate(JSContext *cx, HandleObject proxy, AutoIdVector &props) const +ScriptedDirectProxyHandler::getEnumerablePropertyKeys(JSContext *cx, HandleObject proxy, AutoIdVector &props) const { // step 1 RootedObject handler(cx, GetDirectProxyHandlerObject(proxy)); @@ -782,7 +782,7 @@ ScriptedDirectProxyHandler::enumerate(JSContext *cx, HandleObject proxy, AutoIdV // step 6 if (trap.isUndefined()) - return DirectProxyHandler::enumerate(cx, proxy, props); + return DirectProxyHandler::getEnumerablePropertyKeys(cx, proxy, props); // step 7-8 Value argv[] = { diff --git a/js/src/proxy/ScriptedDirectProxyHandler.h b/js/src/proxy/ScriptedDirectProxyHandler.h index ff36bca7984f..8ce2194a55a9 100644 --- a/js/src/proxy/ScriptedDirectProxyHandler.h +++ b/js/src/proxy/ScriptedDirectProxyHandler.h @@ -26,7 +26,6 @@ class ScriptedDirectProxyHandler : public DirectProxyHandler { virtual bool ownPropertyKeys(JSContext *cx, HandleObject proxy, AutoIdVector &props) const MOZ_OVERRIDE; virtual bool delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const MOZ_OVERRIDE; - virtual bool enumerate(JSContext *cx, HandleObject proxy, AutoIdVector &props) const MOZ_OVERRIDE; /* These two are standard internal methods but aren't implemented to spec yet. */ virtual bool getPrototypeOf(JSContext *cx, HandleObject proxy, @@ -63,6 +62,8 @@ class ScriptedDirectProxyHandler : public DirectProxyHandler { AutoIdVector &props) const MOZ_OVERRIDE { return BaseProxyHandler::getOwnEnumerablePropertyKeys(cx, proxy, props); } + virtual bool getEnumerablePropertyKeys(JSContext *cx, HandleObject proxy, + AutoIdVector &props) const MOZ_OVERRIDE; virtual bool iterate(JSContext *cx, HandleObject proxy, unsigned flags, MutableHandleValue vp) const MOZ_OVERRIDE; diff --git a/js/src/proxy/ScriptedIndirectProxyHandler.cpp b/js/src/proxy/ScriptedIndirectProxyHandler.cpp index d09050dfdb0f..43d9d1293b39 100644 --- a/js/src/proxy/ScriptedIndirectProxyHandler.cpp +++ b/js/src/proxy/ScriptedIndirectProxyHandler.cpp @@ -226,16 +226,6 @@ ScriptedIndirectProxyHandler::delete_(JSContext *cx, HandleObject proxy, HandleI ValueToBool(value, bp); } -bool -ScriptedIndirectProxyHandler::enumerate(JSContext *cx, HandleObject proxy, AutoIdVector &props) const -{ - RootedObject handler(cx, GetIndirectProxyHandlerObject(proxy)); - RootedValue fval(cx), value(cx); - return GetFundamentalTrap(cx, handler, cx->names().enumerate, &fval) && - Trap(cx, handler, fval, 0, nullptr, &value) && - ArrayToIdVector(cx, value, props); -} - bool ScriptedIndirectProxyHandler::has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const { @@ -315,6 +305,17 @@ ScriptedIndirectProxyHandler::getOwnEnumerablePropertyKeys(JSContext *cx, Handle ArrayToIdVector(cx, value, props); } +bool +ScriptedIndirectProxyHandler::getEnumerablePropertyKeys(JSContext *cx, HandleObject proxy, + AutoIdVector &props) const +{ + RootedObject handler(cx, GetIndirectProxyHandlerObject(proxy)); + RootedValue fval(cx), value(cx); + return GetFundamentalTrap(cx, handler, cx->names().enumerate, &fval) && + Trap(cx, handler, fval, 0, nullptr, &value) && + ArrayToIdVector(cx, value, props); +} + bool ScriptedIndirectProxyHandler::iterate(JSContext *cx, HandleObject proxy, unsigned flags, MutableHandleValue vp) const diff --git a/js/src/proxy/ScriptedIndirectProxyHandler.h b/js/src/proxy/ScriptedIndirectProxyHandler.h index 94f7e6cba2fd..3208fe726667 100644 --- a/js/src/proxy/ScriptedIndirectProxyHandler.h +++ b/js/src/proxy/ScriptedIndirectProxyHandler.h @@ -27,7 +27,6 @@ class ScriptedIndirectProxyHandler : public BaseProxyHandler virtual bool ownPropertyKeys(JSContext *cx, HandleObject proxy, AutoIdVector &props) const MOZ_OVERRIDE; virtual bool delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const MOZ_OVERRIDE; - virtual bool enumerate(JSContext *cx, HandleObject proxy, AutoIdVector &props) const MOZ_OVERRIDE; virtual bool preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded) const MOZ_OVERRIDE; virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) const MOZ_OVERRIDE; virtual bool has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const MOZ_OVERRIDE; @@ -42,6 +41,8 @@ class ScriptedIndirectProxyHandler : public BaseProxyHandler virtual bool hasOwn(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const MOZ_OVERRIDE; virtual bool getOwnEnumerablePropertyKeys(JSContext *cx, HandleObject proxy, AutoIdVector &props) const MOZ_OVERRIDE; + virtual bool getEnumerablePropertyKeys(JSContext *cx, HandleObject proxy, + AutoIdVector &props) const MOZ_OVERRIDE; virtual bool iterate(JSContext *cx, HandleObject proxy, unsigned flags, MutableHandleValue vp) const MOZ_OVERRIDE; virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, diff --git a/js/src/vm/ScopeObject.cpp b/js/src/vm/ScopeObject.cpp index f3de687be16c..421deccf3345 100644 --- a/js/src/vm/ScopeObject.cpp +++ b/js/src/vm/ScopeObject.cpp @@ -1755,7 +1755,7 @@ class DebugScopeProxy : public BaseProxyHandler return getScopePropertyNames(cx, proxy, props, JSITER_OWNONLY); } - bool enumerate(JSContext *cx, HandleObject proxy, AutoIdVector &props) const MOZ_OVERRIDE + bool getEnumerablePropertyKeys(JSContext *cx, HandleObject proxy, AutoIdVector &props) const MOZ_OVERRIDE { return getScopePropertyNames(cx, proxy, props, 0); } diff --git a/js/xpconnect/wrappers/FilteringWrapper.cpp b/js/xpconnect/wrappers/FilteringWrapper.cpp index 49d2b5aa010b..3518d19637bf 100644 --- a/js/xpconnect/wrappers/FilteringWrapper.cpp +++ b/js/xpconnect/wrappers/FilteringWrapper.cpp @@ -100,16 +100,6 @@ FilteringWrapper::ownPropertyKeys(JSContext *cx, HandleObject wrap Filter(cx, wrapper, props); } -template -bool -FilteringWrapper::enumerate(JSContext *cx, HandleObject wrapper, - AutoIdVector &props) const -{ - assertEnteredPolicy(cx, wrapper, JSID_VOID, BaseProxyHandler::ENUMERATE); - return Base::enumerate(cx, wrapper, props) && - Filter(cx, wrapper, props); -} - template bool FilteringWrapper::getOwnEnumerablePropertyKeys(JSContext *cx, @@ -121,6 +111,17 @@ FilteringWrapper::getOwnEnumerablePropertyKeys(JSContext *cx, Filter(cx, wrapper, props); } +template +bool +FilteringWrapper::getEnumerablePropertyKeys(JSContext *cx, + HandleObject wrapper, + AutoIdVector &props) const +{ + assertEnteredPolicy(cx, wrapper, JSID_VOID, BaseProxyHandler::ENUMERATE); + return Base::getEnumerablePropertyKeys(cx, wrapper, props) && + Filter(cx, wrapper, props); +} + template bool FilteringWrapper::iterate(JSContext *cx, HandleObject wrapper, @@ -238,7 +239,7 @@ CrossOriginXrayWrapper::ownPropertyKeys(JSContext *cx, JS::Handle wra // All properties on cross-origin objects are supposed |own|, despite what // the underlying native object may report. Override the inherited trap to // avoid passing JSITER_OWNONLY as a flag. - return SecurityXrayDOM::enumerate(cx, wrapper, JSITER_HIDDEN, props); + return SecurityXrayDOM::getPropertyKeys(cx, wrapper, JSITER_HIDDEN, props); } bool @@ -259,8 +260,8 @@ CrossOriginXrayWrapper::delete_(JSContext *cx, JS::Handle wrapper, } bool -CrossOriginXrayWrapper::enumerate(JSContext *cx, JS::Handle wrapper, - JS::AutoIdVector &props) const +CrossOriginXrayWrapper::getEnumerablePropertyKeys(JSContext *cx, JS::Handle wrapper, + JS::AutoIdVector &props) const { // Cross-origin properties are non-enumerable. return true; diff --git a/js/xpconnect/wrappers/FilteringWrapper.h b/js/xpconnect/wrappers/FilteringWrapper.h index b18104b23c53..c09421e12dc9 100644 --- a/js/xpconnect/wrappers/FilteringWrapper.h +++ b/js/xpconnect/wrappers/FilteringWrapper.h @@ -33,14 +33,14 @@ class FilteringWrapper : public Base { JS::MutableHandle desc) const MOZ_OVERRIDE; virtual bool ownPropertyKeys(JSContext *cx, JS::Handle wrapper, JS::AutoIdVector &props) const MOZ_OVERRIDE; - virtual bool enumerate(JSContext *cx, JS::Handle wrapper, - JS::AutoIdVector &props) const MOZ_OVERRIDE; virtual bool getPropertyDescriptor(JSContext *cx, JS::Handle wrapper, JS::Handle id, JS::MutableHandle desc) const MOZ_OVERRIDE; virtual bool getOwnEnumerablePropertyKeys(JSContext *cx, JS::Handle wrapper, JS::AutoIdVector &props) const MOZ_OVERRIDE; + virtual bool getEnumerablePropertyKeys(JSContext *cx, JS::Handle wrapper, + JS::AutoIdVector &props) const MOZ_OVERRIDE; virtual bool iterate(JSContext *cx, JS::Handle wrapper, unsigned flags, JS::MutableHandle vp) const MOZ_OVERRIDE; @@ -80,12 +80,12 @@ class CrossOriginXrayWrapper : public SecurityXrayDOM { JS::AutoIdVector &props) const MOZ_OVERRIDE; virtual bool delete_(JSContext *cx, JS::Handle wrapper, JS::Handle id, bool *bp) const MOZ_OVERRIDE; - virtual bool enumerate(JSContext *cx, JS::Handle wrapper, - JS::AutoIdVector &props) const MOZ_OVERRIDE; virtual bool getPropertyDescriptor(JSContext *cx, JS::Handle wrapper, JS::Handle id, JS::MutableHandle desc) const MOZ_OVERRIDE; + virtual bool getEnumerablePropertyKeys(JSContext *cx, JS::Handle wrapper, + JS::AutoIdVector &props) const MOZ_OVERRIDE; }; } diff --git a/js/xpconnect/wrappers/XrayWrapper.cpp b/js/xpconnect/wrappers/XrayWrapper.cpp index ad5b328e3743..9ad1a15b47ca 100644 --- a/js/xpconnect/wrappers/XrayWrapper.cpp +++ b/js/xpconnect/wrappers/XrayWrapper.cpp @@ -2039,7 +2039,7 @@ XrayWrapper::ownPropertyKeys(JSContext *cx, HandleObject wrapper, AutoIdVector &props) const { assertEnteredPolicy(cx, wrapper, JSID_VOID, BaseProxyHandler::ENUMERATE); - return enumerate(cx, wrapper, JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, props); + return getPropertyKeys(cx, wrapper, JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, props); } template @@ -2063,37 +2063,6 @@ XrayWrapper::delete_(JSContext *cx, HandleObject wrapper, return Traits::singleton.delete_(cx, wrapper, id, bp); } -template -bool -XrayWrapper::enumerate(JSContext *cx, HandleObject wrapper, unsigned flags, - AutoIdVector &props) const -{ - assertEnteredPolicy(cx, wrapper, JSID_VOID, BaseProxyHandler::ENUMERATE); - - // Enumerate expando properties first. Note that the expando object lives - // in the target compartment. - RootedObject target(cx, Traits::singleton.getTargetObject(wrapper)); - RootedObject expando(cx); - if (!Traits::singleton.getExpandoObject(cx, target, wrapper, &expando)) - return false; - - if (expando) { - JSAutoCompartment ac(cx, expando); - if (!js::GetPropertyKeys(cx, expando, flags, &props)) - return false; - } - - return Traits::singleton.enumerateNames(cx, wrapper, flags, props); -} - -template -bool -XrayWrapper::enumerate(JSContext *cx, HandleObject wrapper, - AutoIdVector &props) const -{ - return enumerate(cx, wrapper, 0, props); -} - template bool XrayWrapper::get(JSContext *cx, HandleObject wrapper, @@ -2147,6 +2116,14 @@ XrayWrapper::getOwnEnumerablePropertyKeys(JSContext *cx, return js::BaseProxyHandler::getOwnEnumerablePropertyKeys(cx, wrapper, props); } +template +bool +XrayWrapper::getEnumerablePropertyKeys(JSContext *cx, HandleObject wrapper, + AutoIdVector &props) const +{ + return getPropertyKeys(cx, wrapper, 0, props); +} + template bool XrayWrapper::iterate(JSContext *cx, HandleObject wrapper, @@ -2266,6 +2243,29 @@ XrayWrapper::setImmutablePrototype(JSContext *cx, JS::HandleObject return true; } +template +bool +XrayWrapper::getPropertyKeys(JSContext *cx, HandleObject wrapper, unsigned flags, + AutoIdVector &props) const +{ + assertEnteredPolicy(cx, wrapper, JSID_VOID, BaseProxyHandler::ENUMERATE); + + // Enumerate expando properties first. Note that the expando object lives + // in the target compartment. + RootedObject target(cx, Traits::singleton.getTargetObject(wrapper)); + RootedObject expando(cx); + if (!Traits::singleton.getExpandoObject(cx, target, wrapper, &expando)) + return false; + + if (expando) { + JSAutoCompartment ac(cx, expando); + if (!js::GetPropertyKeys(cx, expando, flags, &props)) + return false; + } + + return Traits::singleton.enumerateNames(cx, wrapper, flags, props); +} + /* * The Permissive / Security variants should be used depending on whether the * compartment of the wrapper is guranteed to subsume the compartment of the diff --git a/js/xpconnect/wrappers/XrayWrapper.h b/js/xpconnect/wrappers/XrayWrapper.h index f4c3ca6968a1..de51cac582b0 100644 --- a/js/xpconnect/wrappers/XrayWrapper.h +++ b/js/xpconnect/wrappers/XrayWrapper.h @@ -413,7 +413,6 @@ class XrayWrapper : public Base { JS::AutoIdVector &props) const MOZ_OVERRIDE; virtual bool delete_(JSContext *cx, JS::Handle wrapper, JS::Handle id, bool *bp) const MOZ_OVERRIDE; - virtual bool enumerate(JSContext *cx, JS::Handle wrapper, JS::AutoIdVector &props) const MOZ_OVERRIDE; virtual bool getPrototypeOf(JSContext *cx, JS::HandleObject wrapper, JS::MutableHandleObject protop) const MOZ_OVERRIDE; virtual bool setPrototypeOf(JSContext *cx, JS::HandleObject wrapper, @@ -440,6 +439,8 @@ class XrayWrapper : public Base { bool *bp) const MOZ_OVERRIDE; virtual bool getOwnEnumerablePropertyKeys(JSContext *cx, JS::Handle wrapper, JS::AutoIdVector &props) const MOZ_OVERRIDE; + virtual bool getEnumerablePropertyKeys(JSContext *cx, JS::Handle wrapper, + JS::AutoIdVector &props) const MOZ_OVERRIDE; virtual bool iterate(JSContext *cx, JS::Handle wrapper, unsigned flags, JS::MutableHandle vp) const MOZ_OVERRIDE; @@ -473,8 +474,8 @@ class XrayWrapper : public Base { } protected: - bool enumerate(JSContext *cx, JS::Handle wrapper, unsigned flags, - JS::AutoIdVector &props) const; + bool getPropertyKeys(JSContext *cx, JS::Handle wrapper, unsigned flags, + JS::AutoIdVector &props) const; }; #define PermissiveXrayXPCWN xpc::XrayWrapper