Bug 803068 - Remove IndirectProxyHandler. r=ejpbruel
authorBobby Holley <bobbyholley@gmail.com>
Mon, 29 Oct 2012 16:52:53 +0100
changeset 111811 7488590fc194f2a68dbb67935b28d209c1c155bd
parent 111810 da2e3ebd1c26734fa6f685623aafd0b5b421e474
child 111812 44d874f51c28266628fd367311002929b8c8197a
push id93
push usernmatsakis@mozilla.com
push dateWed, 31 Oct 2012 21:26:57 +0000
reviewersejpbruel
bugs803068
milestone19.0a1
Bug 803068 - Remove IndirectProxyHandler. r=ejpbruel
js/src/jsproxy.cpp
js/src/jsproxy.h
js/src/jswrapper.cpp
--- a/js/src/jsproxy.cpp
+++ b/js/src/jsproxy.cpp
@@ -369,24 +369,21 @@ BaseProxyHandler::weakmapKeyDelegate(JSO
 bool
 BaseProxyHandler::getPrototypeOf(JSContext *cx, JSObject *proxy, JSObject **proto)
 {
     // The default implementation here just uses proto of the proxy object.
     *proto = proxy->getTaggedProto().toObjectOrNull();
     return true;
 }
 
-IndirectProxyHandler::IndirectProxyHandler(void *family) : BaseProxyHandler(family)
-{
-}
 
 bool
-IndirectProxyHandler::getPropertyDescriptor(JSContext *cx, JSObject *proxy,
-                                            jsid id, bool set,
-                                            PropertyDescriptor *desc)
+DirectProxyHandler::getPropertyDescriptor(JSContext *cx, JSObject *proxy,
+                                          jsid id, bool set,
+                                          PropertyDescriptor *desc)
 {
     RootedObject target(cx, GetProxyTargetObject(proxy));
     return JS_GetPropertyDescriptorById(cx, target, id, JSRESOLVE_QUALIFIED, desc);
 }
 
 static bool
 GetOwnPropertyDescriptor(JSContext *cx, HandleObject obj, jsid id, unsigned flags,
                          JSPropertyDescriptor *desc)
@@ -401,159 +398,159 @@ GetOwnPropertyDescriptor(JSContext *cx, 
     if (!JS_GetPropertyDescriptorById(cx, obj, id, flags, desc))
         return false;
     if (desc->obj != obj)
         desc->obj = NULL;
     return true;
 }
 
 bool
-IndirectProxyHandler::getOwnPropertyDescriptor(JSContext *cx, JSObject *proxy,
-                                               jsid id, bool set,
-                                               PropertyDescriptor *desc)
+DirectProxyHandler::getOwnPropertyDescriptor(JSContext *cx, JSObject *proxy,
+                                             jsid id, bool set,
+                                             PropertyDescriptor *desc)
 {
     RootedObject target(cx, GetProxyTargetObject(proxy));
     return GetOwnPropertyDescriptor(cx, target, id, JSRESOLVE_QUALIFIED, desc);
 }
 
 bool
-IndirectProxyHandler::defineProperty(JSContext *cx, JSObject *proxy, jsid id_,
-                                     PropertyDescriptor *desc)
+DirectProxyHandler::defineProperty(JSContext *cx, JSObject *proxy, jsid id_,
+                                   PropertyDescriptor *desc)
 {
     RootedObject obj(cx, GetProxyTargetObject(proxy));
     Rooted<jsid> id(cx, id_);
     Rooted<Value> v(cx, desc->value);
     return CheckDefineProperty(cx, obj, id, v, desc->getter, desc->setter, desc->attrs) &&
            JS_DefinePropertyById(cx, obj, id, v, desc->getter, desc->setter, desc->attrs);
 }
 
 bool
-IndirectProxyHandler::getOwnPropertyNames(JSContext *cx, JSObject *proxy,
-                                          AutoIdVector &props)
+DirectProxyHandler::getOwnPropertyNames(JSContext *cx, JSObject *proxy,
+                                        AutoIdVector &props)
 {
     RootedObject target(cx, GetProxyTargetObject(proxy));
     return GetPropertyNames(cx, target, JSITER_OWNONLY | JSITER_HIDDEN, &props);
 }
 
 bool
-IndirectProxyHandler::delete_(JSContext *cx, JSObject *proxy, jsid id, bool *bp)
+DirectProxyHandler::delete_(JSContext *cx, JSObject *proxy, jsid id, bool *bp)
 {
     Value v;
     RootedObject target(cx, GetProxyTargetObject(proxy));
     if (!JS_DeletePropertyById2(cx, target, id, &v))
         return false;
     JSBool b;
     if (!JS_ValueToBoolean(cx, v, &b))
         return false;
     *bp = !!b;
     return true;
 }
 
 bool
-IndirectProxyHandler::enumerate(JSContext *cx, JSObject *proxy,
-                                AutoIdVector &props)
+DirectProxyHandler::enumerate(JSContext *cx, JSObject *proxy,
+                              AutoIdVector &props)
 {
     RootedObject target(cx, GetProxyTargetObject(proxy));
     return GetPropertyNames(cx, target, 0, &props);
 }
 
 bool
-IndirectProxyHandler::nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl,
-                                    CallArgs args)
+DirectProxyHandler::nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl,
+                               CallArgs args)
 {
     args.setThis(ObjectValue(*GetProxyTargetObject(&args.thisv().toObject())));
     if (!test(args.thisv())) {
         ReportIncompatible(cx, args);
         return false;
     }
 
     return CallNativeImpl(cx, impl, args);
 }
 
 bool
