From 2999d4406eefdfa7465a35b8ff908258d321893a Mon Sep 17 00:00:00 2001 From: Jason Orendorff Date: Wed, 8 Oct 2014 12:09:08 -0500 Subject: [PATCH] Bug 1081255 - Rewrite comments in jsproxy.h; reclassify the methods a bit. No change in behavior. r=efaust, r=bz, r=jwalden. --HG-- extra : rebase_source : b3440548322d65b2bd01862fb863e6197eb263c6 --- dom/base/nsGlobalWindow.cpp | 59 ++--- dom/bindings/DOMJSProxyHandler.h | 40 +-- js/ipc/WrapperOwner.cpp | 15 +- js/ipc/WrapperOwner.h | 24 +- js/src/jsproxy.h | 263 +++++++++++++------- js/src/jswrapper.h | 62 ++--- js/src/proxy/DeadObjectProxy.h | 16 +- js/src/proxy/Proxy.h | 32 ++- js/src/proxy/ScriptedDirectProxyHandler.h | 28 +-- js/src/proxy/ScriptedIndirectProxyHandler.h | 18 +- js/src/vm/ProxyObject.h | 2 +- js/xpconnect/wrappers/AddonWrapper.h | 13 +- js/xpconnect/wrappers/ChromeObjectWrapper.h | 21 +- js/xpconnect/wrappers/FilteringWrapper.h | 28 +-- js/xpconnect/wrappers/WaiveXrayWrapper.h | 17 +- js/xpconnect/wrappers/XrayWrapper.h | 51 ++-- 16 files changed, 380 insertions(+), 309 deletions(-) diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index 44067714919..afce81803be 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -599,20 +599,7 @@ public: return false; } - virtual const char *className(JSContext *cx, - JS::Handle wrapper) const MOZ_OVERRIDE; - virtual void finalize(JSFreeOp *fop, JSObject *proxy) const MOZ_OVERRIDE; - - // Fundamental traps - virtual bool isExtensible(JSContext *cx, JS::Handle proxy, bool *extensible) - const MOZ_OVERRIDE; - virtual bool preventExtensions(JSContext *cx, - JS::Handle proxy) const MOZ_OVERRIDE; - virtual bool getPropertyDescriptor(JSContext* cx, - JS::Handle proxy, - JS::Handle id, - JS::MutableHandle desc) - const MOZ_OVERRIDE; + // Standard internal methods virtual bool getOwnPropertyDescriptor(JSContext* cx, JS::Handle proxy, JS::Handle id, @@ -631,23 +618,12 @@ public: bool *bp) const MOZ_OVERRIDE; virtual bool enumerate(JSContext *cx, JS::Handle proxy, JS::AutoIdVector &props) const MOZ_OVERRIDE; - - virtual bool watch(JSContext *cx, JS::Handle proxy, - JS::Handle id, JS::Handle callable) const MOZ_OVERRIDE; - virtual bool unwatch(JSContext *cx, JS::Handle proxy, - JS::Handle id) const MOZ_OVERRIDE; - virtual bool isCallable(JSObject *obj) const MOZ_OVERRIDE { - return false; - } - virtual bool isConstructor(JSObject *obj) const MOZ_OVERRIDE { - return false; - } - - // Derived traps + virtual bool isExtensible(JSContext *cx, JS::Handle proxy, bool *extensible) + const MOZ_OVERRIDE; + virtual bool preventExtensions(JSContext *cx, + JS::Handle proxy) const MOZ_OVERRIDE; virtual bool has(JSContext *cx, JS::Handle proxy, JS::Handle id, bool *bp) const MOZ_OVERRIDE; - virtual bool hasOwn(JSContext *cx, JS::Handle proxy, - JS::Handle id, bool *bp) const MOZ_OVERRIDE; virtual bool get(JSContext *cx, JS::Handle proxy, JS::Handle receiver, JS::Handle id, @@ -657,11 +633,36 @@ public: JS::Handle id, bool strict, JS::MutableHandle vp) const MOZ_OVERRIDE; + + // SpiderMonkey extensions + virtual bool getPropertyDescriptor(JSContext* cx, + JS::Handle proxy, + JS::Handle id, + JS::MutableHandle desc) + const MOZ_OVERRIDE; + virtual bool hasOwn(JSContext *cx, JS::Handle proxy, + JS::Handle id, bool *bp) const MOZ_OVERRIDE; virtual bool keys(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; + virtual const char *className(JSContext *cx, + JS::Handle wrapper) const MOZ_OVERRIDE; + + virtual void finalize(JSFreeOp *fop, JSObject *proxy) const MOZ_OVERRIDE; + + virtual bool isCallable(JSObject *obj) const MOZ_OVERRIDE { + return false; + } + virtual bool isConstructor(JSObject *obj) const MOZ_OVERRIDE { + return false; + } + + virtual bool watch(JSContext *cx, JS::Handle proxy, + JS::Handle id, JS::Handle callable) const MOZ_OVERRIDE; + virtual bool unwatch(JSContext *cx, JS::Handle proxy, + JS::Handle id) const MOZ_OVERRIDE; static void ObjectMoved(JSObject *obj, const JSObject *old); diff --git a/dom/bindings/DOMJSProxyHandler.h b/dom/bindings/DOMJSProxyHandler.h index 0ecdedf7493..ade0df8962f 100644 --- a/dom/bindings/DOMJSProxyHandler.h +++ b/dom/bindings/DOMJSProxyHandler.h @@ -50,23 +50,20 @@ public: : js::BaseProxyHandler(aProxyFamily, aHasPrototype) {} - // Implementations of traps that can be implemented in terms of - // fundamental traps. - bool enumerate(JSContext* cx, JS::Handle proxy, - JS::AutoIdVector& props) const MOZ_OVERRIDE; - bool getPropertyDescriptor(JSContext* cx, JS::Handle proxy, - JS::Handle id, - JS::MutableHandle desc) const MOZ_OVERRIDE; + // Implementations of methods that can be implemented in terms of + // other lower-level methods. bool getOwnPropertyDescriptor(JSContext* cx, JS::Handle proxy, JS::Handle id, JS::MutableHandle desc) const MOZ_OVERRIDE; - - bool watch(JSContext* cx, JS::Handle proxy, JS::Handle id, - JS::Handle callable) const MOZ_OVERRIDE; - bool unwatch(JSContext* cx, JS::Handle proxy, - JS::Handle id) 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, + JS::MutableHandle desc) const MOZ_OVERRIDE; + // We override keys() and implement it directly instead of using the // default implementation, which would getOwnPropertyNames and then // filter out the non-enumerable ones. This avoids doing @@ -74,6 +71,11 @@ public: virtual bool keys(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; + bool unwatch(JSContext* cx, JS::Handle proxy, + JS::Handle id) const MOZ_OVERRIDE; + protected: // Hook for subclasses to implement shared ownPropertyKeys()/keys() // functionality. The "flags" argument is either JSITER_OWNONLY (for keys()) @@ -100,7 +102,6 @@ public: : BaseDOMProxyHandler(&family) {} - bool preventExtensions(JSContext *cx, JS::Handle proxy) const MOZ_OVERRIDE; bool defineProperty(JSContext* cx, JS::Handle proxy, JS::Handle id, JS::MutableHandle desc) const MOZ_OVERRIDE { @@ -110,15 +111,16 @@ public: virtual bool defineProperty(JSContext* cx, JS::Handle proxy, JS::Handle id, JS::MutableHandle desc, bool* defined) const; + bool delete_(JSContext* cx, JS::Handle proxy, + JS::Handle id, bool* bp) const MOZ_OVERRIDE; + bool isExtensible(JSContext *cx, JS::Handle proxy, bool *extensible) + const MOZ_OVERRIDE; + bool preventExtensions(JSContext *cx, JS::Handle proxy) const MOZ_OVERRIDE; + bool has(JSContext* cx, JS::Handle proxy, JS::Handle id, + bool* bp) const MOZ_OVERRIDE; bool set(JSContext *cx, JS::Handle proxy, JS::Handle receiver, JS::Handle id, bool strict, JS::MutableHandle vp) const MOZ_OVERRIDE; - bool delete_(JSContext* cx, JS::Handle proxy, - JS::Handle id, bool* bp) const MOZ_OVERRIDE; - bool has(JSContext* cx, JS::Handle proxy, JS::Handle id, - bool* bp) const MOZ_OVERRIDE; - bool isExtensible(JSContext *cx, JS::Handle proxy, bool *extensible) - const MOZ_OVERRIDE; /* * If assigning to proxy[id] hits a named setter with OverrideBuiltins or diff --git a/js/ipc/WrapperOwner.cpp b/js/ipc/WrapperOwner.cpp index adc5df67f67..2a27ca9ccac 100644 --- a/js/ipc/WrapperOwner.cpp +++ b/js/ipc/WrapperOwner.cpp @@ -63,9 +63,6 @@ class CPOWProxyHandler : public BaseProxyHandler return false; } - virtual bool preventExtensions(JSContext *cx, HandleObject proxy) const MOZ_OVERRIDE; - virtual bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id, - MutableHandle desc) const MOZ_OVERRIDE; virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id, MutableHandle desc) const MOZ_OVERRIDE; virtual bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id, @@ -74,18 +71,20 @@ class CPOWProxyHandler : 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 isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) const MOZ_OVERRIDE; + virtual bool preventExtensions(JSContext *cx, HandleObject proxy) const MOZ_OVERRIDE; virtual bool has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const MOZ_OVERRIDE; - virtual bool hasOwn(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const MOZ_OVERRIDE; virtual bool get(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id, MutableHandleValue vp) const MOZ_OVERRIDE; virtual bool set(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiver, JS::HandleId id, bool strict, JS::MutableHandleValue vp) const MOZ_OVERRIDE; - virtual bool keys(JSContext *cx, HandleObject proxy, AutoIdVector &props) 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; + + virtual bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id, + MutableHandle desc) const MOZ_OVERRIDE; + virtual bool hasOwn(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const MOZ_OVERRIDE; + virtual bool keys(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, diff --git a/js/ipc/WrapperOwner.h b/js/ipc/WrapperOwner.h index 26f19113c72..08bfd8f78a6 100644 --- a/js/ipc/WrapperOwner.h +++ b/js/ipc/WrapperOwner.h @@ -31,11 +31,8 @@ class WrapperOwner : public virtual JavaScriptShared explicit WrapperOwner(JSRuntime *rt); bool init(); - // Fundamental proxy traps. These are required. + // Standard internal methods. // (The traps should be in the same order like js/src/jsproxy.h) - bool preventExtensions(JSContext *cx, JS::HandleObject proxy); - bool getPropertyDescriptor(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, - JS::MutableHandle desc); bool getOwnPropertyDescriptor(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, JS::MutableHandle desc); bool defineProperty(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, @@ -43,25 +40,26 @@ class WrapperOwner : public virtual JavaScriptShared 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); - - // Derived proxy traps. Implementing these is useful for perfomance. + bool isExtensible(JSContext *cx, JS::HandleObject proxy, bool *extensible); + bool preventExtensions(JSContext *cx, JS::HandleObject proxy); bool has(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, bool *bp); - bool hasOwn(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, bool *bp); bool get(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiver, JS::HandleId id, JS::MutableHandleValue vp); bool set(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiver, JS::HandleId id, bool strict, JS::MutableHandleValue vp); - bool keys(JSContext *cx, JS::HandleObject proxy, JS::AutoIdVector &props); - // We use "iterate" provided by the base class here. - - // SpiderMonkey Extensions. - bool isExtensible(JSContext *cx, JS::HandleObject proxy, bool *extensible); - bool regexp_toShared(JSContext *cx, JS::HandleObject proxy, js::RegExpGuard *g); bool callOrConstruct(JSContext *cx, JS::HandleObject proxy, const JS::CallArgs &args, bool construct); + + // SpiderMonkey extensions. + bool getPropertyDescriptor(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, + JS::MutableHandle desc); + bool hasOwn(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, bool *bp); + bool keys(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); const char* className(JSContext *cx, JS::HandleObject proxy); + bool regexp_toShared(JSContext *cx, JS::HandleObject proxy, js::RegExpGuard *g); bool isCallable(JSObject *obj); bool isConstructor(JSObject *obj); diff --git a/js/src/jsproxy.h b/js/src/jsproxy.h index aa19392a910..940ded54ba9 100644 --- a/js/src/jsproxy.h +++ b/js/src/jsproxy.h @@ -33,57 +33,120 @@ class RegExpGuard; class JS_FRIEND_API(Wrapper); /* - * A proxy is a JSObject that implements generic behavior by providing custom - * implementations for each object trap. The implementation for each trap is - * provided by a C++ object stored on the proxy, known as its handler. + * A proxy is a JSObject with highly customizable behavior. ES6 specifies a + * single kind of proxy, but the customization mechanisms we use to implement + * ES6 Proxy objects are also useful wherever an object with weird behavior is + * wanted. Proxies are used to implement: * - * A major use case for proxies is to forward each trap to another object, - * known as its target. The target can be an arbitrary C++ object. Not every - * proxy has the notion of a target, however. + * - the scope objects used by the Debugger's frame.eval() method + * (see js::GetDebugScopeForFunction) * - * Proxy traps are grouped into fundamental and derived traps. Every proxy has - * to at least provide implementations for the fundamental traps, but the - * derived traps can be implemented in terms of the fundamental ones - * BaseProxyHandler provides implementations of the derived traps in terms of - * the (pure virtual) fundamental traps. + * - the khuey hack, whereby a whole compartment can be blown away + * even if other compartments hold references to objects in it + * (see js::NukeCrossCompartmentWrappers) * - * In addition to the normal traps, there are two models for proxy prototype - * chains. First, proxies may opt to use the standard prototype mechanism used - * throughout the engine. To do so, simply pass a prototype to NewProxyObject() - * at creation time. All prototype accesses will then "just work" to treat the - * proxy as a "normal" object. Alternatively, if instead the proxy wishes to - * implement more complicated prototype semantics (if, for example, it wants to - * delegate the prototype lookup to a wrapped object), it may pass Proxy::LazyProto - * as the prototype at create time and opt in to the trapped prototype system, - * which guarantees that their trap will be called on any and every prototype - * chain access of the object. + * - XPConnect security wrappers, which protect chrome from malicious content + * (js/xpconnect/wrappers) * - * This system is implemented with two traps: {get,set}PrototypeOf. The default - * implementation of setPrototypeOf throws a TypeError. Since it is not possible - * to create an object without a sense of prototype chain, handler implementors - * must provide a getPrototypeOf trap if opting in to the dynamic prototype system. + * - DOM objects with special property behavior, like named getters + * (dom/bindings/Codegen.py generates these proxies from WebIDL) + * + * - semi-transparent use of objects that live in other processes + * (CPOWs, implemented in js/ipc) + * + * ### Proxies and internal methods + * + * ES6 draft rev 27 (24 August 2014) specifies 14 internal methods. The runtime + * semantics of just about everything a script can do to an object is specified + * in terms of these internal methods. For example: + * + * JS code ES6 internal method that gets called + * --------------------------- -------------------------------- + * obj.prop obj.[[Get]](obj, "prop") + * "prop" in obj obj.[[HasProperty]]("prop") + * new obj() obj.[[Construct]]() + * for (k in obj) {} obj.[[Enumerate]]() + * + * With regard to the implementation of these internal methods, there are three + * very different kinds of object in SpiderMonkey. + * + * 1. Native objects' internal methods are implemented in js::baseops in + * vm/NativeObject.cpp, with duplicate (but functionally identical) + * implementations scattered through the ICs and JITs. + * + * 2. Certain non-native objects have internal methods that are implemented as + * magical js::ObjectOps hooks. We're trying to get rid of these. + * + * 3. All other objects are proxies. A proxy's internal methods are + * implemented in C++, as the virtual methods of a C++ object stored on the + * proxy, known as its handler. + * + * This means that just about anything you do to a proxy will end up going + * through a C++ virtual method call. Possibly several. There's no reason the + * JITs and ICs can't specialize for particular proxies, based on the handler; + * but currently we don't do much of this, so the virtual method overhead + * typically is actually incurred. + * + * ### The proxy handler hierarchy + * + * A major use case for proxies is to forward each internal method call to + * another object, known as its target. The target can be an arbitrary JS + * object. Not every proxy has the notion of a target, however. * * To minimize code duplication, a set of abstract proxy handler classes is - * provided, from which other handlers may inherit. These abstract classes - * are organized in the following hierarchy: + * provided, from which other handlers may inherit. These abstract classes are + * organized in the following hierarchy: * - * BaseProxyHandler - * | - * DirectProxyHandler - * | - * Wrapper + * BaseProxyHandler + * | + * DirectProxyHandler // has a target + * | + * Wrapper // can be unwrapped, revealing target + * | // (see js::CheckedUnwrap) + * | + * CrossCompartmentWrapper // target is in another compartment; + * // implements membrane between compartments + * + * Example: Some DOM objects (including all the arraylike DOM objects) are + * implemented as proxies. Since these objects don't need to forward operations + * to any underlying JS object, DOMJSProxyHandler directly subclasses + * BaseProxyHandler. + * + * Gecko's security wrappers are examples of cross-compartment wrappers. + * + * ### Proxy prototype chains + * + * In addition to the normal methods, there are two models for proxy prototype + * chains. + * + * 1. Proxies can use the standard prototype mechanism used throughout the + * engine. To do so, simply pass a prototype to NewProxyObject() at + * creation time. All prototype accesses will then "just work" to treat the + * proxy as a "normal" object. + * + * 2. A proxy can implement more complicated prototype semantics (if, for + * example, it wants to delegate the prototype lookup to a wrapped object) + * by passing Proxy::LazyProto as the prototype at create time. This + * guarantees that the getPrototypeOf() handler method will be called every + * time the object's prototype chain is accessed. + * + * This system is implemented with two methods: {get,set}PrototypeOf. The + * default implementation of setPrototypeOf throws a TypeError. Since it is + * not possible to create an object without a sense of prototype chain, + * handlers must implement getPrototypeOf if opting in to the dynamic + * prototype system. */ /* * BaseProxyHandler is the most generic kind of proxy handler. It does not make * any assumptions about the target. Consequently, it does not provide any - * default implementation for the fundamental traps. It does, however, implement - * the derived traps in terms of the fundamental ones. This allows consumers of - * this class to define any custom behavior they want. + * default implementation for most methods. As a convenience, a few high-level + * methods, like get() and set(), are given default implementations that work by + * calling the low-level methods, like getOwnPropertyDescriptor(). * - * Important: If you add a trap here, you should probably also add a Proxy::foo - * entry point with an AutoEnterPolicy. If you don't, you need an explicit - * override for the trap in SecurityWrapper. See bug 945826 comment 0. + * Important: If you add a method here, you should probably also add a + * Proxy::foo entry point with an AutoEnterPolicy. If you don't, you need an + * explicit override for the method in SecurityWrapper. See bug 945826 comment 0. */ class JS_FRIEND_API(BaseProxyHandler) { @@ -103,7 +166,7 @@ class JS_FRIEND_API(BaseProxyHandler) * * - When mHasPrototype is true, the engine never calls these methods: * getPropertyDescriptor, has, set, enumerate, iterate. Instead, for - * these operations, it calls the "own" traps like + * these operations, it calls the "own" methods like * getOwnPropertyDescriptor, hasOwn, defineProperty, keys, etc., and * consults the prototype chain if needed. * @@ -155,14 +218,14 @@ class JS_FRIEND_API(BaseProxyHandler) return true; } - /* Policy enforcement traps. + /* Policy enforcement methods. * * enter() allows the policy to specify whether the caller may perform |act| * on the proxy's |id| property. In the case when |act| is CALL, |id| is * generally JSID_VOID. * * The |act| parameter to enter() specifies the action being performed. - * If |bp| is false, the trap suggests that the caller throw (though it + * If |bp| is false, the method suggests that the caller throw (though it * may still decide to squelch the error). * * We make these OR-able so that assertEnteredPolicy can pass a union of them. @@ -183,34 +246,62 @@ class JS_FRIEND_API(BaseProxyHandler) virtual bool enter(JSContext *cx, HandleObject wrapper, HandleId id, Action act, bool *bp) const; - /* ES5 Harmony fundamental proxy traps. */ - virtual bool preventExtensions(JSContext *cx, HandleObject proxy) const = 0; - virtual bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id, - MutableHandle desc) const = 0; - virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, - HandleId id, MutableHandle desc) const = 0; + /* Standard internal methods. */ + virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id, + MutableHandle desc) const = 0; virtual bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id, MutableHandle 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; virtual bool enumerate(JSContext *cx, HandleObject proxy, AutoIdVector &props) const = 0; + virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) const = 0; + virtual bool preventExtensions(JSContext *cx, HandleObject proxy) const = 0; - /* ES5 Harmony derived proxy traps. */ + /* + * 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. + */ + virtual bool getPrototypeOf(JSContext *cx, HandleObject proxy, MutableHandleObject protop) const; + virtual bool setPrototypeOf(JSContext *cx, HandleObject proxy, HandleObject proto, bool *bp) const; + + /* + * These standard internal methods are implemented, as a convenience, so + * that ProxyHandler subclasses don't have to provide every single method. + * + * The base-class implementations work by calling getPropertyDescriptor(). + * They do not follow any standard. When in doubt, override them. + */ virtual bool has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const; - virtual bool hasOwn(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const; virtual bool get(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id, MutableHandleValue vp) const; virtual bool set(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id, bool strict, MutableHandleValue vp) const; + + /* + * [[Call]] and [[Construct]] are standard internal methods but according + * to the spec, they are not present on every object. + * + * SpiderMonkey never calls a proxy's call()/construct() internal method + * unless isCallable()/isConstructor() returns true for that proxy. + * + * BaseProxyHandler::isCallable()/isConstructor() always return false, and + * BaseProxyHandler::call()/construct() crash if called. So if you're + * creating a kind of that is never callable, you don't have to override + * anything, but otherwise you probably want to override all four. + */ + virtual bool call(JSContext *cx, HandleObject proxy, const CallArgs &args) const; + virtual bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args) const; + + /* SpiderMonkey extensions. */ + virtual bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id, + MutableHandle desc) const = 0; + virtual bool hasOwn(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const; virtual bool keys(JSContext *cx, HandleObject proxy, AutoIdVector &props) const; virtual bool iterate(JSContext *cx, HandleObject proxy, unsigned flags, MutableHandleValue vp) const; - - /* Spidermonkey extensions. */ - virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) const = 0; - virtual bool call(JSContext *cx, HandleObject proxy, const CallArgs &args) const; - virtual bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args) const; 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; @@ -221,8 +312,6 @@ class JS_FRIEND_API(BaseProxyHandler) virtual bool defaultValue(JSContext *cx, HandleObject obj, JSType hint, MutableHandleValue vp) const; virtual void finalize(JSFreeOp *fop, JSObject *proxy) const; virtual void objectMoved(JSObject *proxy, const JSObject *old) const; - virtual bool getPrototypeOf(JSContext *cx, HandleObject proxy, MutableHandleObject protop) const; - virtual bool setPrototypeOf(JSContext *cx, HandleObject proxy, HandleObject proto, bool *bp) const; // Allow proxies, wrappers in particular, to specify callability at runtime. // Note: These do not take const JSObject *, but they do in spirit. @@ -246,13 +335,13 @@ class JS_FRIEND_API(BaseProxyHandler) }; /* - * DirectProxyHandler includes a notion of a target object. All traps are + * DirectProxyHandler includes a notion of a target object. All methods are * reimplemented such that they forward their behavior to the target. This * allows consumers of this class to forward to another object as transparently * and efficiently as possible. * - * Important: If you add a trap implementation here, you probably also need to - * add an override in CrossCompartmentWrapper. If you don't, you risk + * Important: If you add a method implementation here, you probably also need + * to add an override in CrossCompartmentWrapper. If you don't, you risk * compartment mismatches. See bug 945826 comment 0. */ class JS_PUBLIC_API(DirectProxyHandler) : public BaseProxyHandler @@ -263,10 +352,7 @@ class JS_PUBLIC_API(DirectProxyHandler) : public BaseProxyHandler : BaseProxyHandler(aFamily, aHasPrototype, aHasSecurityPolicy) { } - /* ES5 Harmony fundamental proxy traps. */ - virtual bool preventExtensions(JSContext *cx, HandleObject proxy) const MOZ_OVERRIDE; - virtual bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id, - MutableHandle desc) const MOZ_OVERRIDE; + /* Standard internal methods. */ virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id, MutableHandle desc) const MOZ_OVERRIDE; virtual bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id, @@ -277,33 +363,34 @@ class JS_PUBLIC_API(DirectProxyHandler) : public BaseProxyHandler bool *bp) const MOZ_OVERRIDE; virtual bool enumerate(JSContext *cx, HandleObject proxy, AutoIdVector &props) const MOZ_OVERRIDE; - - /* ES5 Harmony derived proxy traps. */ - virtual bool has(JSContext *cx, HandleObject proxy, HandleId id, - bool *bp) const MOZ_OVERRIDE; - virtual bool hasOwn(JSContext *cx, HandleObject proxy, HandleId id, - bool *bp) const MOZ_OVERRIDE; - virtual bool get(JSContext *cx, HandleObject proxy, HandleObject receiver, - HandleId id, MutableHandleValue vp) const MOZ_OVERRIDE; - virtual bool set(JSContext *cx, HandleObject proxy, HandleObject receiver, - HandleId id, bool strict, MutableHandleValue vp) const MOZ_OVERRIDE; - virtual bool keys(JSContext *cx, HandleObject proxy, - AutoIdVector &props) const MOZ_OVERRIDE; - virtual bool iterate(JSContext *cx, HandleObject proxy, unsigned flags, - MutableHandleValue vp) const MOZ_OVERRIDE; - - /* Spidermonkey extensions. */ 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; - 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 preventExtensions(JSContext *cx, HandleObject proxy) const MOZ_OVERRIDE; virtual bool getPrototypeOf(JSContext *cx, HandleObject proxy, MutableHandleObject protop) const MOZ_OVERRIDE; virtual bool setPrototypeOf(JSContext *cx, HandleObject proxy, HandleObject proto, bool *bp) const MOZ_OVERRIDE; + virtual bool has(JSContext *cx, HandleObject proxy, HandleId id, + bool *bp) const MOZ_OVERRIDE; + virtual bool get(JSContext *cx, HandleObject proxy, HandleObject receiver, + HandleId id, MutableHandleValue vp) const MOZ_OVERRIDE; + virtual bool set(JSContext *cx, HandleObject proxy, HandleObject receiver, + HandleId id, bool strict, MutableHandleValue vp) 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 proxy, HandleId id, + MutableHandle desc) const MOZ_OVERRIDE; + virtual bool hasOwn(JSContext *cx, HandleObject proxy, HandleId id, + bool *bp) const MOZ_OVERRIDE; + virtual bool keys(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, + 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; @@ -312,8 +399,8 @@ class JS_PUBLIC_API(DirectProxyHandler) : public BaseProxyHandler virtual bool regexp_toShared(JSContext *cx, HandleObject proxy, RegExpGuard *g) const MOZ_OVERRIDE; virtual bool boxedValue_unbox(JSContext *cx, HandleObject proxy, MutableHandleValue vp) const; - virtual JSObject *weakmapKeyDelegate(JSObject *proxy) const MOZ_OVERRIDE; virtual bool isCallable(JSObject *obj) const MOZ_OVERRIDE; + virtual JSObject *weakmapKeyDelegate(JSObject *proxy) const MOZ_OVERRIDE; }; extern JS_FRIEND_DATA(const js::Class* const) ProxyClassPtr; @@ -469,8 +556,8 @@ class JS_FRIEND_API(AutoEnterPolicy) Action enteredAction; // NB: We explicitly don't track the entered action here, because sometimes - // SET traps do an implicit GET during their implementation, leading to - // spurious assertions. + // set() methods do an implicit get() during their implementation, leading + // to spurious assertions. AutoEnterPolicy *prev; void recordEnter(JSContext *cx, HandleObject proxy, HandleId id, Action act); void recordLeave(); diff --git a/js/src/jswrapper.h b/js/src/jswrapper.h index 82021e7b870..dd7216752b9 100644 --- a/js/src/jswrapper.h +++ b/js/src/jswrapper.h @@ -46,12 +46,13 @@ class MOZ_STACK_CLASS WrapperOptions : public ProxyOptions { /* * A wrapper is a proxy with a target object to which it generally forwards - * operations, but may restrict access to certain operations or instrument - * the trap operations in various ways. A wrapper is distinct from a Direct Proxy - * Handler in the sense that it can be "unwrapped" in C++, exposing the underlying + * operations, but may restrict access to certain operations or instrument the + * methods in various ways. A wrapper is distinct from a Direct Proxy Handler + * in the sense that it can be "unwrapped" in C++, exposing the underlying * object (Direct Proxy Handlers have an underlying target object, but don't * expect to expose this object via any kind of unwrapping operation). Callers - * should be careful to avoid unwrapping security wrappers in the wrong context. + * should be careful to avoid unwrapping security wrappers in the wrong + * context. */ class JS_FRIEND_API(Wrapper) : public DirectProxyHandler { @@ -112,10 +113,7 @@ class JS_FRIEND_API(CrossCompartmentWrapper) : public Wrapper : Wrapper(CROSS_COMPARTMENT | aFlags, aHasPrototype, aHasSecurityPolicy) { } - /* ES5 Harmony fundamental wrapper traps. */ - virtual bool preventExtensions(JSContext *cx, HandleObject wrapper) const MOZ_OVERRIDE; - virtual bool getPropertyDescriptor(JSContext *cx, HandleObject wrapper, HandleId id, - MutableHandle desc) const MOZ_OVERRIDE; + /* Standard internal methods. */ virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject wrapper, HandleId id, MutableHandle desc) const MOZ_OVERRIDE; virtual bool defineProperty(JSContext *cx, HandleObject wrapper, HandleId id, @@ -124,22 +122,27 @@ class JS_FRIEND_API(CrossCompartmentWrapper) : public 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; - - /* ES5 Harmony derived wrapper traps. */ + virtual bool isExtensible(JSContext *cx, HandleObject wrapper, bool *extensible) const MOZ_OVERRIDE; + virtual bool preventExtensions(JSContext *cx, HandleObject wrapper) const MOZ_OVERRIDE; + virtual bool getPrototypeOf(JSContext *cx, HandleObject proxy, + MutableHandleObject protop) const MOZ_OVERRIDE; + virtual bool setPrototypeOf(JSContext *cx, HandleObject proxy, HandleObject proto, + bool *bp) const MOZ_OVERRIDE; virtual bool has(JSContext *cx, HandleObject wrapper, HandleId id, bool *bp) const MOZ_OVERRIDE; - virtual bool hasOwn(JSContext *cx, HandleObject wrapper, HandleId id, bool *bp) const MOZ_OVERRIDE; virtual bool get(JSContext *cx, HandleObject wrapper, HandleObject receiver, HandleId id, MutableHandleValue vp) const MOZ_OVERRIDE; virtual bool set(JSContext *cx, HandleObject wrapper, HandleObject receiver, HandleId id, bool strict, MutableHandleValue vp) const MOZ_OVERRIDE; + virtual bool call(JSContext *cx, HandleObject wrapper, const CallArgs &args) const MOZ_OVERRIDE; + 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 desc) const MOZ_OVERRIDE; + virtual bool hasOwn(JSContext *cx, HandleObject wrapper, HandleId id, bool *bp) const MOZ_OVERRIDE; virtual bool keys(JSContext *cx, HandleObject wrapper, AutoIdVector &props) const MOZ_OVERRIDE; virtual bool iterate(JSContext *cx, HandleObject wrapper, unsigned flags, MutableHandleValue vp) const MOZ_OVERRIDE; - - /* Spidermonkey extensions. */ - virtual bool isExtensible(JSContext *cx, HandleObject wrapper, bool *extensible) const MOZ_OVERRIDE; - virtual bool call(JSContext *cx, HandleObject wrapper, const CallArgs &args) const MOZ_OVERRIDE; - virtual bool construct(JSContext *cx, HandleObject wrapper, const CallArgs &args) 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, @@ -151,10 +154,6 @@ class JS_FRIEND_API(CrossCompartmentWrapper) : public Wrapper virtual bool boxedValue_unbox(JSContext *cx, HandleObject proxy, MutableHandleValue vp) const MOZ_OVERRIDE; virtual bool defaultValue(JSContext *cx, HandleObject wrapper, JSType hint, MutableHandleValue vp) const MOZ_OVERRIDE; - virtual bool getPrototypeOf(JSContext *cx, HandleObject proxy, - MutableHandleObject protop) const MOZ_OVERRIDE; - virtual bool setPrototypeOf(JSContext *cx, HandleObject proxy, HandleObject proto, - bool *bp) const MOZ_OVERRIDE; static const CrossCompartmentWrapper singleton; static const CrossCompartmentWrapper singletonWithPrototype; @@ -177,31 +176,32 @@ class JS_FRIEND_API(SecurityWrapper) : public Base : Base(flags, hasPrototype, /* hasSecurityPolicy = */ true) { } - virtual bool isExtensible(JSContext *cx, HandleObject wrapper, bool *extensible) const MOZ_OVERRIDE; - virtual bool preventExtensions(JSContext *cx, HandleObject wrapper) const MOZ_OVERRIDE; virtual bool enter(JSContext *cx, HandleObject wrapper, HandleId id, Wrapper::Action act, bool *bp) const MOZ_OVERRIDE; + + virtual bool defineProperty(JSContext *cx, HandleObject wrapper, HandleId id, + MutableHandle desc) const MOZ_OVERRIDE; + virtual bool isExtensible(JSContext *cx, HandleObject wrapper, bool *extensible) const MOZ_OVERRIDE; + virtual bool preventExtensions(JSContext *cx, HandleObject wrapper) const MOZ_OVERRIDE; + virtual bool setPrototypeOf(JSContext *cx, HandleObject proxy, HandleObject proto, + bool *bp) const MOZ_OVERRIDE; + virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, CallArgs args) const MOZ_OVERRIDE; - virtual bool defaultValue(JSContext *cx, HandleObject wrapper, JSType hint, - MutableHandleValue vp) const MOZ_OVERRIDE; virtual bool objectClassIs(HandleObject obj, ESClassValue classValue, JSContext *cx) const MOZ_OVERRIDE; virtual bool regexp_toShared(JSContext *cx, HandleObject proxy, RegExpGuard *g) const MOZ_OVERRIDE; virtual bool boxedValue_unbox(JSContext *cx, HandleObject proxy, MutableHandleValue vp) const MOZ_OVERRIDE; - virtual bool defineProperty(JSContext *cx, HandleObject wrapper, HandleId id, - MutableHandle desc) const MOZ_OVERRIDE; + virtual bool defaultValue(JSContext *cx, HandleObject wrapper, JSType hint, + MutableHandleValue vp) const MOZ_OVERRIDE; - virtual bool setPrototypeOf(JSContext *cx, HandleObject proxy, HandleObject proto, - bool *bp) const MOZ_OVERRIDE; + // Allow isCallable and isConstructor. They used to be class-level, and so could not be guarded + // against. virtual bool watch(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, JS::HandleObject callable) const MOZ_OVERRIDE; virtual bool unwatch(JSContext *cx, JS::HandleObject proxy, JS::HandleId id) const MOZ_OVERRIDE; - // Allow isCallable and isConstructor. They used to be class-level, and so could not be guarded - // against. - /* * Allow our subclasses to select the superclass behavior they want without * needing to specify an exact superclass. diff --git a/js/src/proxy/DeadObjectProxy.h b/js/src/proxy/DeadObjectProxy.h index 2883c6f2d32..dbd574fb4a0 100644 --- a/js/src/proxy/DeadObjectProxy.h +++ b/js/src/proxy/DeadObjectProxy.h @@ -18,10 +18,7 @@ class DeadObjectProxy : public BaseProxyHandler : BaseProxyHandler(&family) { } - /* ES5 Harmony fundamental wrapper traps. */ - virtual bool preventExtensions(JSContext *cx, HandleObject proxy) const MOZ_OVERRIDE; - virtual bool getPropertyDescriptor(JSContext *cx, HandleObject wrapper, HandleId id, - MutableHandle desc) const MOZ_OVERRIDE; + /* Standard internal methods. */ virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject wrapper, HandleId id, MutableHandle desc) const MOZ_OVERRIDE; virtual bool defineProperty(JSContext *cx, HandleObject wrapper, HandleId id, @@ -30,11 +27,16 @@ class DeadObjectProxy : public BaseProxyHandler 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; - - /* Spidermonkey extensions. */ virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) const MOZ_OVERRIDE; + virtual bool preventExtensions(JSContext *cx, HandleObject proxy) const MOZ_OVERRIDE; + virtual bool getPrototypeOf(JSContext *cx, HandleObject proxy, + MutableHandleObject protop) 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 desc) 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, @@ -46,8 +48,6 @@ class DeadObjectProxy : public BaseProxyHandler virtual bool regexp_toShared(JSContext *cx, HandleObject proxy, RegExpGuard *g) const MOZ_OVERRIDE; virtual bool defaultValue(JSContext *cx, HandleObject obj, JSType hint, MutableHandleValue vp) const MOZ_OVERRIDE; - virtual bool getPrototypeOf(JSContext *cx, HandleObject proxy, - MutableHandleObject protop) const MOZ_OVERRIDE; static const char family; static const DeadObjectProxy singleton; diff --git a/js/src/proxy/Proxy.h b/js/src/proxy/Proxy.h index 90e36fec996..7e26163089b 100644 --- a/js/src/proxy/Proxy.h +++ b/js/src/proxy/Proxy.h @@ -18,19 +18,14 @@ class RegExpGuard; /* * Dispatch point for handlers that executes the appropriate C++ or scripted traps. * - * Important: All proxy traps need either (a) an AutoEnterPolicy in their + * Important: All proxy methods need either (a) an AutoEnterPolicy in their * Proxy::foo entry point below or (b) an override in SecurityWrapper. See bug * 945826 comment 0. */ class Proxy { public: - /* ES5 Harmony fundamental proxy traps. */ - static bool preventExtensions(JSContext *cx, HandleObject proxy); - static bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id, - MutableHandle desc); - static bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id, - MutableHandleValue vp); + /* Standard internal methods. */ static bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id, MutableHandle desc); static bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id, @@ -40,21 +35,26 @@ class Proxy 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); - - /* ES5 Harmony derived proxy traps. */ + static bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible); + static bool preventExtensions(JSContext *cx, HandleObject proxy); + static bool getPrototypeOf(JSContext *cx, HandleObject proxy, MutableHandleObject protop); + static bool setPrototypeOf(JSContext *cx, HandleObject proxy, HandleObject proto, bool *bp); static bool has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp); - static bool hasOwn(JSContext *cx, HandleObject proxy, HandleId id, bool *bp); static bool get(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id, MutableHandleValue vp); static bool set(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id, bool strict, MutableHandleValue vp); - static bool keys(JSContext *cx, HandleObject proxy, AutoIdVector &props); - static bool iterate(JSContext *cx, HandleObject proxy, unsigned flags, MutableHandleValue vp); - - /* Spidermonkey extensions. */ - static bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible); static bool call(JSContext *cx, HandleObject proxy, const CallArgs &args); static bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args); + + /* SpiderMonkey extensions. */ + static bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id, + MutableHandle 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 keys(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); static bool objectClassIs(HandleObject obj, ESClassValue classValue, JSContext *cx); @@ -63,8 +63,6 @@ class Proxy 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); - static bool getPrototypeOf(JSContext *cx, HandleObject proxy, MutableHandleObject protop); - static bool setPrototypeOf(JSContext *cx, HandleObject proxy, HandleObject proto, bool *bp); static bool watch(JSContext *cx, HandleObject proxy, HandleId id, HandleObject callable); static bool unwatch(JSContext *cx, HandleObject proxy, HandleId id); diff --git a/js/src/proxy/ScriptedDirectProxyHandler.h b/js/src/proxy/ScriptedDirectProxyHandler.h index 2918a3ca343..863b42dc0b3 100644 --- a/js/src/proxy/ScriptedDirectProxyHandler.h +++ b/js/src/proxy/ScriptedDirectProxyHandler.h @@ -18,10 +18,7 @@ class ScriptedDirectProxyHandler : public DirectProxyHandler { : DirectProxyHandler(&family) { } - /* ES5 Harmony fundamental proxy traps. */ - virtual bool preventExtensions(JSContext *cx, HandleObject proxy) const MOZ_OVERRIDE; - virtual bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id, - MutableHandle desc) const MOZ_OVERRIDE; + /* Standard internal methods. */ virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id, MutableHandle desc) const MOZ_OVERRIDE; virtual bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id, @@ -30,16 +27,23 @@ class ScriptedDirectProxyHandler : public DirectProxyHandler { 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; - - /* ES5 Harmony derived proxy traps. */ + virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) const MOZ_OVERRIDE; + virtual bool preventExtensions(JSContext *cx, HandleObject proxy) const MOZ_OVERRIDE; virtual bool has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const MOZ_OVERRIDE; - virtual bool hasOwn(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const MOZ_OVERRIDE { - return BaseProxyHandler::hasOwn(cx, proxy, id, bp); - } virtual bool get(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id, MutableHandleValue vp) const MOZ_OVERRIDE; virtual bool set(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id, bool strict, MutableHandleValue vp) 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 proxy, HandleId id, + MutableHandle desc) const MOZ_OVERRIDE; + virtual bool hasOwn(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const MOZ_OVERRIDE { + return BaseProxyHandler::hasOwn(cx, proxy, id, bp); + } + // Kick keys out to getOwnPropertyName and then filter. [[GetOwnProperty]] could potentially // change the enumerability of the target's properties. virtual bool keys(JSContext *cx, HandleObject proxy, AutoIdVector &props) const MOZ_OVERRIDE { @@ -48,12 +52,6 @@ class ScriptedDirectProxyHandler : public DirectProxyHandler { virtual bool iterate(JSContext *cx, HandleObject proxy, unsigned flags, MutableHandleValue vp) const MOZ_OVERRIDE; - /* ES6 Harmony traps */ - virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) const MOZ_OVERRIDE; - - /* Spidermonkey extensions. */ - 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 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 diff --git a/js/src/proxy/ScriptedIndirectProxyHandler.h b/js/src/proxy/ScriptedIndirectProxyHandler.h index ea0218b4f12..c77a9ce4e85 100644 --- a/js/src/proxy/ScriptedIndirectProxyHandler.h +++ b/js/src/proxy/ScriptedIndirectProxyHandler.h @@ -19,10 +19,7 @@ class ScriptedIndirectProxyHandler : public BaseProxyHandler : BaseProxyHandler(&family) { } - /* ES5 Harmony fundamental proxy traps. */ - virtual bool preventExtensions(JSContext *cx, HandleObject proxy) const MOZ_OVERRIDE; - virtual bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id, - MutableHandle desc) const MOZ_OVERRIDE; + /* Standard internal methods. */ virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id, MutableHandle desc) const MOZ_OVERRIDE; virtual bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id, @@ -31,20 +28,21 @@ class ScriptedIndirectProxyHandler : 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; - - /* ES5 Harmony derived proxy traps. */ + virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) const MOZ_OVERRIDE; + virtual bool preventExtensions(JSContext *cx, HandleObject proxy) const MOZ_OVERRIDE; virtual bool has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const MOZ_OVERRIDE; - virtual bool hasOwn(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const MOZ_OVERRIDE; virtual bool get(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id, MutableHandleValue vp) const MOZ_OVERRIDE; virtual bool set(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id, bool strict, MutableHandleValue vp) const MOZ_OVERRIDE; + + /* SpiderMonkey extensions. */ + virtual bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id, + MutableHandle desc) const MOZ_OVERRIDE; + virtual bool hasOwn(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const MOZ_OVERRIDE; virtual bool keys(JSContext *cx, HandleObject proxy, AutoIdVector &props) const MOZ_OVERRIDE; virtual bool iterate(JSContext *cx, HandleObject proxy, unsigned flags, MutableHandleValue vp) const MOZ_OVERRIDE; - - /* Spidermonkey extensions. */ - virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) 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; diff --git a/js/src/vm/ProxyObject.h b/js/src/vm/ProxyObject.h index 1bd1b45ad97..f4a1ac48c64 100644 --- a/js/src/vm/ProxyObject.h +++ b/js/src/vm/ProxyObject.h @@ -91,7 +91,7 @@ class ProxyObject : public JSObject // friend api exposure. // Proxy classes are not allowed to have call or construct hooks directly. Their - // callability is instead decided by a trap call + // callability is instead decided by handler()->isCallable(). return clasp->isProxy() && (clasp->flags & JSCLASS_IMPLEMENTS_BARRIERS) && clasp->trace == proxy_Trace && diff --git a/js/xpconnect/wrappers/AddonWrapper.h b/js/xpconnect/wrappers/AddonWrapper.h index 53de41c730b..38a4573aedb 100644 --- a/js/xpconnect/wrappers/AddonWrapper.h +++ b/js/xpconnect/wrappers/AddonWrapper.h @@ -24,21 +24,20 @@ class AddonWrapper : public Base { public: explicit MOZ_CONSTEXPR AddonWrapper(unsigned flags) : Base(flags) { } - virtual bool getPropertyDescriptor(JSContext *cx, JS::Handle wrapper, - JS::Handle id, - JS::MutableHandle desc) const MOZ_OVERRIDE; virtual bool getOwnPropertyDescriptor(JSContext *cx, JS::Handle wrapper, JS::Handle id, JS::MutableHandle desc) const MOZ_OVERRIDE; - + virtual bool defineProperty(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, + JS::MutableHandle desc) const MOZ_OVERRIDE; + virtual bool delete_(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, bool *bp) const MOZ_OVERRIDE; virtual bool get(JSContext *cx, JS::Handle wrapper, JS::Handle receiver, JS::Handle id, JS::MutableHandle vp) const MOZ_OVERRIDE; virtual bool set(JSContext *cx, JS::HandleObject wrapper, JS::HandleObject receiver, JS::HandleId id, bool strict, JS::MutableHandleValue vp) const MOZ_OVERRIDE; - virtual bool defineProperty(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, - JS::MutableHandle desc) const MOZ_OVERRIDE; - virtual bool delete_(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, bool *bp) const MOZ_OVERRIDE; + virtual bool getPropertyDescriptor(JSContext *cx, JS::Handle wrapper, + JS::Handle id, + JS::MutableHandle desc) const MOZ_OVERRIDE; static const AddonWrapper singleton; }; diff --git a/js/xpconnect/wrappers/ChromeObjectWrapper.h b/js/xpconnect/wrappers/ChromeObjectWrapper.h index 7ce222f6ca1..ce07fa61d72 100644 --- a/js/xpconnect/wrappers/ChromeObjectWrapper.h +++ b/js/xpconnect/wrappers/ChromeObjectWrapper.h @@ -28,33 +28,30 @@ class ChromeObjectWrapper : public ChromeObjectWrapperBase public: MOZ_CONSTEXPR ChromeObjectWrapper() : ChromeObjectWrapperBase(0) {} - /* Custom traps. */ - virtual bool getPropertyDescriptor(JSContext *cx, JS::Handle wrapper, - JS::Handle id, - JS::MutableHandle desc) const MOZ_OVERRIDE; + virtual bool enter(JSContext *cx, JS::Handle wrapper, JS::Handle id, + js::Wrapper::Action act, bool *bp) const MOZ_OVERRIDE; + virtual bool defineProperty(JSContext *cx, JS::Handle wrapper, JS::Handle id, JS::MutableHandle desc) const MOZ_OVERRIDE; - virtual bool set(JSContext *cx, JS::Handle wrapper, - JS::Handle receiver, JS::Handle id, - bool strict, JS::MutableHandle vp) const MOZ_OVERRIDE; - virtual bool has(JSContext *cx, JS::Handle wrapper, JS::Handle id, bool *bp) const MOZ_OVERRIDE; virtual bool get(JSContext *cx, JS::Handle wrapper, JS::Handle receiver, JS::Handle id, JS::MutableHandle vp) const MOZ_OVERRIDE; - + virtual bool set(JSContext *cx, JS::Handle wrapper, + JS::Handle receiver, JS::Handle id, + bool strict, JS::MutableHandle vp) const MOZ_OVERRIDE; virtual bool call(JSContext *cx, JS::Handle wrapper, const JS::CallArgs &args) const MOZ_OVERRIDE; virtual bool construct(JSContext *cx, JS::Handle wrapper, const JS::CallArgs &args) const MOZ_OVERRIDE; + virtual bool getPropertyDescriptor(JSContext *cx, JS::Handle wrapper, + JS::Handle id, + JS::MutableHandle desc) const MOZ_OVERRIDE; virtual bool objectClassIs(JS::Handle obj, js::ESClassValue classValue, JSContext *cx) const MOZ_OVERRIDE; - virtual bool enter(JSContext *cx, JS::Handle wrapper, JS::Handle id, - js::Wrapper::Action act, bool *bp) const MOZ_OVERRIDE; - // NB: One might think we'd need to implement enumerate(), keys(), iterate(), // and getPropertyKeys() here. However, ES5 built-in properties aren't // enumerable (and SpiderMonkey's implementation seems to match the spec diff --git a/js/xpconnect/wrappers/FilteringWrapper.h b/js/xpconnect/wrappers/FilteringWrapper.h index 2b5b72da915..239c08f5c40 100644 --- a/js/xpconnect/wrappers/FilteringWrapper.h +++ b/js/xpconnect/wrappers/FilteringWrapper.h @@ -25,9 +25,9 @@ class FilteringWrapper : public Base { public: MOZ_CONSTEXPR explicit FilteringWrapper(unsigned flags) : Base(flags) {} - virtual bool getPropertyDescriptor(JSContext *cx, JS::Handle wrapper, - JS::Handle id, - JS::MutableHandle desc) const MOZ_OVERRIDE; + virtual bool enter(JSContext *cx, JS::Handle wrapper, JS::Handle id, + js::Wrapper::Action act, bool *bp) const MOZ_OVERRIDE; + virtual bool getOwnPropertyDescriptor(JSContext *cx, JS::Handle wrapper, JS::Handle id, JS::MutableHandle desc) const MOZ_OVERRIDE; @@ -35,6 +35,10 @@ class FilteringWrapper : public Base { 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 keys(JSContext *cx, JS::Handle wrapper, JS::AutoIdVector &props) const MOZ_OVERRIDE; virtual bool iterate(JSContext *cx, JS::Handle wrapper, unsigned flags, @@ -45,9 +49,6 @@ class FilteringWrapper : public Base { virtual bool defaultValue(JSContext *cx, JS::Handle obj, JSType hint, JS::MutableHandleValue vp) const MOZ_OVERRIDE; - virtual bool enter(JSContext *cx, JS::Handle wrapper, JS::Handle id, - js::Wrapper::Action act, bool *bp) const MOZ_OVERRIDE; - static const FilteringWrapper singleton; }; @@ -60,27 +61,24 @@ class CrossOriginXrayWrapper : public SecurityXrayDOM { public: explicit CrossOriginXrayWrapper(unsigned flags); - virtual bool getPropertyDescriptor(JSContext *cx, JS::Handle wrapper, - JS::Handle id, - JS::MutableHandle desc) const MOZ_OVERRIDE; virtual bool getOwnPropertyDescriptor(JSContext *cx, JS::Handle wrapper, JS::Handle id, JS::MutableHandle desc) const MOZ_OVERRIDE; - - virtual bool ownPropertyKeys(JSContext *cx, JS::Handle wrapper, - JS::AutoIdVector &props) const MOZ_OVERRIDE; - virtual bool defineProperty(JSContext *cx, JS::Handle wrapper, JS::Handle id, JS::MutableHandle desc) const MOZ_OVERRIDE; + virtual bool ownPropertyKeys(JSContext *cx, JS::Handle wrapper, + 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 getPropertyDescriptor(JSContext *cx, JS::Handle wrapper, + JS::Handle id, + JS::MutableHandle desc) const MOZ_OVERRIDE; }; } diff --git a/js/xpconnect/wrappers/WaiveXrayWrapper.h b/js/xpconnect/wrappers/WaiveXrayWrapper.h index b62a7e5af04..816a53a05d8 100644 --- a/js/xpconnect/wrappers/WaiveXrayWrapper.h +++ b/js/xpconnect/wrappers/WaiveXrayWrapper.h @@ -17,28 +17,25 @@ class WaiveXrayWrapper : public js::CrossCompartmentWrapper { public: explicit MOZ_CONSTEXPR WaiveXrayWrapper(unsigned flags) : js::CrossCompartmentWrapper(flags) { } - virtual bool getPropertyDescriptor(JSContext *cx, JS::Handle wrapper, - JS::Handle id, - JS::MutableHandle desc) const MOZ_OVERRIDE; virtual bool getOwnPropertyDescriptor(JSContext *cx, JS::Handle wrapper, JS::Handle id, JS::MutableHandle desc) const MOZ_OVERRIDE; + virtual bool getPrototypeOf(JSContext *cx, JS::Handle wrapper, + JS::MutableHandle protop) const MOZ_OVERRIDE; virtual bool get(JSContext *cx, JS::Handle wrapper, JS::Handle receiver, JS::Handle id, JS::MutableHandle vp) const MOZ_OVERRIDE; - virtual bool iterate(JSContext *cx, JS::Handle proxy, unsigned flags, - JS::MutableHandle vp) const MOZ_OVERRIDE; - - virtual bool call(JSContext *cx, JS::Handle wrapper, const JS::CallArgs &args) const MOZ_OVERRIDE; virtual bool construct(JSContext *cx, JS::Handle wrapper, const JS::CallArgs &args) const MOZ_OVERRIDE; + virtual bool iterate(JSContext *cx, JS::Handle proxy, unsigned flags, + JS::MutableHandle vp) const MOZ_OVERRIDE; virtual bool nativeCall(JSContext *cx, JS::IsAcceptableThis test, JS::NativeImpl impl, JS::CallArgs args) const MOZ_OVERRIDE; - - virtual bool getPrototypeOf(JSContext *cx, JS::Handle wrapper, - JS::MutableHandle protop) const MOZ_OVERRIDE; + virtual bool getPropertyDescriptor(JSContext *cx, JS::Handle wrapper, + JS::Handle id, + JS::MutableHandle desc) const MOZ_OVERRIDE; static const WaiveXrayWrapper singleton; }; diff --git a/js/xpconnect/wrappers/XrayWrapper.h b/js/xpconnect/wrappers/XrayWrapper.h index 1d5898ac4e4..c41c377b0f6 100644 --- a/js/xpconnect/wrappers/XrayWrapper.h +++ b/js/xpconnect/wrappers/XrayWrapper.h @@ -404,11 +404,7 @@ class XrayWrapper : public Base { : Base(flags | WrapperFactory::IS_XRAY_WRAPPER_FLAG, Traits::HasPrototype) { }; - /* Fundamental proxy traps. */ - virtual bool isExtensible(JSContext *cx, JS::Handle wrapper, bool *extensible) const MOZ_OVERRIDE; - virtual bool preventExtensions(JSContext *cx, JS::Handle wrapper) const MOZ_OVERRIDE; - virtual bool getPropertyDescriptor(JSContext *cx, JS::Handle wrapper, JS::Handle id, - JS::MutableHandle desc) const MOZ_OVERRIDE; + /* Standard internal methods. */ virtual bool getOwnPropertyDescriptor(JSContext *cx, JS::Handle wrapper, JS::Handle id, JS::MutableHandle desc) const MOZ_OVERRIDE; virtual bool defineProperty(JSContext *cx, JS::Handle wrapper, JS::Handle id, @@ -418,14 +414,26 @@ class XrayWrapper : public Base { 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; - - /* Derived proxy traps. */ + virtual bool isExtensible(JSContext *cx, JS::Handle wrapper, bool *extensible) const MOZ_OVERRIDE; + virtual bool preventExtensions(JSContext *cx, JS::Handle wrapper) 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, + JS::HandleObject proto, bool *bp) const MOZ_OVERRIDE; + virtual bool has(JSContext *cx, JS::Handle wrapper, JS::Handle id, + bool *bp) const MOZ_OVERRIDE; virtual bool get(JSContext *cx, JS::Handle wrapper, JS::Handle receiver, JS::Handle id, JS::MutableHandle vp) const MOZ_OVERRIDE; virtual bool set(JSContext *cx, JS::Handle wrapper, JS::Handle receiver, JS::Handle id, bool strict, JS::MutableHandle vp) const MOZ_OVERRIDE; - virtual bool has(JSContext *cx, JS::Handle wrapper, JS::Handle id, - bool *bp) const MOZ_OVERRIDE; + virtual bool call(JSContext *cx, JS::Handle wrapper, + const JS::CallArgs &args) const MOZ_OVERRIDE; + virtual bool construct(JSContext *cx, JS::Handle wrapper, + const JS::CallArgs &args) const MOZ_OVERRIDE; + + /* SpiderMonkey extensions. */ + virtual bool getPropertyDescriptor(JSContext *cx, JS::Handle wrapper, JS::Handle id, + JS::MutableHandle desc) const MOZ_OVERRIDE; virtual bool hasOwn(JSContext *cx, JS::Handle wrapper, JS::Handle id, bool *bp) const MOZ_OVERRIDE; virtual bool keys(JSContext *cx, JS::Handle wrapper, @@ -433,21 +441,11 @@ class XrayWrapper : public Base { virtual bool iterate(JSContext *cx, JS::Handle wrapper, unsigned flags, JS::MutableHandle vp) const MOZ_OVERRIDE; - virtual bool call(JSContext *cx, JS::Handle wrapper, - const JS::CallArgs &args) const MOZ_OVERRIDE; - virtual bool construct(JSContext *cx, JS::Handle wrapper, - const JS::CallArgs &args) 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; - virtual bool getPrototypeOf(JSContext *cx, JS::HandleObject wrapper, - JS::MutableHandleObject protop) const MOZ_OVERRIDE; - virtual bool setPrototypeOf(JSContext *cx, JS::HandleObject wrapper, - JS::HandleObject proto, bool *bp) const MOZ_OVERRIDE; - static const XrayWrapper singleton; private: @@ -491,23 +489,24 @@ public: { } - virtual bool getPropertyDescriptor(JSContext *cx, JS::Handle proxy, - JS::Handle id, - JS::MutableHandle desc) const MOZ_OVERRIDE; virtual bool getOwnPropertyDescriptor(JSContext *cx, JS::Handle proxy, JS::Handle id, JS::MutableHandle desc) const MOZ_OVERRIDE; - // We just forward the derived traps to the BaseProxyHandler versions which - // implement them in terms of the fundamental traps. + // We just forward the high-level methods to the BaseProxyHandler versions + // which implement them in terms of lower-level methods. virtual bool has(JSContext *cx, JS::Handle proxy, JS::Handle id, bool *bp) const MOZ_OVERRIDE; - virtual bool hasOwn(JSContext *cx, JS::Handle proxy, JS::Handle id, - bool *bp) const MOZ_OVERRIDE; virtual bool get(JSContext *cx, JS::Handle proxy, JS::Handle receiver, JS::Handle id, JS::MutableHandle vp) const MOZ_OVERRIDE; virtual bool set(JSContext *cx, JS::Handle proxy, JS::Handle receiver, JS::Handle id, bool strict, JS::MutableHandle vp) const MOZ_OVERRIDE; + + virtual bool getPropertyDescriptor(JSContext *cx, JS::Handle proxy, + JS::Handle id, + JS::MutableHandle desc) const MOZ_OVERRIDE; + virtual bool hasOwn(JSContext *cx, JS::Handle proxy, JS::Handle id, + bool *bp) const MOZ_OVERRIDE; virtual bool keys(JSContext *cx, JS::Handle proxy, JS::AutoIdVector &props) const MOZ_OVERRIDE; virtual bool iterate(JSContext *cx, JS::Handle proxy, unsigned flags,