Bug 1027402 - Part 2: Mark Proxy Handler instances as const. (r=bholley)
☠☠ backed out by 41e50e705f51 ☠ ☠
authorEric Faust <efaustbmo@gmail.com>
Fri, 27 Jun 2014 04:44:04 -0700
changeset 212019 346912776f973e9f5375cc49c4cac6ef374a3e75
parent 212018 2c64038181063d93859477d05edd2f2c0fd3e173
child 212020 285c853fedfa684dfea52dba1e1e7db1cec7050b
push id3857
push userraliiev@mozilla.com
push dateTue, 02 Sep 2014 16:39:23 +0000
treeherdermozilla-beta@5638b907b505 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbholley
bugs1027402
milestone33.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 1027402 - Part 2: Mark Proxy Handler instances as const. (r=bholley)
dom/base/WindowNamedPropertiesHandler.h
dom/base/nsGlobalWindow.cpp
dom/bindings/Codegen.py
js/ipc/WrapperOwner.cpp
js/src/jsproxy.cpp
js/src/jsproxy.h
js/src/jswrapper.cpp
js/src/jswrapper.h
js/src/vm/ProxyObject.cpp
js/src/vm/ProxyObject.h
js/src/vm/ScopeObject.cpp
js/xpconnect/src/Sandbox.cpp
js/xpconnect/wrappers/ChromeObjectWrapper.cpp
js/xpconnect/wrappers/ChromeObjectWrapper.h
js/xpconnect/wrappers/FilteringWrapper.cpp
js/xpconnect/wrappers/FilteringWrapper.h
js/xpconnect/wrappers/WaiveXrayWrapper.h
js/xpconnect/wrappers/WrapperFactory.cpp
js/xpconnect/wrappers/WrapperFactory.h
js/xpconnect/wrappers/XrayWrapper.cpp
js/xpconnect/wrappers/XrayWrapper.h
--- a/dom/base/WindowNamedPropertiesHandler.h
+++ b/dom/base/WindowNamedPropertiesHandler.h
@@ -49,20 +49,20 @@ public:
     return true;
   }
   virtual const char*
   className(JSContext *aCx, JS::Handle<JSObject*> aProxy) MOZ_OVERRIDE
   {
     return "WindowProperties";
   }
 
-  static WindowNamedPropertiesHandler*
+  static const WindowNamedPropertiesHandler*
   getInstance()
   {
-    static WindowNamedPropertiesHandler instance;
+    static const WindowNamedPropertiesHandler instance;
     return &instance;
   }
 
   // For Install, aProto is the proto of the Window we're associated with.
   static void
   Install(JSContext *aCx, JS::Handle<JSObject*> aProto);
 };
 
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -659,17 +659,17 @@ public:
                    bool strict,
                    JS::MutableHandle<JS::Value> vp) MOZ_OVERRIDE;
   virtual bool keys(JSContext *cx, JS::Handle<JSObject*> proxy,
                     JS::AutoIdVector &props) MOZ_OVERRIDE;
   virtual bool iterate(JSContext *cx, JS::Handle<JSObject*> proxy,
                        unsigned flags,
                        JS::MutableHandle<JS::Value> vp) MOZ_OVERRIDE;
 
-  static nsOuterWindowProxy singleton;
+  static const nsOuterWindowProxy singleton;
 
 protected:
   nsGlobalWindow* GetWindow(JSObject *proxy)
   {
     return nsGlobalWindow::FromSupports(
       static_cast<nsISupports*>(js::GetProxyExtra(proxy, 0).toPrivate()));
   }
 
