Bug 945826 - Trap overrides and comments. r=jorendorff
authorBobby Holley <bobbyholley@gmail.com>
Thu, 05 Dec 2013 12:58:20 -0800
changeset 173771 a3f7a5b3bb3a099b521d5050a044f64e5e52e494
parent 173770 ec5f9193d1786e68bb1b8ebb846caa93e0eec78a
child 173772 20e4d6b3c819cdf36a25dc253217d55611104db2
push id3224
push userlsblakk@mozilla.com
push dateTue, 04 Feb 2014 01:06:49 +0000
treeherdermozilla-beta@60c04d0987f1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjorendorff
bugs945826
milestone28.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 945826 - Trap overrides and comments. r=jorendorff
js/src/jsproxy.h
js/src/jswrapper.cpp
js/src/jswrapper.h
--- a/js/src/jsproxy.h
+++ b/js/src/jsproxy.h
@@ -59,16 +59,20 @@ class JS_FRIEND_API(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.
+ *
+ * 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.
  */
 class JS_FRIEND_API(BaseProxyHandler)
 {
     const void *mFamily;
     bool mHasPrototype;
     bool mHasPolicy;
   protected:
     // Subclasses may set this in their constructor.
@@ -178,16 +182,20 @@ class JS_FRIEND_API(BaseProxyHandler)
     virtual bool isScripted() { return false; }
 };
 
 /*
  * 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.
+ *
+ * Important: If you add a trap 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
 {
   public:
     explicit DirectProxyHandler(const void *family);
 
     /* ES5 Harmony fundamental proxy traps. */
     virtual bool preventExtensions(JSContext *cx, HandleObject proxy) MOZ_OVERRIDE;
@@ -232,17 +240,23 @@ class JS_PUBLIC_API(DirectProxyHandler) 
     virtual const char *className(JSContext *cx, HandleObject proxy) MOZ_OVERRIDE;
     virtual JSString *fun_toString(JSContext *cx, HandleObject proxy,
                                    unsigned indent) MOZ_OVERRIDE;
     virtual bool regexp_toShared(JSContext *cx, HandleObject proxy,
                                  RegExpGuard *g) MOZ_OVERRIDE;
     virtual JSObject *weakmapKeyDelegate(JSObject *proxy);
 };
 
-/* Dispatch point for handlers that executes the appropriate C++ or scripted traps. */
+/*
+ * Dispatch point for handlers that executes the appropriate C++ or scripted traps.
+ *
+ * Important: All proxy traps 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<JSPropertyDescriptor> desc, unsigned flags);
     static bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, unsigned flags, HandleId id,
--- a/js/src/jswrapper.cpp
+++ b/js/src/jswrapper.cpp
@@ -684,16 +684,35 @@ SecurityWrapper<Base>::defineProperty(JS
         JS_ReportErrorNumberUC(cx, js_GetErrorMessage, nullptr,
                                JSMSG_ACCESSOR_DEF_DENIED, prop);
         return false;
     }
 
     return Base::defineProperty(cx, wrapper, id, desc);
 }
 
+template <class Base>
+bool
+SecurityWrapper<Base>::watch(JSContext *cx, HandleObject proxy,
+                             HandleId id, HandleObject callable)
+{
+    JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_UNWRAP_DENIED);
+    return false;
+}
+
+template <class Base>
+bool
+SecurityWrapper<Base>::unwatch(JSContext *cx, HandleObject proxy,
+                               HandleId id)
+{
+    JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_UNWRAP_DENIED);
+    return false;
+}
+
+
 template class js::SecurityWrapper<Wrapper>;
 template class js::SecurityWrapper<CrossCompartmentWrapper>;
 
 DeadObjectProxy::DeadObjectProxy()
   : BaseProxyHandler(&sDeadObjectFamily)
 {
 }
 
--- a/js/src/jswrapper.h
+++ b/js/src/jswrapper.h
@@ -150,16 +150,20 @@ class JS_FRIEND_API(SecurityWrapper) : p
     virtual bool defaultValue(JSContext *cx, HandleObject wrapper, JSType hint,
                               MutableHandleValue vp) MOZ_OVERRIDE;
     virtual bool objectClassIs(HandleObject obj, ESClassValue classValue,
                                JSContext *cx) MOZ_OVERRIDE;
     virtual bool regexp_toShared(JSContext *cx, HandleObject proxy, RegExpGuard *g) MOZ_OVERRIDE;
     virtual bool defineProperty(JSContext *cx, HandleObject wrapper, HandleId id,
                                 MutableHandle<JSPropertyDescriptor> desc) MOZ_OVERRIDE;
 
+    virtual bool watch(JSContext *cx, JS::HandleObject proxy, JS::HandleId id,
+                       JS::HandleObject callable) MOZ_OVERRIDE;
+    virtual bool unwatch(JSContext *cx, JS::HandleObject proxy, JS::HandleId id) MOZ_OVERRIDE;
+
     /*
      * Allow our subclasses to select the superclass behavior they want without
      * needing to specify an exact superclass.
      */
     typedef Base Permissive;
     typedef SecurityWrapper<Base> Restrictive;
 };