-IndirectProxyHandler::hasInstance(JSContext *cx, HandleObject proxy, MutableHandleValue v,
-                                  bool *bp)
+DirectProxyHandler::hasInstance(JSContext *cx, HandleObject proxy, MutableHandleValue v,
+                                bool *bp)
 {
     JSBool b;
     RootedObject target(cx, GetProxyTargetObject(proxy));
     if (!JS_HasInstance(cx, target, v, &b))
         return false;
     *bp = !!b;
     return true;
 }
 
 JSType
-IndirectProxyHandler::typeOf(JSContext *cx, JSObject *proxy)
+DirectProxyHandler::typeOf(JSContext *cx, JSObject *proxy)
 {
     return TypeOfValue(cx, ObjectValue(*GetProxyTargetObject(proxy)));
 }
 
 bool
-IndirectProxyHandler::objectClassIs(JSObject *proxy, ESClassValue classValue,
-                                    JSContext *cx)
+DirectProxyHandler::objectClassIs(JSObject *proxy, ESClassValue classValue,
+                                  JSContext *cx)
 {
     return ObjectClassIs(*GetProxyTargetObject(proxy), classValue, cx);
 }
 
 JSString *
-IndirectProxyHandler::obj_toString(JSContext *cx, JSObject *proxy)
+DirectProxyHandler::obj_toString(JSContext *cx, JSObject *proxy)
 {
     return obj_toStringHelper(cx, GetProxyTargetObject(proxy));
 }
 
 JSString *
-IndirectProxyHandler::fun_toString(JSContext *cx, JSObject *proxy,
-                                   unsigned indent)
+DirectProxyHandler::fun_toString(JSContext *cx, JSObject *proxy,
+                                 unsigned indent)
 {
     RootedObject target(cx, GetProxyTargetObject(proxy));
     return fun_toStringHelper(cx, target, indent);
 }
 
 bool
-IndirectProxyHandler::regexp_toShared(JSContext *cx, JSObject *proxy,
-                                      RegExpGuard *g)
+DirectProxyHandler::regexp_toShared(JSContext *cx, JSObject *proxy,
+                                    RegExpGuard *g)
 {
     return RegExpToShared(cx, *GetProxyTargetObject(proxy), g);
 }
 
 bool
-IndirectProxyHandler::defaultValue(JSContext *cx, JSObject *proxy, JSType hint,
-                                   Value *vp)
+DirectProxyHandler::defaultValue(JSContext *cx, JSObject *proxy, JSType hint,
+                                 Value *vp)
 {
     *vp = ObjectValue(*GetProxyTargetObject(proxy));
     if (hint == JSTYPE_VOID)
         return ToPrimitive(cx, vp);
     return ToPrimitive(cx, hint, vp);
 }
 
 bool
-IndirectProxyHandler::iteratorNext(JSContext *cx, JSObject *proxy, Value *vp)
+DirectProxyHandler::iteratorNext(JSContext *cx, JSObject *proxy, Value *vp)
 {
     Rooted<JSObject*> target(cx, GetProxyTargetObject(proxy));
     RootedValue value(cx);
     if (!js_IteratorMore(cx, target, &value))
         return false;
     *vp = value;
     if (vp->toBoolean()) {
         *vp = cx->iterValue;
         cx->iterValue = UndefinedValue();
     } else {
         *vp = MagicValue(JS_NO_ITER_VALUE);
     }
     return true;
 }
 
 JSObject *
-IndirectProxyHandler::weakmapKeyDelegate(JSObject *proxy)
+DirectProxyHandler::weakmapKeyDelegate(JSObject *proxy)
 {
     return UnwrapObject(proxy);
 }
 
 DirectProxyHandler::DirectProxyHandler(void *family)
-  : IndirectProxyHandler(family)
+  : BaseProxyHandler(family)
 {
 }
 
 bool
 DirectProxyHandler::has(JSContext *cx, JSObject *proxy, jsid id, bool *bp)
 {
     JSBool found;
     RootedObject target(cx, GetProxyTargetObject(proxy));
--- a/js/src/jsproxy.h
+++ b/js/src/jsproxy.h
@@ -21,27 +21,29 @@ class JS_FRIEND_API(Wrapper);
  * provided by a C++ object stored on the proxy, known as its handler.
  *
  * 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.
  *
  * 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.
+ * 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.
  *
  * 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:
  *
  * BaseProxyHandler
  * |
- * IndirectProxyHandler
- * |                    
  * DirectProxyHandler
+ * |
+ * Wrapper
  */
 
 /*
  * 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.
@@ -125,27 +127,24 @@ class JS_FRIEND_API(BaseProxyHandler) {
                                      uint32_t index, Value *vp, bool *present);
     virtual bool getPrototypeOf(JSContext *cx, JSObject *proxy, JSObject **protop);
 
     /* See comment for weakmapKeyDelegateOp in jsclass.h. */
     virtual JSObject *weakmapKeyDelegate(JSObject *proxy);
 };
 
 /*
- * IndirectProxyHandler assumes that a target exists. Moreover, it assumes the
- * target is a JSObject. Consequently, it provides default implementations for
- * the fundamental traps that forward their behavior to the target. The derived
- * traps, however, are inherited from BaseProxyHandler, and therefore still
- * implemented in terms of the fundamental ones. This allows consumers of this
- * class to define custom behavior without implementing the entire gamut of
- * proxy traps. 
+ * DirectProxyHandler includes a notion of a target object. All traps 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.
  */
-class JS_PUBLIC_API(IndirectProxyHandler) : public BaseProxyHandler {
-  public:
-    explicit IndirectProxyHandler(void *family);
+class JS_PUBLIC_API(DirectProxyHandler) : public BaseProxyHandler {
+public:
+    explicit DirectProxyHandler(void *family);
 
     /* ES5 Harmony fundamental proxy traps. */
     virtual bool getPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id,
                                        bool set,
                                        PropertyDescriptor *desc) MOZ_OVERRIDE;
     virtual bool getOwnPropertyDescriptor(JSContext *cx, JSObject *proxy,
                                           jsid id, bool set,
                                           PropertyDescriptor *desc) MOZ_OVERRIDE;
@@ -153,16 +152,30 @@ class JS_PUBLIC_API(IndirectProxyHandler
                                 PropertyDescriptor *desc) MOZ_OVERRIDE;
     virtual bool getOwnPropertyNames(JSContext *cx, JSObject *proxy,
                                      AutoIdVector &props) MOZ_OVERRIDE;
     virtual bool delete_(JSContext *cx, JSObject *proxy, jsid id,
                          bool *bp) MOZ_OVERRIDE;
     virtual bool enumerate(JSContext *cx, JSObject *proxy,
                            AutoIdVector &props) MOZ_OVERRIDE;
 
+    /* ES5 Harmony derived proxy traps. */
+    virtual bool has(JSContext *cx, JSObject *proxy, jsid id,
+                     bool *bp) MOZ_OVERRIDE;
+    virtual bool hasOwn(JSContext *cx, JSObject *proxy, jsid id,
+                        bool *bp) MOZ_OVERRIDE;
+    virtual bool get(JSContext *cx, JSObject *proxy, JSObject *receiver,
+                     jsid id, Value *vp) MOZ_OVERRIDE;
+    virtual bool set(JSContext *cx, JSObject *proxy, JSObject *receiver,
+                     jsid id, bool strict, Value *vp) MOZ_OVERRIDE;
+    virtual bool keys(JSContext *cx, JSObject *proxy,
+                      AutoIdVector &props) MOZ_OVERRIDE;
+    virtual bool iterate(JSContext *cx, JSObject *proxy, unsigned flags,
+                         Value *vp) MOZ_OVERRIDE;
+
     /* Spidermonkey extensions. */
     virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl,
                             CallArgs args) MOZ_OVERRIDE;
     virtual bool hasInstance(JSContext *cx, HandleObject proxy, MutableHandleValue v,
                              bool *bp) MOZ_OVERRIDE;
     virtual JSType typeOf(JSContext *cx, JSObject *proxy) MOZ_OVERRIDE;
     virtual bool objectClassIs(JSObject *obj, ESClassValue classValue,
                                JSContext *cx) MOZ_OVERRIDE;
@@ -173,43 +186,16 @@ class JS_PUBLIC_API(IndirectProxyHandler
                                  RegExpGuard *g) MOZ_OVERRIDE;
     virtual bool defaultValue(JSContext *cx, JSObject *obj, JSType hint,
                               Value *vp) MOZ_OVERRIDE;
     virtual bool iteratorNext(JSContext *cx, JSObject *proxy,
                               Value *vp) MOZ_OVERRIDE;
     virtual JSObject *weakmapKeyDelegate(JSObject *proxy);
 };
 
-/*
- * DirectProxyHandler has the same assumptions about the target as its base,
- * IndirectProxyHandler. Its fundamental traps are inherited from this class,
- * and therefore forward their behavior to the target. The derived traps,
- * however, are overrided so that, they too, forward their behavior to the
- * target. This allows consumers of this class to forward to another object as
- * transparently as possible.
- */
-class JS_PUBLIC_API(DirectProxyHandler) : public IndirectProxyHandler {
-public:
-    explicit DirectProxyHandler(void *family);
-
-    /* ES5 Harmony derived proxy traps. */
-    virtual bool has(JSContext *cx, JSObject *proxy, jsid id,
-                     bool *bp) MOZ_OVERRIDE;
-    virtual bool hasOwn(JSContext *cx, JSObject *proxy, jsid id,
-                        bool *bp) MOZ_OVERRIDE;
-    virtual bool get(JSContext *cx, JSObject *proxy, JSObject *receiver,
-                     jsid id, Value *vp) MOZ_OVERRIDE;
-    virtual bool set(JSContext *cx, JSObject *proxy, JSObject *receiver,
-                     jsid id, bool strict, Value *vp) MOZ_OVERRIDE;
-    virtual bool keys(JSContext *cx, JSObject *proxy,
-                      AutoIdVector &props) MOZ_OVERRIDE;
-    virtual bool iterate(JSContext *cx, JSObject *proxy, unsigned flags,
-                         Value *vp) MOZ_OVERRIDE;
-};
-
 /* Dispatch point for handlers that executes the appropriate C++ or scripted traps. */
 class Proxy {
   public:
     /* ES5 Harmony fundamental proxy traps. */
     static bool getPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id, bool set,
                                       PropertyDescriptor *desc);
     static bool getPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id, bool set, Value *vp);
     static bool getOwnPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id, bool set,
--- a/js/src/jswrapper.cpp
+++ b/js/src/jswrapper.cpp
@@ -290,55 +290,55 @@ DirectWrapper::iterate(JSContext *cx, JS
     GET(DirectProxyHandler::iterate(cx, wrapper, flags, vp));
 }
 
 bool
 DirectWrapper::call(JSContext *cx, JSObject *wrapper, unsigned argc, Value *vp)
 {
     vp->setUndefined(); // default result if we refuse to perform this action
     const jsid id = JSID_VOID;
-    CHECKED(IndirectProxyHandler::call(cx, wrapper, argc, vp), CALL);
+    CHECKED(DirectProxyHandler::call(cx, wrapper, argc, vp), CALL);
 }
 
 bool
 DirectWrapper::construct(JSContext *cx, JSObject *wrapper, unsigned argc, Value *argv, Value *vp)
 {
     vp->setUndefined(); // default result if we refuse to perform this action
     const jsid id = JSID_VOID;
-    CHECKED(IndirectProxyHandler::construct(cx, wrapper, argc, argv, vp), CALL);
+    CHECKED(DirectProxyHandler::construct(cx, wrapper, argc, argv, vp), CALL);
 }
 
 bool
 DirectWrapper::nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, CallArgs args)
 {
     const jsid id = JSID_VOID;
     Rooted<JSObject*> wrapper(cx, &args.thisv().toObject());
-    CHECKED(IndirectProxyHandler::nativeCall(cx, test, impl, args), CALL);
+    CHECKED(DirectProxyHandler::nativeCall(cx, test, impl, args), CALL);
 }
 
 bool
 DirectWrapper::hasInstance(JSContext *cx, HandleObject wrapper, MutableHandleValue v, bool *bp)
 {
     *bp = false; // default result if we refuse to perform this action
     const jsid id = JSID_VOID;
-    GET(IndirectProxyHandler::hasInstance(cx, wrapper, v, bp));
+    GET(DirectProxyHandler::hasInstance(cx, wrapper, v, bp));
 }
 
 JSString *
 DirectWrapper::obj_toString(JSContext *cx, JSObject *wrapper)
 {
     bool status;
     if (!enter(cx, wrapper, JSID_VOID, GET, &status)) {
         if (status) {
             // Perform some default behavior that doesn't leak any information.
             return JS_NewStringCopyZ(cx, "[object Object]");
         }
         return NULL;
     }
-    JSString *str = IndirectProxyHandler::obj_toString(cx, wrapper);
+    JSString *str = DirectProxyHandler::obj_toString(cx, wrapper);
     return str;
 }
 
 JSString *
 DirectWrapper::fun_toString(JSContext *cx, JSObject *wrapper, unsigned indent)
 {
     bool status;
     if (!enter(cx, wrapper, JSID_VOID, GET, &status)) {
@@ -346,17 +346,17 @@ DirectWrapper::fun_toString(JSContext *c
             // Perform some default behavior that doesn't leak any information.
             if (wrapper->isCallable())
                 return JS_NewStringCopyZ(cx, "function () {\n    [native code]\n}");
             ReportIsNotFunction(cx, ObjectValue(*wrapper));
             return NULL;
         }
         return NULL;
     }
-    JSString *str = IndirectProxyHandler::fun_toString(cx, wrapper, indent);
+    JSString *str = DirectProxyHandler::fun_toString(cx, wrapper, indent);
     return str;
 }
 
 DirectWrapper DirectWrapper::singleton((unsigned)0);
 DirectWrapper DirectWrapper::singletonWithPrototype((unsigned)0, true);
 
 /* Compartments. */
 
@@ -739,17 +739,17 @@ CrossCompartmentWrapper::defaultValue(JS
     return cx->compartment->wrap(cx, vp);
 }
 
 bool
 CrossCompartmentWrapper::iteratorNext(JSContext *cx, JSObject *wrapper, Value *vp)
 {
     PIERCE(cx, wrapper, GET,
            NOTHING,
-           IndirectProxyHandler::iteratorNext(cx, wrapper, vp),
+           DirectProxyHandler::iteratorNext(cx, wrapper, vp),
            cx->compartment->wrap(cx, vp));
 }
 
 bool
 CrossCompartmentWrapper::getPrototypeOf(JSContext *cx, JSObject *proxy, JSObject **protop)
 {
     assertSameCompartment(cx, proxy);