@@ -1014,39 +1014,39 @@ nsOuterWindowProxy::watch(JSContext *cx,
 
 bool
 nsOuterWindowProxy::unwatch(JSContext *cx, JS::Handle<JSObject*> proxy,
                             JS::Handle<jsid> id)
 {
   return js::UnwatchGuts(cx, proxy, id);
 }
 
-nsOuterWindowProxy
+const nsOuterWindowProxy
 nsOuterWindowProxy::singleton;
 
 class nsChromeOuterWindowProxy : public nsOuterWindowProxy
 {
 public:
   nsChromeOuterWindowProxy() : nsOuterWindowProxy() {}
 
   virtual const char *className(JSContext *cx, JS::Handle<JSObject*> wrapper) MOZ_OVERRIDE;
 
-  static nsChromeOuterWindowProxy singleton;
+  static const nsChromeOuterWindowProxy singleton;
 };
 
 const char *
 nsChromeOuterWindowProxy::className(JSContext *cx,
                                     JS::Handle<JSObject*> proxy)
 {
     MOZ_ASSERT(js::IsProxy(proxy));
 
     return "ChromeWindow";
 }
 
-nsChromeOuterWindowProxy
+const nsChromeOuterWindowProxy
 nsChromeOuterWindowProxy::singleton;
 
 static JSObject*
 NewOuterWindowProxy(JSContext *cx, JS::Handle<JSObject*> parent, bool isChrome)
 {
   JSAutoCompartment ac(cx, parent);
   js::WrapperOptions options;
   options.setClass(&OuterWindowProxyClass);
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -10184,21 +10184,21 @@ class CGDOMJSProxyHandler_slice(ClassMet
             return true;
             """,
             nativeType=self.descriptor.nativeType,
             get=get)
 
 
 class CGDOMJSProxyHandler_getInstance(ClassMethod):
     def __init__(self):
-        ClassMethod.__init__(self, "getInstance", "DOMProxyHandler*", [], static=True)
+        ClassMethod.__init__(self, "getInstance", "const DOMProxyHandler*", [], static=True)
 
     def getBody(self):
         return dedent("""
-            static DOMProxyHandler instance;
+            static const DOMProxyHandler instance;
             return &instance;
             """)
 
 
 class CGDOMJSProxyHandler(CGClass):
     def __init__(self, descriptor):
         assert (descriptor.supportsIndexedProperties() or
                 descriptor.supportsNamedProperties())
--- a/js/ipc/WrapperOwner.cpp
+++ b/js/ipc/WrapperOwner.cpp
@@ -79,20 +79,20 @@ class CPOWProxyHandler : public BaseProx
     virtual bool keys(JSContext *cx, HandleObject proxy, AutoIdVector &props) MOZ_OVERRIDE;
 
     virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) MOZ_OVERRIDE;
     virtual bool call(JSContext *cx, HandleObject proxy, const CallArgs &args) MOZ_OVERRIDE;
     virtual bool objectClassIs(HandleObject obj, js::ESClassValue classValue, JSContext *cx) MOZ_OVERRIDE;
     virtual const char* className(JSContext *cx, HandleObject proxy) MOZ_OVERRIDE;
     virtual void finalize(JSFreeOp *fop, JSObject *proxy) MOZ_OVERRIDE;
 
-    static CPOWProxyHandler singleton;
+    static const CPOWProxyHandler singleton;
 };
 
-CPOWProxyHandler CPOWProxyHandler::singleton;
+const CPOWProxyHandler CPOWProxyHandler::singleton;
 
 #define FORWARD(call, args)                                             \
     WrapperOwner *owner = OwnerOf(proxy);                               \
     if (!owner->active()) {                                             \
         JS_ReportError(cx, "cannot use a CPOW whose process is gone");  \
         return false;                                                   \
     }                                                                   \
     return owner->call args;
--- a/js/src/jsproxy.cpp
+++ b/js/src/jsproxy.cpp
@@ -764,17 +764,17 @@ class ScriptedIndirectProxyHandler : pub
     virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) MOZ_OVERRIDE;
     virtual bool call(JSContext *cx, HandleObject proxy, const CallArgs &args) MOZ_OVERRIDE;
     virtual bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args) MOZ_OVERRIDE;
     virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl,
                             CallArgs args) MOZ_OVERRIDE;
     virtual JSString *fun_toString(JSContext *cx, HandleObject proxy, unsigned indent) MOZ_OVERRIDE;
     virtual bool isScripted() MOZ_OVERRIDE { return true; }
 
-    static ScriptedIndirectProxyHandler singleton;
+    static const ScriptedIndirectProxyHandler singleton;
 };
 
 /*
  * Old-style indirect proxies allow callers to specify distinct scripted
  * [[Call]] and [[Construct]] traps. We use an intermediate object so that we
  * can stash this information in a single reserved slot on the proxy object.
  *
  * Note - Currently this is slightly unnecesary, because we actually have 2
@@ -1038,17 +1038,17 @@ ScriptedIndirectProxyHandler::fun_toStri
                              js_Function_str, js_toString_str,
                              "object");
         return nullptr;
     }
     RootedObject obj(cx, &proxy->as<ProxyObject>().extra(0).toObject().getReservedSlot(0).toObject());
     return fun_toStringHelper(cx, obj, indent);
 }
 
-ScriptedIndirectProxyHandler ScriptedIndirectProxyHandler::singleton;
+const ScriptedIndirectProxyHandler ScriptedIndirectProxyHandler::singleton;
 
 /* Derived class for all scripted direct proxy handlers. */
 class ScriptedDirectProxyHandler : public DirectProxyHandler {
   public:
     ScriptedDirectProxyHandler();
     virtual ~ScriptedDirectProxyHandler();
 
     /* ES5 Harmony fundamental proxy traps. */
@@ -1084,17 +1084,17 @@ class ScriptedDirectProxyHandler : publi
     /* ES6 Harmony traps */
     virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) MOZ_OVERRIDE;
 
     /* Spidermonkey extensions. */
     virtual bool call(JSContext *cx, HandleObject proxy, const CallArgs &args) MOZ_OVERRIDE;
     virtual bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args) MOZ_OVERRIDE;
     virtual bool isScripted() MOZ_OVERRIDE { return true; }
 
-    static ScriptedDirectProxyHandler singleton;
+    static const ScriptedDirectProxyHandler singleton;
 };
 
 // This variable exists solely to provide a unique address for use as an identifier.
 static const char sScriptedDirectProxyHandlerFamily = 0;
 
 static inline bool
 IsDataDescriptor(const PropertyDescriptor &desc)
 {
@@ -2086,17 +2086,17 @@ ScriptedDirectProxyHandler::construct(JS
         return false;
     if (!args.rval().isObject()) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_PROXY_CONSTRUCT_OBJECT);
         return false;
     }
     return true;
 }
 
-ScriptedDirectProxyHandler ScriptedDirectProxyHandler::singleton;
+const ScriptedDirectProxyHandler ScriptedDirectProxyHandler::singleton;
 
 #define INVOKE_ON_PROTOTYPE(cx, handler, proxy, protoCall)                   \
     JS_BEGIN_MACRO                                                           \
         RootedObject proto(cx);                                              \
         if (!JSObject::getProto(cx, proxy, &proto))                          \
             return false;                                                    \
         if (!proto)                                                          \
             return true;                                                     \
@@ -2842,33 +2842,33 @@ js::proxy_Slice(JSContext *cx, HandleObj
 
 const Class js::ProxyObject::uncallableClass_ = PROXY_CLASS(nullptr, nullptr);
 const Class js::ProxyObject::callableClass_ = PROXY_CLASS(proxy_Call, proxy_Construct);
 
 const Class* const js::CallableProxyClassPtr = &ProxyObject::callableClass_;
 const Class* const js::UncallableProxyClassPtr = &ProxyObject::uncallableClass_;
 
 JS_FRIEND_API(JSObject *)
-js::NewProxyObject(JSContext *cx, BaseProxyHandler *handler, HandleValue priv, JSObject *proto_,
+js::NewProxyObject(JSContext *cx, const BaseProxyHandler *handler, HandleValue priv, JSObject *proto_,
                    JSObject *parent_, const ProxyOptions &options)
 {
     return ProxyObject::New(cx, handler, priv, TaggedProto(proto_), parent_,
                             options);
 }
 
 void
-ProxyObject::renew(JSContext *cx, BaseProxyHandler *handler, Value priv)
+ProxyObject::renew(JSContext *cx, const BaseProxyHandler *handler, Value priv)
 {
     JS_ASSERT_IF(IsCrossCompartmentWrapper(this), IsDeadProxyObject(this));
     JS_ASSERT(getParent() == cx->global());
     JS_ASSERT(getClass() == &uncallableClass_);
     JS_ASSERT(!getClass()->ext.innerObject);
     JS_ASSERT(getTaggedProto().isLazy());
 
-    setSlot(HANDLER_SLOT, PrivateValue(handler));
+    setHandler(handler);
     setCrossCompartmentSlot(PRIVATE_SLOT, priv);
     setSlot(EXTRA_SLOT + 0, UndefinedValue());
     setSlot(EXTRA_SLOT + 1, UndefinedValue());
 }
 
 static bool
 proxy(JSContext *cx, unsigned argc, jsval *vp)
 {
--- a/js/src/jsproxy.h
+++ b/js/src/jsproxy.h
@@ -116,25 +116,25 @@ class JS_FRIEND_API(BaseProxyHandler)
      */
     bool mHasSecurityPolicy;
 
   public:
     explicit BaseProxyHandler(const void *family, bool hasPrototype = false,
                               bool hasSecurityPolicy = false);
     virtual ~BaseProxyHandler();
 
-    bool hasPrototype() {
+    bool hasPrototype() const {
         return mHasPrototype;
     }
 
-    bool hasSecurityPolicy() {
+    bool hasSecurityPolicy() const {
         return mHasSecurityPolicy;
     }
 
-    inline const void *family() {
+    inline const void *family() const {
         return mFamily;
     }
     static size_t offsetOfFamily() {
         return offsetof(BaseProxyHandler, mFamily);
     }
 
     virtual bool finalizeInBackground(Value priv) {
         /*
@@ -454,17 +454,17 @@ class MOZ_STACK_CLASS ProxyOptions {
     }
 
   private:
     bool singleton_;
     const Class *clasp_;
 };
 
 JS_FRIEND_API(JSObject *)
-NewProxyObject(JSContext *cx, BaseProxyHandler *handler, HandleValue priv,
+NewProxyObject(JSContext *cx, const BaseProxyHandler *handler, HandleValue priv,
                JSObject *proto, JSObject *parent, const ProxyOptions &options = ProxyOptions());
 
 JSObject *
 RenewProxyObject(JSContext *cx, JSObject *obj, BaseProxyHandler *handler, Value priv);
 
 class JS_FRIEND_API(AutoEnterPolicy)
 {
   public:
--- a/js/src/jswrapper.cpp
+++ b/js/src/jswrapper.cpp
@@ -34,17 +34,17 @@ Wrapper::defaultValue(JSContext *cx, Han
 {
     vp.set(ObjectValue(*proxy->as<ProxyObject>().target()));
     if (hint == JSTYPE_VOID)
         return ToPrimitive(cx, vp);
     return ToPrimitive(cx, hint, vp);
 }
 
 JSObject *
-Wrapper::New(JSContext *cx, JSObject *obj, JSObject *parent, Wrapper *handler,
+Wrapper::New(JSContext *cx, JSObject *obj, JSObject *parent, const Wrapper *handler,
              const WrapperOptions *options)
 {
     JS_ASSERT(parent);
 
     AutoMarkInDeadZone amd(cx->zone());
 
     RootedValue priv(cx, ObjectValue(*obj));
     mozilla::Maybe<WrapperOptions> opts;
@@ -52,17 +52,17 @@ Wrapper::New(JSContext *cx, JSObject *ob
         opts.construct();
         opts.ref().selectDefaultClass(obj->isCallable());
         options = opts.addr();
     }
     return NewProxyObject(cx, handler, priv, options->proto(), parent, *options);
 }
 
 JSObject *
-Wrapper::Renew(JSContext *cx, JSObject *existing, JSObject *obj, Wrapper *handler)
+Wrapper::Renew(JSContext *cx, JSObject *existing, JSObject *obj, const Wrapper *handler)
 {
     JS_ASSERT(!obj->isCallable());
     existing->as<ProxyObject>().renew(cx, handler, ObjectValue(*obj));
     return existing;
 }
 
 Wrapper *
 Wrapper::wrapperHandler(JSObject *wrapper)
@@ -132,18 +132,18 @@ Wrapper::Wrapper(unsigned flags, bool ha
     mFlags(flags)
 {
 }
 
 Wrapper::~Wrapper()
 {
 }
 
-Wrapper Wrapper::singleton((unsigned)0);
-Wrapper Wrapper::singletonWithPrototype((unsigned)0, true);
+const Wrapper Wrapper::singleton((unsigned)0);
+const Wrapper Wrapper::singletonWithPrototype((unsigned)0, true);
 JSObject *Wrapper::defaultProto = TaggedProto::LazyProto;
 
 /* Compartments. */
 
 extern JSObject *
 js::TransparentObjectWrapper(JSContext *cx, HandleObject existing, HandleObject obj,
                              HandleObject parent, unsigned flags)
 {
@@ -598,17 +598,17 @@ CrossCompartmentWrapper::setPrototypeOf(
 {
     RootedObject protoCopy(cx, proto);
     PIERCE(cx, wrapper,
            cx->compartment()->wrap(cx, &protoCopy),
            Wrapper::setPrototypeOf(cx, wrapper, protoCopy, bp),
            NOTHING);
 }
 
-CrossCompartmentWrapper CrossCompartmentWrapper::singleton(0u);
+const CrossCompartmentWrapper CrossCompartmentWrapper::singleton(0u);
 
 /* Security wrappers. */
 
 template <class Base>
 SecurityWrapper<Base>::SecurityWrapper(unsigned flags, bool hasPrototype)
   : Base(flags, hasPrototype, /* hasSecurityPolicy = */ true)
 {
 }
@@ -854,17 +854,17 @@ DeadObjectProxy::defaultValue(JSContext 
 
 bool
 DeadObjectProxy::getPrototypeOf(JSContext *cx, HandleObject proxy, MutableHandleObject protop)
 {
     protop.set(nullptr);
     return true;
 }
 
-DeadObjectProxy DeadObjectProxy::singleton;
+const DeadObjectProxy DeadObjectProxy::singleton;
 const char DeadObjectProxy::sDeadObjectFamily = 0;
 
 bool
 js::IsDeadProxyObject(JSObject *obj)
 {
     return obj->is<ProxyObject>() &&
            obj->as<ProxyObject>().handler() == &DeadObjectProxy::singleton;
 }
--- a/js/src/jswrapper.h
+++ b/js/src/jswrapper.h
@@ -63,37 +63,37 @@ class JS_FRIEND_API(Wrapper) : public Di
     enum Flags {
         CROSS_COMPARTMENT = 1 << 0,
         LAST_USED_FLAG = CROSS_COMPARTMENT
     };
 
     virtual bool defaultValue(JSContext *cx, HandleObject obj, JSType hint,
                               MutableHandleValue vp) MOZ_OVERRIDE;
 
-    static JSObject *New(JSContext *cx, JSObject *obj, JSObject *parent, Wrapper *handler,
+    static JSObject *New(JSContext *cx, JSObject *obj, JSObject *parent, const Wrapper *handler,
                          const WrapperOptions *options = nullptr);
 
-    static JSObject *Renew(JSContext *cx, JSObject *existing, JSObject *obj, Wrapper *handler);
+    static JSObject *Renew(JSContext *cx, JSObject *existing, JSObject *obj, const Wrapper *handler);
 
     static Wrapper *wrapperHandler(JSObject *wrapper);
 
     static JSObject *wrappedObject(JSObject *wrapper);
 
     unsigned flags() const {
         return mFlags;
     }
 
     explicit Wrapper(unsigned flags, bool hasPrototype = false, bool hasSecurityPolicy = false);
 
     virtual ~Wrapper();
 
     virtual bool finalizeInBackground(Value priv) MOZ_OVERRIDE;
 
-    static Wrapper singleton;
-    static Wrapper singletonWithPrototype;
+    static const Wrapper singleton;
+    static const Wrapper singletonWithPrototype;
 
     static JSObject *defaultProto;
 };
 
 inline JSObject *
 WrapperOptions::proto() const
 {
     return proto_.empty() ? Wrapper::defaultProto : proto_.ref();
@@ -146,18 +146,18 @@ class JS_FRIEND_API(CrossCompartmentWrap
     virtual bool regexp_toShared(JSContext *cx, HandleObject proxy, RegExpGuard *g) MOZ_OVERRIDE;
     virtual bool defaultValue(JSContext *cx, HandleObject wrapper, JSType hint,
                               MutableHandleValue vp) MOZ_OVERRIDE;
     virtual bool getPrototypeOf(JSContext *cx, HandleObject proxy,
                                 MutableHandleObject protop) MOZ_OVERRIDE;
     virtual bool setPrototypeOf(JSContext *cx, HandleObject proxy, HandleObject proto,
                                 bool *bp) MOZ_OVERRIDE;
 
-    static CrossCompartmentWrapper singleton;
-    static CrossCompartmentWrapper singletonWithPrototype;
+    static const CrossCompartmentWrapper singleton;
+    static const CrossCompartmentWrapper singletonWithPrototype;
 };
 
 /*
  * Base class for security wrappers. A security wrapper is potentially hiding
  * all or part of some wrapped object thus SecurityWrapper defaults to denying
  * access to the wrappee. This is the opposite of Wrapper which tries to be
  * completely transparent.
  *
@@ -236,17 +236,17 @@ class JS_FRIEND_API(DeadObjectProxy) : p
     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 bool defaultValue(JSContext *cx, HandleObject obj, JSType hint,
                               MutableHandleValue vp) MOZ_OVERRIDE;
     virtual bool getPrototypeOf(JSContext *cx, HandleObject proxy,
                                 MutableHandleObject protop) MOZ_OVERRIDE;
 
-    static DeadObjectProxy singleton;
+    static const DeadObjectProxy singleton;
 };
 
 extern JSObject *
 TransparentObjectWrapper(JSContext *cx, HandleObject existing, HandleObject obj,
                          HandleObject parent, unsigned flags);
 
 // Proxy family for wrappers. Public so that IsWrapper() can be fully inlined by
 // jsfriendapi users.
--- a/js/src/vm/ProxyObject.cpp
+++ b/js/src/vm/ProxyObject.cpp
@@ -9,17 +9,17 @@
 #include "jscompartment.h"
 #include "jsgcinlines.h"
 #include "jsinferinlines.h"
 #include "jsobjinlines.h"
 
 using namespace js;
 
 /* static */ ProxyObject *
-ProxyObject::New(JSContext *cx, BaseProxyHandler *handler, HandleValue priv, TaggedProto proto_,
+ProxyObject::New(JSContext *cx, const BaseProxyHandler *handler, HandleValue priv, TaggedProto proto_,
                  JSObject *parent_, const ProxyOptions &options)
 {
     Rooted<TaggedProto> proto(cx, proto_);
     RootedObject parent(cx, parent_);
 
     const Class *clasp = options.clasp();
 
     JS_ASSERT(isValidProxyClass(clasp));
@@ -64,36 +64,36 @@ ProxyObject::New(JSContext *cx, BaseProx
 
 void
 ProxyObject::initCrossCompartmentPrivate(HandleValue priv)
 {
     initCrossCompartmentSlot(PRIVATE_SLOT, priv);
 }
 
 void
-ProxyObject::initHandler(BaseProxyHandler *handler)
+ProxyObject::initHandler(const BaseProxyHandler *handler)
 {
-    initSlot(HANDLER_SLOT, PrivateValue(handler));
+    initSlot(HANDLER_SLOT, PrivateValue(const_cast<BaseProxyHandler*>(handler)));
 }
 
 static void
 NukeSlot(ProxyObject *proxy, uint32_t slot)
 {
     Value old = proxy->getSlot(slot);
     if (old.isMarkable()) {
         Zone *zone = ZoneOfValue(old);
         AutoMarkInDeadZone amd(zone);
         proxy->setReservedSlot(slot, NullValue());
     } else {
         proxy->setReservedSlot(slot, NullValue());
     }
 }
 
 void
-ProxyObject::nuke(BaseProxyHandler *handler)
+ProxyObject::nuke(const BaseProxyHandler *handler)
 {
     /* Allow people to add their own number of reserved slots beyond the expected 4 */
     unsigned numSlots = JSCLASS_RESERVED_SLOTS(getClass());
     for (unsigned i = 0; i < numSlots; i++)
         NukeSlot(this, i);
     /* Restore the handler as requested after nuking. */
     setHandler(handler);
 }
--- a/js/src/vm/ProxyObject.h
+++ b/js/src/vm/ProxyObject.h
@@ -18,17 +18,17 @@ class ProxyObject : public JSObject
 {
     // These are just local renamings of the slot constants that are part of
     // the API in jsproxy.h.
     static const uint32_t PRIVATE_SLOT = PROXY_PRIVATE_SLOT;
     static const uint32_t HANDLER_SLOT = PROXY_HANDLER_SLOT;
     static const uint32_t EXTRA_SLOT   = PROXY_EXTRA_SLOT;
 
   public:
-    static ProxyObject *New(JSContext *cx, BaseProxyHandler *handler, HandleValue priv,
+    static ProxyObject *New(JSContext *cx, const BaseProxyHandler *handler, HandleValue priv,
                             TaggedProto proto_, JSObject *parent_,
                             const ProxyOptions &options);
 
     const Value &private_() {
         return GetReservedSlot(this, PRIVATE_SLOT);
     }
 
     void initCrossCompartmentPrivate(HandleValue priv);
@@ -40,20 +40,20 @@ class ProxyObject : public JSObject
     JSObject *target() const {
         return const_cast<ProxyObject*>(this)->private_().toObjectOrNull();
     }
 
     BaseProxyHandler *handler() {
         return static_cast<BaseProxyHandler*>(GetReservedSlot(this, HANDLER_SLOT).toPrivate());
     }
 
-    void initHandler(BaseProxyHandler *handler);
+    void initHandler(const BaseProxyHandler *handler);
 
-    void setHandler(BaseProxyHandler *handler) {
-        SetReservedSlot(this, HANDLER_SLOT, PrivateValue(handler));
+    void setHandler(const BaseProxyHandler *handler) {
+        SetReservedSlot(this, HANDLER_SLOT, PrivateValue(const_cast<BaseProxyHandler*>(handler)));
     }
 
     static size_t offsetOfHandler() {
         return getFixedSlotOffset(HANDLER_SLOT);
     }
 
     const Value &extra(size_t n) const {
         JS_ASSERT(n == 0 || n == 1);
@@ -88,21 +88,21 @@ class ProxyObject : public JSObject
                (clasp->flags & JSCLASS_IMPLEMENTS_BARRIERS) &&
                clasp->trace == proxy_Trace &&
                JSCLASS_RESERVED_SLOTS(clasp) >= PROXY_MINIMUM_SLOTS;
     }
 
   public:
     static unsigned grayLinkSlot(JSObject *obj);
 
-    void renew(JSContext *cx, BaseProxyHandler *handler, Value priv);
+    void renew(JSContext *cx, const BaseProxyHandler *handler, Value priv);
 
     static void trace(JSTracer *trc, JSObject *obj);
 
-    void nuke(BaseProxyHandler *handler);
+    void nuke(const BaseProxyHandler *handler);
 
     static const Class callableClass_;
     static const Class uncallableClass_;
 };
 
 } // namespace js
 
 // Note: the following |JSObject::is<T>| methods are implemented in terms of
--- a/js/src/vm/ScopeObject.cpp
+++ b/js/src/vm/ScopeObject.cpp
@@ -1309,17 +1309,17 @@ class DebugScopeProxy : public BaseProxy
             return true;
 
         argsObj.set(ArgumentsObject::createUnexpected(cx, maybeScope->frame()));
         return !!argsObj;
     }
 
   public:
     static int family;
-    static DebugScopeProxy singleton;
+    static const DebugScopeProxy singleton;
 
     DebugScopeProxy() : BaseProxyHandler(&family) {}
 
     bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) MOZ_OVERRIDE
     {
         // always [[Extensible]], can't be made non-[[Extensible]], like most
         // proxies
         *extensible = true;
@@ -1578,17 +1578,17 @@ class DebugScopeProxy : public BaseProxy
         return js_ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_CANT_DELETE,
                                         JSDVG_IGNORE_STACK, idval, NullPtr(), nullptr, nullptr);
     }
 };
 
 } /* anonymous namespace */
 
 int DebugScopeProxy::family = 0;
-DebugScopeProxy DebugScopeProxy::singleton;
+const DebugScopeProxy DebugScopeProxy::singleton;
 
 /* static */ DebugScopeObject *
 DebugScopeObject::create(JSContext *cx, ScopeObject &scope, HandleObject enclosing)
 {
     JS_ASSERT(scope.compartment() == cx->compartment());
     RootedValue priv(cx, ObjectValue(scope));
     JSObject *obj = NewProxyObject(cx, &DebugScopeProxy::singleton, priv,
                                    nullptr /* proto */, &scope.global());
--- a/js/xpconnect/src/Sandbox.cpp
+++ b/js/xpconnect/src/Sandbox.cpp
@@ -506,17 +506,17 @@ NS_IMPL_RELEASE(nsXPCComponents_utils_Sa
 // We use the nsIXPScriptable macros to generate lots of stuff for us.
 #define XPC_MAP_CLASSNAME           nsXPCComponents_utils_Sandbox
 #define XPC_MAP_QUOTED_CLASSNAME   "nsXPCComponents_utils_Sandbox"
 #define                             XPC_MAP_WANT_CALL
 #define                             XPC_MAP_WANT_CONSTRUCT
 #define XPC_MAP_FLAGS               0
 #include "xpc_map_end.h" /* This #undef's the above. */
 
-xpc::SandboxProxyHandler xpc::sandboxProxyHandler;
+const xpc::SandboxProxyHandler xpc::sandboxProxyHandler;
 
 bool
 xpc::IsSandboxPrototypeProxy(JSObject *obj)
 {
     return js::IsProxy(obj) &&
            js::GetProxyHandler(obj) == &xpc::sandboxProxyHandler;
 }
 
@@ -570,17 +570,17 @@ xpc::SandboxCallableProxyHandler::call(J
     if (thisVal == ObjectValue(*sandboxGlobal)) {
         thisVal = ObjectValue(*js::GetProxyTargetObject(sandboxProxy));
     }
 
     RootedValue func(cx, js::GetProxyPrivate(proxy));
     return JS::Call(cx, thisVal, func, args, args.rval());
 }
 
-xpc::SandboxCallableProxyHandler xpc::sandboxCallableProxyHandler;
+const xpc::SandboxCallableProxyHandler xpc::sandboxCallableProxyHandler;
 
 /*
  * Wrap a callable such that if we're called with oldThisObj as the
  * "this" we will instead call it with newThisObj as the this.
  */
 static JSObject*
 WrapCallable(JSContext *cx, JSObject *callable, JSObject *sandboxProtoProxy)
 {
--- a/js/xpconnect/wrappers/ChromeObjectWrapper.cpp
+++ b/js/xpconnect/wrappers/ChromeObjectWrapper.cpp
@@ -16,28 +16,29 @@ namespace xpc {
 // (like Array.prototype). If it is, we use the corresponding standard prototype
 // from the wrapper's scope, rather than the wrapped standard prototype
 // from the wrappee's scope.
 //
 // One of the reasons for doing this is to allow standard operations like
 // chromeArray.forEach(..) to Just Work without explicitly listing them in
 // __exposedProps__. Since proxies don't automatically inherit behavior from
 // their prototype, we have to instrument the traps to do this manually.
-ChromeObjectWrapper ChromeObjectWrapper::singleton;
+const ChromeObjectWrapper ChromeObjectWrapper::singleton;
 
 using js::assertEnteredPolicy;
 
 static bool
 AllowedByBase(JSContext *cx, HandleObject wrapper, HandleId id,
               js::Wrapper::Action act)
 {
     MOZ_ASSERT(js::Wrapper::wrapperHandler(wrapper) ==
                &ChromeObjectWrapper::singleton);
     bool bp;
-    ChromeObjectWrapper *handler = &ChromeObjectWrapper::singleton;
+    ChromeObjectWrapper *handler =
+        const_cast<ChromeObjectWrapper*>(&ChromeObjectWrapper::singleton);
     return handler->ChromeObjectWrapperBase::enter(cx, wrapper, id, act, &bp);
 }
 
 static bool
 PropIsFromStandardPrototype(JSContext *cx, JS::MutableHandle<JSPropertyDescriptor> desc)
 {
     MOZ_ASSERT(desc.object());
     RootedObject unwrapped(cx, js::UncheckedUnwrap(desc.object()));
@@ -51,17 +52,18 @@ PropIsFromStandardPrototype(JSContext *c
 // transparent wrapper) would have come off a standard prototype.
 static bool
 PropIsFromStandardPrototype(JSContext *cx, HandleObject wrapper,
                             HandleId id)
 {
     MOZ_ASSERT(js::Wrapper::wrapperHandler(wrapper) ==
                &ChromeObjectWrapper::singleton);
     Rooted<JSPropertyDescriptor> desc(cx);
-    ChromeObjectWrapper *handler = &ChromeObjectWrapper::singleton;
+    ChromeObjectWrapper *handler =
+        const_cast<ChromeObjectWrapper*>(&ChromeObjectWrapper::singleton);
     if (!handler->ChromeObjectWrapperBase::getPropertyDescriptor(cx, wrapper, id,
                                                                  &desc) ||
         !desc.object())
     {
         return false;
     }
     return PropIsFromStandardPrototype(cx, &desc);
 }
--- a/js/xpconnect/wrappers/ChromeObjectWrapper.h
+++ b/js/xpconnect/wrappers/ChromeObjectWrapper.h
@@ -46,14 +46,14 @@ class ChromeObjectWrapper : public Chrom
     // NB: One might think we'd need to implement enumerate(), keys(), iterate(),
     // and getPropertyNames() here. However, ES5 built-in properties aren't
     // enumerable (and SpiderMonkey's implementation seems to match the spec
     // modulo Error.prototype.fileName and Error.prototype.lineNumber). Since
     // we're only remapping the prototypes of standard objects, there would
     // never be anything more to enumerate up the prototype chain. So we can
     // atually skip these.
 
-    static ChromeObjectWrapper singleton;
+    static const ChromeObjectWrapper singleton;
 };
 
 } /* namespace xpc */
 
 #endif /* __ChromeObjectWrapper_h__ */
--- a/js/xpconnect/wrappers/FilteringWrapper.cpp
+++ b/js/xpconnect/wrappers/FilteringWrapper.cpp
@@ -186,22 +186,22 @@ FilteringWrapper<Base, Policy>::enter(JS
     return true;
 }
 
 #define XOW FilteringWrapper<SecurityXrayXPCWN, CrossOriginAccessiblePropertiesOnly>
 #define DXOW   FilteringWrapper<SecurityXrayDOM, CrossOriginAccessiblePropertiesOnly>
 #define NNXOW FilteringWrapper<CrossCompartmentSecurityWrapper, Opaque>
 #define NNXOWC FilteringWrapper<CrossCompartmentSecurityWrapper, OpaqueWithCall>
 #define GO FilteringWrapper<CrossCompartmentSecurityWrapper, GentlyOpaque>
-template<> XOW XOW::singleton(0);
-template<> DXOW DXOW::singleton(0);
-template<> NNXOW NNXOW::singleton(0);
-template<> NNXOWC NNXOWC::singleton(0);
+template<> const XOW XOW::singleton(0);
+template<> const DXOW DXOW::singleton(0);
+template<> const NNXOW NNXOW::singleton(0);
+template<> const NNXOWC NNXOWC::singleton(0);
 
-template<> GO GO::singleton(0);
+template<> const GO GO::singleton(0);
 
 template class XOW;
 template class DXOW;
 template class NNXOW;
 template class NNXOWC;
 template class ChromeObjectWrapperBase;
 template class GO;
 }
--- a/js/xpconnect/wrappers/FilteringWrapper.h
+++ b/js/xpconnect/wrappers/FilteringWrapper.h
@@ -42,14 +42,14 @@ class FilteringWrapper : public Base {
     virtual bool nativeCall(JSContext *cx, JS::IsAcceptableThis test, JS::NativeImpl impl,
                             JS::CallArgs args) MOZ_OVERRIDE;
 
     virtual bool defaultValue(JSContext *cx, JS::Handle<JSObject*> obj, JSType hint, JS::MutableHandleValue vp) MOZ_OVERRIDE;
 
     virtual bool enter(JSContext *cx, JS::Handle<JSObject*> wrapper, JS::Handle<jsid> id,
                        js::Wrapper::Action act, bool *bp) MOZ_OVERRIDE;
 
-    static FilteringWrapper singleton;
+    static const FilteringWrapper singleton;
 };
 
 }
 
 #endif /* __FilteringWrapper_h__ */
--- a/js/xpconnect/wrappers/WaiveXrayWrapper.h
+++ b/js/xpconnect/wrappers/WaiveXrayWrapper.h
@@ -33,14 +33,14 @@ class WaiveXrayWrapper : public js::Cros
                            const JS::CallArgs &args) MOZ_OVERRIDE;
 
     virtual bool nativeCall(JSContext *cx, JS::IsAcceptableThis test,
                             JS::NativeImpl impl, JS::CallArgs args) MOZ_OVERRIDE;
 
     virtual bool getPrototypeOf(JSContext *cx, JS::Handle<JSObject*> wrapper,
                                 JS::MutableHandle<JSObject*> protop) MOZ_OVERRIDE;
 
-    static WaiveXrayWrapper singleton;
+    static const WaiveXrayWrapper singleton;
 };
 
 }
 
 #endif
--- a/js/xpconnect/wrappers/WrapperFactory.cpp
+++ b/js/xpconnect/wrappers/WrapperFactory.cpp
@@ -27,23 +27,23 @@ namespace xpc {
 
 // When chrome pulls a naked property across the membrane using
 // .wrappedJSObject, we want it to cross the membrane into the
 // chrome compartment without automatically being wrapped into an
 // X-ray wrapper. We achieve this by wrapping it into a special
 // transparent wrapper in the origin (non-chrome) compartment. When
 // an object with that special wrapper applied crosses into chrome,
 // we know to not apply an X-ray wrapper.
-Wrapper XrayWaiver(WrapperFactory::WAIVE_XRAY_WRAPPER_FLAG);
+const Wrapper XrayWaiver(WrapperFactory::WAIVE_XRAY_WRAPPER_FLAG);
 
 // When objects for which we waived the X-ray wrapper cross into
 // chrome, we wrap them into a special cross-compartment wrapper
 // that transitively extends the waiver to all properties we get
 // off it.
-WaiveXrayWrapper WaiveXrayWrapper::singleton(0);
+const WaiveXrayWrapper WaiveXrayWrapper::singleton(0);
 
 bool
 WrapperFactory::IsCOW(JSObject *obj)
 {
     return IsWrapper(obj) &&
            Wrapper::wrapperHandler(obj) == &ChromeObjectWrapper::singleton;
 }
 
@@ -320,17 +320,17 @@ WrapperFactory::PrepareForWrapping(JSCon
         return nullptr;
     newwn->SetSet(unionSet);
 
     return DoubleWrap(cx, obj, flags);
 }
 
 #ifdef DEBUG
 static void
-DEBUG_CheckUnwrapSafety(HandleObject obj, js::Wrapper *handler,
+DEBUG_CheckUnwrapSafety(HandleObject obj, const js::Wrapper *handler,
                         JSCompartment *origin, JSCompartment *target)
 {
     if (AccessCheck::isChrome(target) || xpc::IsUniversalXPConnectEnabled(target)) {
         // If the caller is chrome (or effectively so), unwrap should always be allowed.
         MOZ_ASSERT(!handler->hasSecurityPolicy());
     } else if (handler == &FilteringWrapper<CrossCompartmentSecurityWrapper, GentlyOpaque>::singleton) {
         // We explicitly use a SecurityWrapper to protect privileged callers from
         // less-privileged objects that they should never see. Skip the check in
@@ -339,17 +339,17 @@ DEBUG_CheckUnwrapSafety(HandleObject obj
         // Otherwise, it should depend on whether the target subsumes the origin.
         MOZ_ASSERT(handler->hasSecurityPolicy() == !AccessCheck::subsumesConsideringDomain(target, origin));
     }
 }
 #else
 #define DEBUG_CheckUnwrapSafety(obj, handler, origin, target) {}
 #endif
 
-static Wrapper *
+static const Wrapper *
 SelectWrapper(bool securityWrapper, bool wantXrays, XrayType xrayType,
               bool waiveXrays, bool originIsXBLScope)
 {
     // Waived Xray uses a modified CCW that has transparent behavior but
     // transitively waives Xrays on arguments.
     if (waiveXrays) {
         MOZ_ASSERT(!securityWrapper);
         return &WaiveXrayWrapper::singleton;
@@ -415,17 +415,17 @@ WrapperFactory::Rewrap(JSContext *cx, Ha
     bool originIsChrome = AccessCheck::isChrome(origin);
     bool targetIsChrome = AccessCheck::isChrome(target);
     bool originSubsumesTarget = AccessCheck::subsumesConsideringDomain(origin, target);
     bool targetSubsumesOrigin = AccessCheck::subsumesConsideringDomain(target, origin);
     bool sameOrigin = targetSubsumesOrigin && originSubsumesTarget;
     XrayType xrayType = GetXrayType(obj);
     bool waiveXrayFlag = flags & WAIVE_XRAY_WRAPPER_FLAG;
 
-    Wrapper *wrapper;
+    const Wrapper *wrapper;
     CompartmentPrivate *targetdata = EnsureCompartmentPrivate(target);
 
     //
     // First, handle the special cases.
     //
 
     // If UniversalXPConnect is enabled, this is just some dumb mochitest. Use
     // a vanilla CCW.
--- a/js/xpconnect/wrappers/WrapperFactory.h
+++ b/js/xpconnect/wrappers/WrapperFactory.h
@@ -59,13 +59,13 @@ class WrapperFactory {
     // Wrap wrapped object into a waiver wrapper and then re-wrap it.
     static bool WaiveXrayAndWrap(JSContext *cx, JS::MutableHandleValue vp);
     static bool WaiveXrayAndWrap(JSContext *cx, JS::MutableHandleObject object);
 
     // Returns true if the wrapper is in not shadowing mode for the id.
     static bool XrayWrapperNotShadowing(JSObject *wrapper, jsid id);
 };
 
-extern js::Wrapper XrayWaiver;
+extern const js::Wrapper XrayWaiver;
 
 }
 
 #endif /* _xpc_WRAPPERFACTORY_H */
--- a/js/xpconnect/wrappers/XrayWrapper.cpp
+++ b/js/xpconnect/wrappers/XrayWrapper.cpp
@@ -2570,25 +2570,27 @@ XrayWrapper<Base, Traits>::iterate(JSCon
     return js::BaseProxyHandler::iterate(cx, wrapper, flags, vp);
 }
 
 template <typename Base, typename Traits>
 bool
 XrayWrapper<Base, Traits>::call(JSContext *cx, HandleObject wrapper, const JS::CallArgs &args)
 {
     assertEnteredPolicy(cx, wrapper, JSID_VOID, BaseProxyHandler::CALL);
-    return Traits::call(cx, wrapper, args, Base::singleton);
+    // Hard cast the singleton since SecurityWrapper doesn't have one.
+    return Traits::call(cx, wrapper, args, (js::Wrapper&)Base::singleton);
 }
 
 template <typename Base, typename Traits>
 bool
 XrayWrapper<Base, Traits>::construct(JSContext *cx, HandleObject wrapper, const JS::CallArgs &args)
 {
     assertEnteredPolicy(cx, wrapper, JSID_VOID, BaseProxyHandler::CALL);
-    return Traits::construct(cx, wrapper, args, Base::singleton);
+    // Hard cast the singleton since SecurityWrapper doesn't have one.
+    return Traits::construct(cx, wrapper, args, (js::Wrapper&)Base::singleton);
 }
 
 template <typename Base, typename Traits>
 bool
 XrayWrapper<Base, Traits>::defaultValue(JSContext *cx, HandleObject wrapper,
                                         JSType hint, MutableHandleValue vp)
 {
     // Even if this isn't a security wrapper, Xray semantics dictate that we
@@ -2658,37 +2660,37 @@ XrayWrapper<Base, Traits>::setPrototypeO
 /*
  * The Permissive / Security variants should be used depending on whether the
  * compartment of the wrapper is guranteed to subsume the compartment of the
  * wrapped object (i.e. - whether it is safe from a security perspective to
  * unwrap the wrapper).
  */
 
 template<>
-PermissiveXrayXPCWN PermissiveXrayXPCWN::singleton(0);
+const PermissiveXrayXPCWN PermissiveXrayXPCWN::singleton(0);
 template class PermissiveXrayXPCWN;
 
 template<>
-SecurityXrayXPCWN SecurityXrayXPCWN::singleton(0);
+const SecurityXrayXPCWN SecurityXrayXPCWN::singleton(0);
 template class SecurityXrayXPCWN;
 
 template<>
-PermissiveXrayDOM PermissiveXrayDOM::singleton(0);
+const PermissiveXrayDOM PermissiveXrayDOM::singleton(0);
 template class PermissiveXrayDOM;
 
 template<>
-SecurityXrayDOM SecurityXrayDOM::singleton(0);
+const SecurityXrayDOM SecurityXrayDOM::singleton(0);
 template class SecurityXrayDOM;
 
 template<>
-PermissiveXrayJS PermissiveXrayJS::singleton(0);
+const PermissiveXrayJS PermissiveXrayJS::singleton(0);
 template class PermissiveXrayJS;
 
 template<>
-SCSecurityXrayXPCWN SCSecurityXrayXPCWN::singleton(0);
+const SCSecurityXrayXPCWN SCSecurityXrayXPCWN::singleton(0);
 template class SCSecurityXrayXPCWN;
 
 static nsQueryInterface
 do_QueryInterfaceNative(JSContext* cx, HandleObject wrapper)
 {
     nsISupports* nativeSupports;
     if (IsWrapper(wrapper) && WrapperFactory::IsXrayWrapper(wrapper)) {
         RootedObject target(cx, XrayTraits::getTargetObject(wrapper));
--- a/js/xpconnect/wrappers/XrayWrapper.h
+++ b/js/xpconnect/wrappers/XrayWrapper.h
@@ -106,17 +106,17 @@ class XrayWrapper : public Base {
                               JSType hint, JS::MutableHandleValue vp)
                               MOZ_OVERRIDE;
 
     virtual bool getPrototypeOf(JSContext *cx, JS::HandleObject wrapper,
                                 JS::MutableHandleObject protop) MOZ_OVERRIDE;
     virtual bool setPrototypeOf(JSContext *cx, JS::HandleObject wrapper,
                                 JS::HandleObject proto, bool *bp) MOZ_OVERRIDE;
 
-    static XrayWrapper singleton;
+    static const XrayWrapper singleton;
 
   private:
     template <bool HasPrototype>
     typename mozilla::EnableIf<HasPrototype, bool>::Type
         getPrototypeOfHelper(JSContext *cx, JS::HandleObject wrapper,
                              JS::HandleObject target, JS::MutableHandleObject protop)
     {
         return Traits::singleton.getPrototypeOf(cx, wrapper, target, protop);
@@ -170,32 +170,32 @@ public:
     virtual bool set(JSContext *cx, JS::Handle<JSObject*> proxy, JS::Handle<JSObject*> receiver,
                      JS::Handle<jsid> id, bool strict, JS::MutableHandle<JS::Value> vp) MOZ_OVERRIDE;
     virtual bool keys(JSContext *cx, JS::Handle<JSObject*> proxy,
                       JS::AutoIdVector &props) MOZ_OVERRIDE;
     virtual bool iterate(JSContext *cx, JS::Handle<JSObject*> proxy, unsigned flags,
                          JS::MutableHandle<JS::Value> vp) MOZ_OVERRIDE;
 };
 
-extern SandboxProxyHandler sandboxProxyHandler;
+extern const SandboxProxyHandler sandboxProxyHandler;
 
 // A proxy handler that lets us wrap callables and invoke them with
 // the correct this object, while forwarding all other operations down
 // to them directly.
 class SandboxCallableProxyHandler : public js::Wrapper {
 public:
     SandboxCallableProxyHandler() : js::Wrapper(0)
     {
     }
 
     virtual bool call(JSContext *cx, JS::Handle<JSObject*> proxy,
                       const JS::CallArgs &args) MOZ_OVERRIDE;
 };
 
-extern SandboxCallableProxyHandler sandboxCallableProxyHandler;
+extern const SandboxCallableProxyHandler sandboxCallableProxyHandler;
 
 class AutoSetWrapperNotShadowing;
 class XPCWrappedNativeXrayTraits;
 
 class MOZ_STACK_CLASS ResolvingId {
 public:
     ResolvingId(JSContext *cx, JS::HandleObject wrapper, JS::HandleId id);
     ~ResolvingId();