Skip to content

Instantly share code, notes, and snippets.

@evilpie
Created December 12, 2014 23:05
Show Gist options
  • Save evilpie/2bc4e7f94483b36c6e76 to your computer and use it in GitHub Desktop.
Save evilpie/2bc4e7f94483b36c6e76 to your computer and use it in GitHub Desktop.
Remove getEnumerablePropertyKeys
diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -645,18 +645,16 @@ public:
JS::Handle<JSObject*> proxy,
JS::Handle<jsid> id,
JS::MutableHandle<JSPropertyDescriptor> desc)
const MOZ_OVERRIDE;
virtual bool hasOwn(JSContext *cx, JS::Handle<JSObject*> proxy,
JS::Handle<jsid> id, bool *bp) const MOZ_OVERRIDE;
virtual bool getOwnEnumerablePropertyKeys(JSContext *cx, JS::Handle<JSObject*> proxy,
JS::AutoIdVector &props) const MOZ_OVERRIDE;
- virtual bool getEnumerablePropertyKeys(JSContext *cx, JS::Handle<JSObject*> proxy,
- JS::AutoIdVector &props) const MOZ_OVERRIDE;
virtual const char *className(JSContext *cx,
JS::Handle<JSObject*> wrapper) const MOZ_OVERRIDE;
virtual void finalize(JSFreeOp *fop, JSObject *proxy) const MOZ_OVERRIDE;
virtual bool isCallable(JSObject *obj) const MOZ_OVERRIDE {
return false;
}
@@ -922,37 +920,21 @@ nsOuterWindowProxy::getOwnEnumerableProp
JS::AutoIdVector &props) const
{
// BaseProxyHandler::keys seems to do what we want here: call
// ownPropertyKeys and then filter out the non-enumerable properties.
return js::BaseProxyHandler::getOwnEnumerablePropertyKeys(cx, proxy, props);
}
bool
-nsOuterWindowProxy::getEnumerablePropertyKeys(JSContext *cx, JS::Handle<JSObject*> 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::enumerate(JSContext *cx, JS::Handle<JSObject*> proxy,
JS::MutableHandle<JSObject*> objp) const
{
// BaseProxyHandler::enumerate seems to do what we want here: fall
- // back on the property names returned from getEnumerablePropertyKeys()
+ // back on the property names returned from js::GetPropertyKeys()
return js::BaseProxyHandler::enumerate(cx, proxy, objp);
}
bool
nsOuterWindowProxy::GetSubframeWindow(JSContext *cx,
JS::Handle<JSObject*> proxy,
JS::Handle<jsid> id,
JS::MutableHandle<JS::Value> vp,
diff --git a/dom/bindings/DOMJSProxyHandler.cpp b/dom/bindings/DOMJSProxyHandler.cpp
--- a/dom/bindings/DOMJSProxyHandler.cpp
+++ b/dom/bindings/DOMJSProxyHandler.cpp
@@ -292,29 +292,16 @@ bool
BaseDOMProxyHandler::getOwnEnumerablePropertyKeys(JSContext* cx,
JS::Handle<JSObject*> proxy,
JS::AutoIdVector& props) const
{
return ownPropNames(cx, proxy, JSITER_OWNONLY, props);
}
bool
-BaseDOMProxyHandler::getEnumerablePropertyKeys(JSContext* cx,
- JS::Handle<JSObject*> proxy,
- AutoIdVector& props) const
-{
- JS::Rooted<JSObject*> proto(cx);
- if (!JS_GetPrototype(cx, proxy, &proto)) {
- return false;
- }
- return getOwnEnumerablePropertyKeys(cx, proxy, props) &&
- (!proto || js::GetPropertyKeys(cx, proto, 0, &props));
-}
-
-bool
BaseDOMProxyHandler::enumerate(JSContext *cx, JS::Handle<JSObject*> proxy,
JS::MutableHandle<JSObject*> objp) const
{
return BaseProxyHandler::enumerate(cx, proxy, objp);
}
bool
DOMProxyHandler::has(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool* bp) const
diff --git a/dom/bindings/DOMJSProxyHandler.h b/dom/bindings/DOMJSProxyHandler.h
--- a/dom/bindings/DOMJSProxyHandler.h
+++ b/dom/bindings/DOMJSProxyHandler.h
@@ -66,18 +66,16 @@ public:
JS::MutableHandle<JSObject*> objp) const MOZ_OVERRIDE;
// We override getOwnEnumerablePropertyKeys() and implement it directly
// instead of using the default implementation, which would call
// ownPropertyKeys and then filter out the non-enumerable ones. This avoids
// unnecessary work during enumeration.
virtual bool getOwnEnumerablePropertyKeys(JSContext* cx, JS::Handle<JSObject*> proxy,
JS::AutoIdVector &props) const MOZ_OVERRIDE;
- bool getEnumerablePropertyKeys(JSContext* cx, JS::Handle<JSObject*> proxy,
- JS::AutoIdVector& props) const MOZ_OVERRIDE;
bool watch(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
JS::Handle<JSObject*> callable) const MOZ_OVERRIDE;
bool unwatch(JSContext* cx, JS::Handle<JSObject*> proxy,
JS::Handle<jsid> id) const MOZ_OVERRIDE;
protected:
// Hook for subclasses to implement shared ownPropertyKeys()/keys()
diff --git a/js/ipc/WrapperOwner.cpp b/js/ipc/WrapperOwner.cpp
--- a/js/ipc/WrapperOwner.cpp
+++ b/js/ipc/WrapperOwner.cpp
@@ -105,18 +105,16 @@ class CPOWProxyHandler : public BaseProx
virtual bool call(JSContext *cx, HandleObject proxy, const CallArgs &args) const MOZ_OVERRIDE;
virtual bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args) const MOZ_OVERRIDE;
virtual bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
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,
JSContext *cx) const MOZ_OVERRIDE;
virtual const char* className(JSContext *cx, HandleObject proxy) const MOZ_OVERRIDE;
virtual bool regexp_toShared(JSContext *cx, HandleObject proxy, RegExpGuard *g) const MOZ_OVERRIDE;
virtual void finalize(JSFreeOp *fop, JSObject *proxy) const MOZ_OVERRIDE;
virtual void objectMoved(JSObject *proxy, const JSObject *old) const MOZ_OVERRIDE;
@@ -267,17 +265,18 @@ WrapperOwner::delete_(JSContext *cx, Han
return ok(cx, status);
}
bool
CPOWProxyHandler::enumerate(JSContext *cx, HandleObject proxy, MutableHandleObject objp) const
{
// Using a CPOW for the Iterator would slow down for .. in performance, instead
- // call the base hook, that will us our implementation of getEnumerablePropertyKeys.
+ // call the base hook, that will us our implementation of getOwnEnumerablePropertyKeys
+ // and follow the proto chain.
return BaseProxyHandler::enumerate(cx, proxy, objp);
}
bool
CPOWProxyHandler::has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const
{
FORWARD(has, (cx, proxy, id, bp));
}
@@ -476,28 +475,16 @@ CPOWProxyHandler::getOwnEnumerableProper
bool
WrapperOwner::getOwnEnumerablePropertyKeys(JSContext *cx, HandleObject proxy, AutoIdVector &props)
{
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
{
FORWARD(preventExtensions, (cx, proxy, succeeded));
}
bool
WrapperOwner::preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded)
{
diff --git a/js/ipc/WrapperOwner.h b/js/ipc/WrapperOwner.h
--- a/js/ipc/WrapperOwner.h
+++ b/js/ipc/WrapperOwner.h
@@ -50,18 +50,16 @@ class WrapperOwner : public virtual Java
bool construct);
// SpiderMonkey extensions.
bool getPropertyDescriptor(JSContext *cx, JS::HandleObject proxy, JS::HandleId id,
JS::MutableHandle<JSPropertyDescriptor> desc);
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);
bool hasInstance(JSContext *cx, JS::HandleObject proxy, JS::MutableHandleValue v, bool *bp);
bool objectClassIs(JSContext *cx, JS::HandleObject obj, js::ESClassValue classValue);
const char* className(JSContext *cx, JS::HandleObject proxy);
bool regexp_toShared(JSContext *cx, JS::HandleObject proxy, js::RegExpGuard *g);
nsresult instanceOf(JSObject *obj, const nsID *id, bool *bp);
bool toString(JSContext *cx, JS::HandleObject callee, JS::CallArgs &args);
diff --git a/js/src/jit-test/tests/proxy/testDirectProxyOnProtoWithForIn.js b/js/src/jit-test/tests/proxy/testDirectProxyOnProtoWithForIn.js
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/proxy/testDirectProxyOnProtoWithForIn.js
@@ -0,0 +1,19 @@
+let proxy = new Proxy({
+ a: 1,
+ b: 2,
+ c: 3
+}, {
+ enumerate() {
+ // Should not be invoked.
+ assertEq(false, true);
+ },
+
+ ownKeys() {
+ return ['a', 'b'];
+ }
+});
+
+let object = Object.create(proxy);
+object.d = 4;
+
+assertEq([x for (x in object)].toString(), "d,a,b");
diff --git a/js/src/jsiter.cpp b/js/src/jsiter.cpp
--- a/js/src/jsiter.cpp
+++ b/js/src/jsiter.cpp
@@ -301,48 +301,43 @@ Snapshot(JSContext *cx, HandleObject pob
if (JSEnumerateOp enumerate = pobj->getClass()->enumerate) {
if (!enumerate(cx, pobj.as<NativeObject>()))
return false;
}
if (!EnumerateNativeProperties(cx, pobj.as<NativeObject>(), flags, ht, props))
return false;
} else if (pobj->is<ProxyObject>()) {
AutoIdVector proxyProps(cx);
- if (flags & JSITER_OWNONLY) {
- if (flags & JSITER_HIDDEN) {
- // This gets all property keys, both strings and
- // symbols. The call to Enumerate in the loop below
- // will filter out unwanted keys, per the flags.
- if (!Proxy::ownPropertyKeys(cx, pobj, proxyProps))
- return false;
- } else {
- if (!Proxy::getOwnEnumerablePropertyKeys(cx, pobj, proxyProps))
- return false;
- }
+
+ if (flags & JSITER_HIDDEN) {
+ // This gets all property keys, both strings and
+ // symbols. The call to Enumerate in the loop below
+ // will filter out unwanted keys, per the flags.
+ if (!Proxy::ownPropertyKeys(cx, pobj, proxyProps))
+ return false;
} else {
- if (!Proxy::getEnumerablePropertyKeys(cx, pobj, proxyProps))
+ if (!Proxy::getOwnEnumerablePropertyKeys(cx, pobj, proxyProps))
return false;
}
for (size_t n = 0, len = proxyProps.length(); n < len; n++) {
if (!Enumerate(cx, pobj, proxyProps[n], true, flags, ht, props))
return false;
}
-
- // Proxy objects enumerate the prototype on their own, so we're
- // done here.
- break;
} else {
MOZ_CRASH("non-native objects must have an enumerate op");
}
if (flags & JSITER_OWNONLY)
break;
- } while ((pobj = pobj->getProto()) != nullptr);
+ if (!JSObject::getProto(cx, pobj, &pobj))
+ return false;
+
+ } while (pobj != nullptr);
#ifdef JS_MORE_DETERMINISTIC
/*
* In some cases the enumeration order for an object depends on the
* execution mode (interpreter vs. JIT), especially for native objects
* with a class enumerate hook (where resolving a property changes the
* resulting enumeration order). These aren't really bugs, but the
diff --git a/js/src/jsproxy.h b/js/src/jsproxy.h
--- a/js/src/jsproxy.h
+++ b/js/src/jsproxy.h
@@ -253,17 +253,18 @@ class JS_FRIEND_API(BaseProxyHandler)
virtual bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
MutableHandle<JSPropertyDescriptor> desc) const = 0;
virtual bool ownPropertyKeys(JSContext *cx, HandleObject proxy,
AutoIdVector &props) const = 0;
virtual bool delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const = 0;
/*
* Because [[Enumerate]] is one of the standard traps it should be overridden.
* However for convenience BaseProxyHandler includes a pure virtual implementation,
- * that turns the properties returned by getEnumerablePropertyKeys into an Iterator object.
+ * that turns the properties returned by getOwnEnumerablePropertyKeys (and proto walking)
+ * into an Iterator object.
*/
virtual bool enumerate(JSContext *cx, HandleObject proxy, MutableHandleObject objp) const = 0;
/*
* These methods are standard, but the engine does not normally call them.
* They're opt-in. See "Proxy prototype chains" above.
*
* getPrototypeOf() crashes if called. setPrototypeOf() throws a TypeError.
@@ -306,18 +307,16 @@ class JS_FRIEND_API(BaseProxyHandler)
virtual bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args) const;
/* SpiderMonkey extensions. */
virtual bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
MutableHandle<JSPropertyDescriptor> desc) const = 0;
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 nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, CallArgs args) const;
virtual bool hasInstance(JSContext *cx, HandleObject proxy, MutableHandleValue v, bool *bp) const;
virtual bool objectClassIs(HandleObject obj, ESClassValue classValue, JSContext *cx) const;
virtual const char *className(JSContext *cx, HandleObject proxy) const;
virtual JSString *fun_toString(JSContext *cx, HandleObject proxy, unsigned indent) const;
virtual bool regexp_toShared(JSContext *cx, HandleObject proxy, RegExpGuard *g) const;
virtual bool boxedValue_unbox(JSContext *cx, HandleObject proxy, MutableHandleValue vp) const;
virtual bool defaultValue(JSContext *cx, HandleObject obj, JSType hint, MutableHandleValue vp) const;
@@ -393,18 +392,16 @@ class JS_PUBLIC_API(DirectProxyHandler)
/* SpiderMonkey extensions. */
virtual bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
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 nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl,
CallArgs args) const MOZ_OVERRIDE;
virtual bool hasInstance(JSContext *cx, HandleObject proxy, MutableHandleValue v,
bool *bp) const MOZ_OVERRIDE;
virtual bool objectClassIs(HandleObject obj, ESClassValue classValue,
JSContext *cx) const MOZ_OVERRIDE;
virtual const char *className(JSContext *cx, HandleObject proxy) const MOZ_OVERRIDE;
virtual JSString *fun_toString(JSContext *cx, HandleObject proxy,
diff --git a/js/src/jswrapper.h b/js/src/jswrapper.h
--- a/js/src/jswrapper.h
+++ b/js/src/jswrapper.h
@@ -140,18 +140,16 @@ class JS_FRIEND_API(CrossCompartmentWrap
virtual bool construct(JSContext *cx, HandleObject wrapper, const CallArgs &args) const MOZ_OVERRIDE;
/* SpiderMonkey extensions. */
virtual bool getPropertyDescriptor(JSContext *cx, HandleObject wrapper, HandleId id,
MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
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 nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl,
CallArgs args) const MOZ_OVERRIDE;
virtual bool hasInstance(JSContext *cx, HandleObject wrapper, MutableHandleValue v,
bool *bp) const MOZ_OVERRIDE;
virtual const char *className(JSContext *cx, HandleObject proxy) const MOZ_OVERRIDE;
virtual JSString *fun_toString(JSContext *cx, HandleObject wrapper,
unsigned indent) const MOZ_OVERRIDE;
virtual bool regexp_toShared(JSContext *cx, HandleObject proxy, RegExpGuard *g) const MOZ_OVERRIDE;
diff --git a/js/src/proxy/BaseProxyHandler.cpp b/js/src/proxy/BaseProxyHandler.cpp
--- a/js/src/proxy/BaseProxyHandler.cpp
+++ b/js/src/proxy/BaseProxyHandler.cpp
@@ -229,19 +229,22 @@ BaseProxyHandler::getOwnEnumerableProper
return true;
}
bool
BaseProxyHandler::enumerate(JSContext *cx, HandleObject proxy, MutableHandleObject objp) const
{
assertEnteredPolicy(cx, proxy, JSID_VOID, ENUMERATE);
+ // GetPropertyKeys will invoke getOwnEnumerablePropertyKeys along the proto
+ // chain for us.
AutoIdVector props(cx);
- if (!getEnumerablePropertyKeys(cx, proxy, props))
+ if (!GetPropertyKeys(cx, proxy, 0, &props))
return false;
+
return EnumeratedIdVectorToIterator(cx, proxy, 0, props, objp);
}
bool
BaseProxyHandler::call(JSContext *cx, HandleObject proxy, const CallArgs &args) const
{
MOZ_CRASH("callable proxies should implement call trap");
}
diff --git a/js/src/proxy/CrossCompartmentWrapper.cpp b/js/src/proxy/CrossCompartmentWrapper.cpp
--- a/js/src/proxy/CrossCompartmentWrapper.cpp
+++ b/js/src/proxy/CrossCompartmentWrapper.cpp
@@ -183,26 +183,16 @@ CrossCompartmentWrapper::getOwnEnumerabl
AutoIdVector &props) const
{
PIERCE(cx, wrapper,
NOTHING,
Wrapper::getOwnEnumerablePropertyKeys(cx, wrapper, props),
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.
*/
static bool
CanReify(HandleObject obj)
{
return obj->is<PropertyIteratorObject>() &&
diff --git a/js/src/proxy/DeadObjectProxy.cpp b/js/src/proxy/DeadObjectProxy.cpp
--- a/js/src/proxy/DeadObjectProxy.cpp
+++ b/js/src/proxy/DeadObjectProxy.cpp
@@ -56,24 +56,16 @@ DeadObjectProxy::delete_(JSContext *cx,
bool
DeadObjectProxy::enumerate(JSContext *cx, HandleObject wrapper, MutableHandleObject objp) const
{
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_DEAD_OBJECT);
return false;
}
bool
-DeadObjectProxy::getEnumerablePropertyKeys(JSContext *cx, HandleObject wrapper,
- AutoIdVector &props) const
-{
- JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_DEAD_OBJECT);
- return false;
-}
-
-bool
DeadObjectProxy::getPrototypeOf(JSContext *cx, HandleObject proxy, MutableHandleObject protop) const
{
protop.set(nullptr);
return true;
}
bool
DeadObjectProxy::preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded) const
diff --git a/js/src/proxy/DeadObjectProxy.h b/js/src/proxy/DeadObjectProxy.h
--- a/js/src/proxy/DeadObjectProxy.h
+++ b/js/src/proxy/DeadObjectProxy.h
@@ -32,18 +32,16 @@ class DeadObjectProxy : public BaseProxy
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 call(JSContext *cx, HandleObject proxy, const CallArgs &args) const MOZ_OVERRIDE;
virtual bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args) const MOZ_OVERRIDE;
/* SpiderMonkey extensions. */
virtual bool getPropertyDescriptor(JSContext *cx, HandleObject wrapper, HandleId id,
MutableHandle<JSPropertyDescriptor> 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,
bool *bp) const MOZ_OVERRIDE;
virtual bool objectClassIs(HandleObject obj, ESClassValue classValue,
JSContext *cx) const MOZ_OVERRIDE;
virtual const char *className(JSContext *cx, HandleObject proxy) const MOZ_OVERRIDE;
virtual JSString *fun_toString(JSContext *cx, HandleObject proxy, unsigned indent) const MOZ_OVERRIDE;
diff --git a/js/src/proxy/DirectProxyHandler.cpp b/js/src/proxy/DirectProxyHandler.cpp
--- a/js/src/proxy/DirectProxyHandler.cpp
+++ b/js/src/proxy/DirectProxyHandler.cpp
@@ -238,23 +238,13 @@ DirectProxyHandler::getOwnEnumerableProp
AutoIdVector &props) const
{
assertEnteredPolicy(cx, proxy, JSID_VOID, ENUMERATE);
RootedObject target(cx, proxy->as<ProxyObject>().target());
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<ProxyObject>().target());
- return GetPropertyKeys(cx, target, 0, &props);
-}
-
-bool
DirectProxyHandler::isCallable(JSObject *obj) const
{
JSObject * target = obj->as<ProxyObject>().target();
return target->isCallable();
}
diff --git a/js/src/proxy/Proxy.cpp b/js/src/proxy/Proxy.cpp
--- a/js/src/proxy/Proxy.cpp
+++ b/js/src/proxy/Proxy.cpp
@@ -343,55 +343,36 @@ Proxy::getOwnEnumerablePropertyKeys(JSCo
const BaseProxyHandler *handler = proxy->as<ProxyObject>().handler();
AutoEnterPolicy policy(cx, handler, proxy, JSID_VOIDHANDLE, BaseProxyHandler::ENUMERATE, true);
if (!policy.allowed())
return policy.returnValue();
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<ProxyObject>().handler();
- AutoEnterPolicy policy(cx, handler, proxy, JSID_VOIDHANDLE, BaseProxyHandler::ENUMERATE, true);
- if (!policy.allowed())
- return policy.returnValue();
- if (!handler->hasPrototype())
- return proxy->as<ProxyObject>().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::enumerate(JSContext *cx, HandleObject proxy, MutableHandleObject objp)
{
JS_CHECK_RECURSION(cx, return false);
const BaseProxyHandler *handler = proxy->as<ProxyObject>().handler();
objp.set(nullptr); // default result if we refuse to perform this action
if (!handler->hasPrototype()) {
AutoEnterPolicy policy(cx, handler, proxy, JSID_VOIDHANDLE,
BaseProxyHandler::ENUMERATE, true);
// If the policy denies access but wants us to return true, we need
// to hand a valid (empty) iterator object to the caller.
if (!policy.allowed()) {
return policy.returnValue() &&
NewEmptyPropertyIterator(cx, 0, objp);
}
return handler->enumerate(cx, proxy, objp);
}
- AutoIdVector props(cx);
- // The other Proxy::foo methods do the prototype-aware work for us here.
- if (!Proxy::getEnumerablePropertyKeys(cx, proxy, props))
- return false;
- return EnumeratedIdVectorToIterator(cx, proxy, 0, props, objp);
+
+ // XXXX REALLY not sure about this stuff at all.
+ // The base method does the prototype-aware work for us here.
+ return handler->BaseProxyHandler::enumerate(cx, proxy, objp);
}
bool
Proxy::call(JSContext *cx, HandleObject proxy, const CallArgs &args)
{
JS_CHECK_RECURSION(cx, return false);
const BaseProxyHandler *handler = proxy->as<ProxyObject>().handler();
diff --git a/js/src/proxy/Proxy.h b/js/src/proxy/Proxy.h
--- a/js/src/proxy/Proxy.h
+++ b/js/src/proxy/Proxy.h
@@ -51,17 +51,16 @@ class Proxy
/* SpiderMonkey extensions. */
static bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
MutableHandle<JSPropertyDescriptor> desc);
static bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
MutableHandleValue vp);
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 nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, CallArgs args);
static bool hasInstance(JSContext *cx, HandleObject proxy, MutableHandleValue v, bool *bp);
static bool objectClassIs(HandleObject obj, ESClassValue classValue, JSContext *cx);
static const char *className(JSContext *cx, HandleObject proxy);
static JSString *fun_toString(JSContext *cx, HandleObject proxy, unsigned indent);
static bool regexp_toShared(JSContext *cx, HandleObject proxy, RegExpGuard *g);
static bool boxedValue_unbox(JSContext *cx, HandleObject proxy, MutableHandleValue vp);
static bool defaultValue(JSContext *cx, HandleObject obj, JSType hint, MutableHandleValue vp);
diff --git a/js/src/proxy/ScriptedDirectProxyHandler.cpp b/js/src/proxy/ScriptedDirectProxyHandler.cpp
--- a/js/src/proxy/ScriptedDirectProxyHandler.cpp
+++ b/js/src/proxy/ScriptedDirectProxyHandler.cpp
@@ -795,43 +795,16 @@ ScriptedDirectProxyHandler::enumerate(JS
return false;
}
// step 11
objp.set(&trapResult.toObject());
return true;
}
-// Non-standard, try to convert iterator result to ids
-bool
-ScriptedDirectProxyHandler::getEnumerablePropertyKeys(JSContext *cx, HandleObject proxy, AutoIdVector &props) const
-{
- RootedObject iterator(cx);
- if (!enumerate(cx, proxy, &iterator))
- return false;
-
- do {
- RootedValue rval(cx);
- if (!IteratorMore(cx, iterator, &rval))
- return false;
-
- if (rval.isMagic(JS_NO_ITER_VALUE))
- break;
-
- RootedId id(cx);
- if (!ValueToId<CanGC>(cx, rval, &id))
- return false;
-
- if (!props.append(id))
- return false;
- } while (true);
-
- return true;
-}
-
// ES6 (22 May, 2014) 9.5.7 Proxy.[[HasProperty]](P)
bool
ScriptedDirectProxyHandler::has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const
{
// step 2
RootedObject handler(cx, GetDirectProxyHandlerObject(proxy));
// step 3
diff --git a/js/src/proxy/ScriptedDirectProxyHandler.h b/js/src/proxy/ScriptedDirectProxyHandler.h
--- a/js/src/proxy/ScriptedDirectProxyHandler.h
+++ b/js/src/proxy/ScriptedDirectProxyHandler.h
@@ -58,18 +58,16 @@ class ScriptedDirectProxyHandler : publi
// Kick getOwnEnumerablePropertyKeys out to ownPropertyKeys and then
// filter. [[GetOwnProperty]] could potentially change the enumerability of
// the target's properties.
virtual bool getOwnEnumerablePropertyKeys(JSContext *cx, HandleObject proxy,
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 isCallable(JSObject *obj) const MOZ_OVERRIDE;
virtual bool isConstructor(JSObject *obj) const MOZ_OVERRIDE {
// For now we maintain the broken behavior that a scripted proxy is constructable if it's
// callable. See bug 929467.
return isCallable(obj);
}
virtual bool isScripted() const MOZ_OVERRIDE { return true; }
diff --git a/js/src/proxy/ScriptedIndirectProxyHandler.cpp b/js/src/proxy/ScriptedIndirectProxyHandler.cpp
--- a/js/src/proxy/ScriptedIndirectProxyHandler.cpp
+++ b/js/src/proxy/ScriptedIndirectProxyHandler.cpp
@@ -342,27 +342,16 @@ ScriptedIndirectProxyHandler::getOwnEnum
return false;
if (!IsCallable(value))
return BaseProxyHandler::getOwnEnumerablePropertyKeys(cx, proxy, props);
return Trap(cx, handler, value, 0, nullptr, &value) &&
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::nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl,
CallArgs args) const
{
return BaseProxyHandler::nativeCall(cx, test, impl, args);
}
JSString *
ScriptedIndirectProxyHandler::fun_toString(JSContext *cx, HandleObject proxy, unsigned indent) const
diff --git a/js/src/proxy/ScriptedIndirectProxyHandler.h b/js/src/proxy/ScriptedIndirectProxyHandler.h
--- a/js/src/proxy/ScriptedIndirectProxyHandler.h
+++ b/js/src/proxy/ScriptedIndirectProxyHandler.h
@@ -38,18 +38,16 @@ class ScriptedIndirectProxyHandler : pub
bool strict, MutableHandleValue vp) const MOZ_OVERRIDE;
/* SpiderMonkey extensions. */
virtual bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
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 nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl,
CallArgs args) const MOZ_OVERRIDE;
virtual JSString *fun_toString(JSContext *cx, HandleObject proxy, unsigned indent) const MOZ_OVERRIDE;
virtual bool isScripted() const MOZ_OVERRIDE { return true; }
static const char family;
static const ScriptedIndirectProxyHandler singleton;
diff --git a/js/src/vm/ScopeObject.cpp b/js/src/vm/ScopeObject.cpp
--- a/js/src/vm/ScopeObject.cpp
+++ b/js/src/vm/ScopeObject.cpp
@@ -1687,35 +1687,34 @@ class DebugScopeProxy : public BaseProxy
// Descriptors never store JSNatives for
// accessors: they have either JSFunctions
// or JSPropertyOps.
desc.attributes() | JSPROP_PROPOP_ACCESSORS,
JS_PROPERTYOP_GETTER(desc.getter()),
JS_PROPERTYOP_SETTER(desc.setter()));
}
- bool getScopePropertyNames(JSContext *cx, HandleObject proxy, AutoIdVector &props,
- unsigned flags) const
+ bool ownPropertyKeys(JSContext *cx, HandleObject proxy, AutoIdVector &props) const
{
Rooted<ScopeObject*> scope(cx, &proxy->as<DebugScopeObject>().scope());
if (isMissingArgumentsBinding(*scope)) {
if (!props.append(NameToId(cx->names().arguments)))
return false;
}
// DynamicWithObject isn't a very good proxy. It doesn't have a
// JSNewEnumerateOp implementation, because if it just delegated to the
// target object, the object would indicate that native enumeration is
// the thing to do, but native enumeration over the DynamicWithObject
// wrapper yields no properties. So instead here we hack around the
// issue, and punch a hole through to the with object target.
Rooted<JSObject*> target(cx, (scope->is<DynamicWithObject>()
? &scope->as<DynamicWithObject>().object() : scope));
- if (!GetPropertyKeys(cx, target, flags, &props))
+ if (!GetPropertyKeys(cx, target, JSITER_OWNONLY, &props))
return false;
/*
* Function scopes are optimized to not contain unaliased variables so
* they must be manually appended here.
*/
if (scope->is<CallObject>() && !scope->as<CallObject>().isForEval()) {
RootedScript script(cx, scope->as<CallObject>().callee().nonLazyScript());
@@ -1723,26 +1722,16 @@ class DebugScopeProxy : public BaseProxy
if (!bi->aliased() && !props.append(NameToId(bi->name())))
return false;
}
}
return true;
}
- bool ownPropertyKeys(JSContext *cx, HandleObject proxy, AutoIdVector &props) const MOZ_OVERRIDE
- {
- return getScopePropertyNames(cx, proxy, props, JSITER_OWNONLY);
- }
-
- bool getEnumerablePropertyKeys(JSContext *cx, HandleObject proxy, AutoIdVector &props) const MOZ_OVERRIDE
- {
- return getScopePropertyNames(cx, proxy, props, 0);
- }
-
bool enumerate(JSContext *cx, HandleObject proxy, MutableHandleObject objp) const MOZ_OVERRIDE
{
return BaseProxyHandler::enumerate(cx, proxy, objp);
}
bool has(JSContext *cx, HandleObject proxy, HandleId id_, bool *bp) const MOZ_OVERRIDE
{
RootedId id(cx, id_);
diff --git a/js/xpconnect/wrappers/FilteringWrapper.cpp b/js/xpconnect/wrappers/FilteringWrapper.cpp
--- a/js/xpconnect/wrappers/FilteringWrapper.cpp
+++ b/js/xpconnect/wrappers/FilteringWrapper.cpp
@@ -108,34 +108,23 @@ FilteringWrapper<Base, Policy>::getOwnEn
{
assertEnteredPolicy(cx, wrapper, JSID_VOID, BaseProxyHandler::ENUMERATE);
return Base::getOwnEnumerablePropertyKeys(cx, wrapper, props) &&
Filter<Policy>(cx, wrapper, props);
}
template <typename Base, typename Policy>
bool
-FilteringWrapper<Base, Policy>::getEnumerablePropertyKeys(JSContext *cx,
- HandleObject wrapper,
- AutoIdVector &props) const
-{
- assertEnteredPolicy(cx, wrapper, JSID_VOID, BaseProxyHandler::ENUMERATE);
- return Base::getEnumerablePropertyKeys(cx, wrapper, props) &&
- Filter<Policy>(cx, wrapper, props);
-}
-
-template <typename Base, typename Policy>
-bool
FilteringWrapper<Base, Policy>::enumerate(JSContext *cx, HandleObject wrapper,
MutableHandleObject objp) const
{
assertEnteredPolicy(cx, wrapper, JSID_VOID, BaseProxyHandler::ENUMERATE);
// We refuse to trigger the enumerate hook across chrome wrappers because
// we don't know how to censor custom iterator objects. Instead we trigger
- // the default proxy enumerate trap, which will ask getEnumerablePropertyKeys()
+ // the default proxy enumerate trap, which will use js::GetPropertyKeys
// for the list of (censored) ids.
return js::BaseProxyHandler::enumerate(cx, wrapper, objp);
}
template <typename Base, typename Policy>
bool
FilteringWrapper<Base, Policy>::call(JSContext *cx, JS::Handle<JSObject*> wrapper,
const JS::CallArgs &args) const
@@ -254,24 +243,16 @@ CrossOriginXrayWrapper::defineProperty(J
bool
CrossOriginXrayWrapper::delete_(JSContext *cx, JS::Handle<JSObject*> wrapper,
JS::Handle<jsid> id, bool *bp) const
{
JS_ReportError(cx, "Permission denied to delete property on cross-origin object");
return false;
}
-bool
-CrossOriginXrayWrapper::getEnumerablePropertyKeys(JSContext *cx, JS::Handle<JSObject*> wrapper,
- JS::AutoIdVector &props) const
-{
- // Cross-origin properties are non-enumerable.
- return true;
-}
-
#define XOW FilteringWrapper<CrossOriginXrayWrapper, CrossOriginAccessiblePropertiesOnly>
#define NNXOW FilteringWrapper<CrossCompartmentSecurityWrapper, Opaque>
#define NNXOWC FilteringWrapper<CrossCompartmentSecurityWrapper, OpaqueWithCall>
template<> const XOW XOW::singleton(0);
template<> const NNXOW NNXOW::singleton(0);
template<> const NNXOWC NNXOWC::singleton(0);
diff --git a/js/xpconnect/wrappers/FilteringWrapper.h b/js/xpconnect/wrappers/FilteringWrapper.h
--- a/js/xpconnect/wrappers/FilteringWrapper.h
+++ b/js/xpconnect/wrappers/FilteringWrapper.h
@@ -34,18 +34,16 @@ class FilteringWrapper : public Base {
virtual bool ownPropertyKeys(JSContext *cx, JS::Handle<JSObject*> wrapper,
JS::AutoIdVector &props) const MOZ_OVERRIDE;
virtual bool getPropertyDescriptor(JSContext *cx, JS::Handle<JSObject*> wrapper,
JS::Handle<jsid> id,
JS::MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
virtual bool getOwnEnumerablePropertyKeys(JSContext *cx, JS::Handle<JSObject*> wrapper,
JS::AutoIdVector &props) const MOZ_OVERRIDE;
- virtual bool getEnumerablePropertyKeys(JSContext *cx, JS::Handle<JSObject*> wrapper,
- JS::AutoIdVector &props) const MOZ_OVERRIDE;
virtual bool enumerate(JSContext *cx, JS::Handle<JSObject*> wrapper,
JS::MutableHandle<JSObject*> objp) const MOZ_OVERRIDE;
virtual bool call(JSContext *cx, JS::Handle<JSObject*> wrapper,
const JS::CallArgs &args) const MOZ_OVERRIDE;
virtual bool construct(JSContext *cx, JS::Handle<JSObject*> wrapper,
const JS::CallArgs &args) const MOZ_OVERRIDE;
@@ -79,15 +77,13 @@ class CrossOriginXrayWrapper : public Se
virtual bool ownPropertyKeys(JSContext *cx, JS::Handle<JSObject*> wrapper,
JS::AutoIdVector &props) const MOZ_OVERRIDE;
virtual bool delete_(JSContext *cx, JS::Handle<JSObject*> wrapper,
JS::Handle<jsid> id, bool *bp) const MOZ_OVERRIDE;
virtual bool getPropertyDescriptor(JSContext *cx, JS::Handle<JSObject*> wrapper,
JS::Handle<jsid> id,
JS::MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
- virtual bool getEnumerablePropertyKeys(JSContext *cx, JS::Handle<JSObject*> wrapper,
- JS::AutoIdVector &props) const MOZ_OVERRIDE;
};
}
#endif /* __FilteringWrapper_h__ */
diff --git a/js/xpconnect/wrappers/XrayWrapper.cpp b/js/xpconnect/wrappers/XrayWrapper.cpp
--- a/js/xpconnect/wrappers/XrayWrapper.cpp
+++ b/js/xpconnect/wrappers/XrayWrapper.cpp
@@ -2107,24 +2107,16 @@ XrayWrapper<Base, Traits>::getOwnEnumera
AutoIdVector &props) const
{
// Skip our Base if it isn't already ProxyHandler.
return js::BaseProxyHandler::getOwnEnumerablePropertyKeys(cx, wrapper, props);
}
template <typename Base, typename Traits>
bool
-XrayWrapper<Base, Traits>::getEnumerablePropertyKeys(JSContext *cx, HandleObject wrapper,
- AutoIdVector &props) const
-{
- return getPropertyKeys(cx, wrapper, 0, props);
-}
-
-template <typename Base, typename Traits>
-bool
XrayWrapper<Base, Traits>::enumerate(JSContext *cx, HandleObject wrapper,
MutableHandleObject objp) const
{
// Skip our Base if it isn't already ProxyHandler.
return js::BaseProxyHandler::enumerate(cx, wrapper, objp);
}
template <typename Base, typename Traits>
diff --git a/js/xpconnect/wrappers/XrayWrapper.h b/js/xpconnect/wrappers/XrayWrapper.h
--- a/js/xpconnect/wrappers/XrayWrapper.h
+++ b/js/xpconnect/wrappers/XrayWrapper.h
@@ -436,18 +436,16 @@ class XrayWrapper : public Base {
/* SpiderMonkey extensions. */
virtual bool getPropertyDescriptor(JSContext *cx, JS::Handle<JSObject*> wrapper, JS::Handle<jsid> id,
JS::MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
virtual bool hasOwn(JSContext *cx, JS::Handle<JSObject*> wrapper, JS::Handle<jsid> id,
bool *bp) const MOZ_OVERRIDE;
virtual bool getOwnEnumerablePropertyKeys(JSContext *cx, JS::Handle<JSObject*> wrapper,
JS::AutoIdVector &props) const MOZ_OVERRIDE;
- virtual bool getEnumerablePropertyKeys(JSContext *cx, JS::Handle<JSObject*> wrapper,
- JS::AutoIdVector &props) const MOZ_OVERRIDE;
virtual const char *className(JSContext *cx, JS::HandleObject proxy) const MOZ_OVERRIDE;
virtual bool defaultValue(JSContext *cx, JS::HandleObject wrapper,
JSType hint, JS::MutableHandleValue vp)
const MOZ_OVERRIDE;
static const XrayWrapper singleton;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment