Bug 1053271 - Remove XPCWN Xrays. r=bz.
authorPeter Van der Beken <peterv@propagandism.org>
Mon, 04 Jun 2018 12:56:38 +0200
changeset 805265 c0c9e69ee274daf9d6c6eb017a92b856b88c368e
parent 805264 15fc5d2e7faf3309e399331fd592ae6804c0c574
child 805266 3cd7e51e9913010024d318fa6b726f335e21c48f
push id112610
push userbmo:gl@mozilla.com
push dateThu, 07 Jun 2018 15:48:24 +0000
reviewersbz
bugs1053271
milestone62.0a1
Bug 1053271 - Remove XPCWN Xrays. r=bz.
js/xpconnect/wrappers/AccessCheck.cpp
js/xpconnect/wrappers/WrapperFactory.cpp
js/xpconnect/wrappers/XrayWrapper.cpp
js/xpconnect/wrappers/XrayWrapper.h
--- a/js/xpconnect/wrappers/AccessCheck.cpp
+++ b/js/xpconnect/wrappers/AccessCheck.cpp
@@ -159,17 +159,16 @@ IsFrameId(JSContext* cx, JSObject* obj, 
     return domwin != nullptr;
 }
 
 CrossOriginObjectType
 IdentifyCrossOriginObject(JSObject* obj)
 {
     obj = js::UncheckedUnwrap(obj, /* stopAtWindowProxy = */ false);
     const js::Class* clasp = js::GetObjectClass(obj);
-    MOZ_ASSERT(!XrayUtils::IsXPCWNHolderClass(Jsvalify(clasp)), "shouldn't have a holder here");
 
     if (clasp->name[0] == 'L' && !strcmp(clasp->name, "Location"))
         return CrossOriginLocation;
     if (clasp->name[0] == 'W' && !strcmp(clasp->name, "Window"))
         return CrossOriginWindow;
 
     return CrossOriginOpaque;
 }
--- a/js/xpconnect/wrappers/WrapperFactory.cpp
+++ b/js/xpconnect/wrappers/WrapperFactory.cpp
@@ -395,19 +395,17 @@ SelectWrapper(bool securityWrapper, Xray
         if (!securityWrapper)
             return &CrossCompartmentWrapper::singleton;
         return &FilteringWrapper<CrossCompartmentSecurityWrapper, Opaque>::singleton;
     }
 
     // Ok, we're using Xray. If this isn't a security wrapper, use the permissive
     // version and skip the filter.
     if (!securityWrapper) {
-        if (xrayType == XrayForWrappedNative)
-            return &PermissiveXrayXPCWN::singleton;
-        else if (xrayType == XrayForDOMObject)
+        if (xrayType == XrayForDOMObject)
             return &PermissiveXrayDOM::singleton;
         else if (xrayType == XrayForJSObject)
             return &PermissiveXrayJS::singleton;
         MOZ_ASSERT(xrayType == XrayForOpaqueObject);
         return &PermissiveXrayOpaque::singleton;
     }
 
     // This is a security wrapper. Use the security versions and filter.
@@ -430,17 +428,16 @@ SelectWrapper(bool securityWrapper, Xray
 
 JSObject*
 WrapperFactory::Rewrap(JSContext* cx, HandleObject existing, HandleObject obj)
 {
     MOZ_ASSERT(!IsWrapper(obj) ||
                GetProxyHandler(obj) == &XrayWaiver ||
                js::IsWindowProxy(obj),
                "wrapped object passed to rewrap");
-    MOZ_ASSERT(!XrayUtils::IsXPCWNHolderClass(JS_GetClass(obj)), "trying to wrap a holder");
     MOZ_ASSERT(!js::IsWindow(obj));
     MOZ_ASSERT(dom::IsJSAPIActive());
 
     // Compute the information we need to select the right wrapper.
     JSCompartment* origin = js::GetObjectCompartment(obj);
     JSCompartment* target = js::GetContextCompartment(cx);
     bool originIsChrome = AccessCheck::isChrome(origin);
     bool targetIsChrome = AccessCheck::isChrome(target);
--- a/js/xpconnect/wrappers/XrayWrapper.cpp
+++ b/js/xpconnect/wrappers/XrayWrapper.cpp
@@ -99,19 +99,17 @@ IsJSXraySupported(JSProtoKey key)
 
 XrayType
 GetXrayType(JSObject* obj)
 {
     obj = js::UncheckedUnwrap(obj, /* stopAtWindowProxy = */ false);
     if (mozilla::dom::UseDOMXray(obj))
         return XrayForDOMObject;
 
-    const js::Class* clasp = js::GetObjectClass(obj);
-    if (IS_WN_CLASS(clasp) || js::IsWindowProxy(obj))
-        return XrayForWrappedNative;
+    MOZ_ASSERT(!js::IsWindowProxy(obj));
 
     JSProtoKey standardProto = IdentifyStandardInstanceOrPrototype(obj);
     if (IsJSXraySupported(standardProto))
         return XrayForJSObject;
 
     // Modulo a few exceptions, everything else counts as an XrayWrapper to an
     // opaque object, which means that more-privileged code sees nothing from
     // the underlying object. This is very important for security. In some cases
@@ -193,27 +191,16 @@ XrayTraits::detachExpandoChain(HandleObj
 }
 
 bool
 XrayTraits::setExpandoChain(JSContext* cx, HandleObject obj, HandleObject chain)
 {
     return ObjectScope(obj)->SetExpandoChain(cx, obj, chain);
 }
 
-// static
-XPCWrappedNative*
-XPCWrappedNativeXrayTraits::getWN(JSObject* wrapper)
-{
-    return XPCWrappedNative::Get(getTargetObject(wrapper));
-}
-
-const JSClass XPCWrappedNativeXrayTraits::HolderClass = {
-    "NativePropertyHolder", JSCLASS_HAS_RESERVED_SLOTS(HOLDER_SHARED_SLOT_COUNT)
-};
-
 const JSClass XrayTraits::HolderClass = {
     "XrayHolder", JSCLASS_HAS_RESERVED_SLOTS(HOLDER_SHARED_SLOT_COUNT)
 };
 
 const JSClass JSXrayTraits::HolderClass = {
     "JSXrayHolder", JSCLASS_HAS_RESERVED_SLOTS(SLOT_COUNT)
 };
 
@@ -1024,29 +1011,26 @@ JSXrayTraits::createHolder(JSContext* cx
     if (key == JSProto_Function) {
         v.setNumber(static_cast<uint32_t>(IdentifyStandardConstructor(target)));
         js::SetReservedSlot(holder, SLOT_CONSTRUCTOR_FOR, v);
     }
 
     return holder;
 }
 
-XPCWrappedNativeXrayTraits XPCWrappedNativeXrayTraits::singleton;
 DOMXrayTraits DOMXrayTraits::singleton;
 JSXrayTraits JSXrayTraits::singleton;
 OpaqueXrayTraits OpaqueXrayTraits::singleton;
 
 XrayTraits*
 GetXrayTraits(JSObject* obj)
 {
     switch (GetXrayType(obj)) {
       case XrayForDOMObject:
         return &DOMXrayTraits::singleton;
-      case XrayForWrappedNative:
-        return &XPCWrappedNativeXrayTraits::singleton;
       case XrayForJSObject:
         return &JSXrayTraits::singleton;
       case XrayForOpaqueObject:
         return &OpaqueXrayTraits::singleton;
       default:
         return nullptr;
     }
 }
@@ -1418,141 +1402,31 @@ GetCachedXrayExpando(JSObject* wrapper)
 static inline void
 SetCachedXrayExpando(JSObject* holder, JSObject* expandoWrapper)
 {
     MOZ_ASSERT(js::GetObjectCompartment(holder) ==
                js::GetObjectCompartment(expandoWrapper));
     JS_SetReservedSlot(holder, XrayTraits::HOLDER_SLOT_EXPANDO, ObjectValue(*expandoWrapper));
 }
 
-namespace XrayUtils {
-
-bool
-IsXPCWNHolderClass(const JSClass* clasp)
-{
-  return clasp == &XPCWrappedNativeXrayTraits::HolderClass;
-}
-
-} // namespace XrayUtils
-
 static nsGlobalWindowInner*
 AsWindow(JSContext* cx, JSObject* wrapper)
 {
   // We want to use our target object here, since we don't want to be
   // doing a security check while unwrapping.
   JSObject* target = XrayTraits::getTargetObject(wrapper);
   return WindowOrNull(target);
 }
 
 static bool
 IsWindow(JSContext* cx, JSObject* wrapper)
 {
     return !!AsWindow(cx, wrapper);
 }
 
-void
-XPCWrappedNativeXrayTraits::preserveWrapper(JSObject* target)
-{
-}
-
-static bool
-XrayToString(JSContext* cx, unsigned argc, JS::Value* vp);
-
-bool
-XPCWrappedNativeXrayTraits::resolveNativeProperty(JSContext* cx, HandleObject wrapper,
-                                                  HandleObject holder, HandleId id,
-                                                  MutableHandle<PropertyDescriptor> desc)
-{
-    MOZ_ASSERT(js::GetObjectJSClass(holder) == &HolderClass);
-
-    desc.object().set(nullptr);
-
-    // This will do verification and the method lookup for us.
-    RootedObject target(cx, getTargetObject(wrapper));
-    XPCCallContext ccx(cx, target, nullptr, id);
-
-    // There are no native numeric (or symbol-keyed) properties, so we can
-    // shortcut here. We will not find the property.
-    if (!JSID_IS_STRING(id))
-        return true;
-
-    XPCNativeInterface* iface;
-    XPCNativeMember* member;
-    XPCWrappedNative* wn = getWN(wrapper);
-
-    if (ccx.GetWrapper() != wn || !wn->IsValid()) {
-        return true;
-    }
-
-    if (!(iface = ccx.GetInterface()) || !(member = ccx.GetMember())) {
-        if (id != XPCJSRuntime::Get()->GetStringID(XPCJSContext::IDX_TO_STRING))
-            return true;
-
-        JSFunction* toString = JS_NewFunction(cx, XrayToString, 0, 0, "toString");
-        if (!toString)
-            return false;
-
-        FillPropertyDescriptor(desc, wrapper, 0,
-                               ObjectValue(*JS_GetFunctionObject(toString)));
-
-        return JS_DefinePropertyById(cx, holder, id, desc) &&
-               JS_GetOwnPropertyDescriptorById(cx, holder, id, desc);
-    }
-
-    desc.object().set(holder);
-    desc.setAttributes(JSPROP_ENUMERATE);
-    desc.setGetter(nullptr);
-    desc.setSetter(nullptr);
-    desc.value().setUndefined();
-
-    RootedValue fval(cx, JS::UndefinedValue());
-    if (member->IsConstant()) {
-        if (!member->GetConstantValue(ccx, iface, desc.value().address())) {
-            JS_ReportErrorASCII(cx, "Failed to convert constant native property to JS value");
-            return false;
-        }
-    } else if (member->IsAttribute()) {
-        // This is a getter/setter. Clone a function for it.
-        if (!member->NewFunctionObject(ccx, iface, wrapper, fval.address())) {
-            JS_ReportErrorASCII(cx, "Failed to clone function object for native getter/setter");
-            return false;
-        }
-
-        unsigned attrs = desc.attributes();
-        attrs |= JSPROP_GETTER;
-        if (member->IsWritableAttribute())
-            attrs |= JSPROP_SETTER;
-
-        desc.setAttributes(attrs);
-    } else {
-        // This is a method. Clone a function for it.
-        if (!member->NewFunctionObject(ccx, iface, wrapper, desc.value().address())) {
-            JS_ReportErrorASCII(cx, "Failed to clone function object for native function");
-            return false;
-        }
-
-        // Without a wrapper the function would live on the prototype. Since we
-        // don't have one, we have to avoid calling the scriptable helper's
-        // GetProperty method for this property, so null out the getter and
-        // setter here explicitly.
-        desc.setGetter(nullptr);
-        desc.setSetter(nullptr);
-    }
-
-    if (!JS_WrapValue(cx, desc.value()) || !JS_WrapValue(cx, &fval))
-        return false;
-
-    if (desc.hasGetterObject())
-        desc.setGetterObject(&fval.toObject());
-    if (desc.hasSetterObject())
-        desc.setSetterObject(&fval.toObject());
-
-    return JS_DefinePropertyById(cx, holder, id, desc);
-}
-
 static bool
 wrappedJSObject_getter(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     if (!args.thisv().isObject()) {
         JS_ReportErrorASCII(cx, "This value not an object");
         return false;
     }
@@ -1634,122 +1508,16 @@ XrayTraits::resolveOwnProperty(JSContext
         desc.object().set(wrapper);
         return true;
     }
 
     return true;
 }
 
 bool
-XPCWrappedNativeXrayTraits::resolveOwnProperty(JSContext* cx, HandleObject wrapper,
-                                               HandleObject target, HandleObject holder,
-                                               HandleId id,
-                                               MutableHandle<PropertyDescriptor> desc)
-{
-    // Call the common code.
-    bool ok = XrayTraits::resolveOwnProperty(cx, wrapper, target, holder,
-                                             id, desc);
-    if (!ok || desc.object())
-        return ok;
-
-    // Xray wrappers don't use the regular wrapper hierarchy, so we should be
-    // in the wrapper's compartment here, not the wrappee.
-    MOZ_ASSERT(js::IsObjectInContextCompartment(wrapper, cx));
-
-    return JS_GetOwnPropertyDescriptorById(cx, holder, id, desc);
-}
-
-bool
-XPCWrappedNativeXrayTraits::enumerateNames(JSContext* cx, HandleObject wrapper, unsigned flags,
-                                           AutoIdVector& props)
-{
-    // Force all native properties to be materialized onto the wrapped native.
-    AutoIdVector wnProps(cx);
-    {
-        RootedObject target(cx, getTargetObject(wrapper));
-        JSAutoRealm ar(cx, target);
-        if (!js::GetPropertyKeys(cx, target, flags, &wnProps))
-            return false;
-    }
-
-    // Go through the properties we found on the underlying object and see if
-    // they appear on the XrayWrapper. If it throws (which may happen if the
-    // wrapper is a SecurityWrapper), just clear the exception and move on.
-    MOZ_ASSERT(!JS_IsExceptionPending(cx));
-    if (!props.reserve(wnProps.length()))
-        return false;
-    for (size_t n = 0; n < wnProps.length(); ++n) {
-        RootedId id(cx, wnProps[n]);
-        JS_MarkCrossZoneId(cx, id);
-        bool hasProp;
-        if (JS_HasPropertyById(cx, wrapper, id, &hasProp) && hasProp)
-            props.infallibleAppend(id);
-        JS_ClearPendingException(cx);
-    }
-    return true;
-}
-
-JSObject*
-XPCWrappedNativeXrayTraits::createHolder(JSContext* cx, JSObject* wrapper)
-{
-    return JS_NewObjectWithGivenProto(cx, &HolderClass, nullptr);
-}
-
-bool
-XPCWrappedNativeXrayTraits::call(JSContext* cx, HandleObject wrapper,
-                                 const JS::CallArgs& args,
-                                 const js::Wrapper& baseInstance)
-{
-    // Run the call hook of the wrapped native.
-    XPCWrappedNative* wn = getWN(wrapper);
-    if (wn->GetScriptable() && wn->GetScriptable()->WantCall()) {
-        XPCCallContext ccx(cx, wrapper, nullptr, JSID_VOIDHANDLE, args.length(),
-                           args.array(), args.rval().address());
-        if (!ccx.IsValid())
-            return false;
-        bool ok = true;
-        nsresult rv = wn->GetScriptable()->Call(wn, cx, wrapper, args, &ok);
-        if (NS_FAILED(rv)) {
-            if (ok)
-                XPCThrower::Throw(rv, cx);
-            return false;
-        }
-    }
-
-    return true;
-
-}
-
-bool
-XPCWrappedNativeXrayTraits::construct(JSContext* cx, HandleObject wrapper,
-                                      const JS::CallArgs& args,
-                                      const js::Wrapper& baseInstance)
-{
-    // Run the construct hook of the wrapped native.
-    XPCWrappedNative* wn = getWN(wrapper);
-    if (wn->GetScriptable() && wn->GetScriptable()->WantConstruct()) {
-        XPCCallContext ccx(cx, wrapper, nullptr, JSID_VOIDHANDLE, args.length(),
-                           args.array(), args.rval().address());
-        if (!ccx.IsValid())
-            return false;
-        bool ok = true;
-        nsresult rv =
-            wn->GetScriptable()->Construct(wn, cx, wrapper, args, &ok);
-        if (NS_FAILED(rv)) {
-            if (ok)
-                XPCThrower::Throw(rv, cx);
-            return false;
-        }
-    }
-
-    return true;
-
-}
-
-bool
 DOMXrayTraits::resolveOwnProperty(JSContext* cx, HandleObject wrapper, HandleObject target,
                                   HandleObject holder, HandleId id,
                                   MutableHandle<PropertyDescriptor> desc)
 {
     // Call the common code.
     bool ok = XrayTraits::resolveOwnProperty(cx, wrapper, target, holder, id, desc);
     if (!ok || desc.object())
         return ok;
@@ -1983,68 +1751,16 @@ HasNativeProperty(JSContext* cx, HandleO
     if (!traits->resolveNativeProperty(cx, wrapper, holder, id, &desc))
         return false;
     *hasProp = !!desc.object();
     return true;
 }
 
 } // namespace XrayUtils
 
-static bool
-XrayToString(JSContext* cx, unsigned argc, Value* vp)
-{
-    CallArgs args = CallArgsFromVp(argc, vp);
-
-    if (!args.thisv().isObject()) {
-        JS_ReportErrorASCII(cx, "XrayToString called on an incompatible object");
-        return false;
-    }
-
-    RootedObject wrapper(cx, &args.thisv().toObject());
-    if (!wrapper)
-        return false;
-    if (IsWrapper(wrapper) &&
-        GetProxyHandler(wrapper) == &sandboxCallableProxyHandler) {
-        wrapper = xpc::SandboxCallableProxyHandler::wrappedObject(wrapper);
-    }
-    if (!IsWrapper(wrapper) || !WrapperFactory::IsXrayWrapper(wrapper)) {
-        JS_ReportErrorASCII(cx, "XrayToString called on an incompatible object");
-        return false;
-    }
-
-    RootedObject obj(cx, XrayTraits::getTargetObject(wrapper));
-    if (GetXrayType(obj) != XrayForWrappedNative) {
-        JS_ReportErrorASCII(cx, "XrayToString called on an incompatible object");
-        return false;
-    }
-
-    static const char start[] = "[object XrayWrapper ";
-    static const char end[] = "]";
-    nsAutoString result;
-    result.AppendASCII(start);
-
-    XPCCallContext ccx(cx, obj);
-    XPCWrappedNative* wn = XPCWrappedNativeXrayTraits::getWN(wrapper);
-    char* wrapperStr = wn->ToString();
-    if (!wrapperStr) {
-        JS_ReportOutOfMemory(cx);
-        return false;
-    }
-    result.AppendASCII(wrapperStr);
-    js_free(wrapperStr);
-
-    result.AppendASCII(end);
-
-    JSString* str = JS_NewUCStringCopyN(cx, result.get(), result.Length());
-    if (!str)
-        return false;
-
-    args.rval().setString(str);
-    return true;
-}
 
 template <typename Base, typename Traits>
 bool
 XrayWrapper<Base, Traits>::preventExtensions(JSContext* cx, HandleObject wrapper,
                                              ObjectOpResult& result) const
 {
     // Xray wrappers are supposed to provide a clean view of the target
     // reflector, hiding any modifications by script in the target scope.  So
@@ -2086,22 +1802,19 @@ XrayWrapper<Base, Traits>::getPropertyDe
     //
     // We first need to call resolveOwnProperty, even before checking the holder,
     // because there might be a new dynamic |own| property that appears and
     // shadows a previously-resolved non-own property that we cached on the
     // holder. This can happen with indexed properties on NodeLists, for example,
     // which are |own| value props.
     //
     // resolveOwnProperty may or may not cache what it finds on the holder,
-    // depending on how ephemeral it decides the property is. XPCWN |own|
-    // properties generally end up on the holder via Resolve, whereas
-    // NodeList |own| properties don't get defined on the holder, since they're
-    // supposed to be dynamic. This means that we have to first check the result
-    // of resolveOwnProperty, and _then_, if that comes up blank, check the
-    // holder for any cached native properties.
+    // depending on how ephemeral it decides the property is. This means that we have to
+    // first check the result of resolveOwnProperty, and _then_, if that comes up blank,
+    // check the holder for any cached native properties.
     //
     // Finally, we call resolveNativeProperty, which checks non-own properties,
     // and unconditionally caches what it finds on the holder.
 
     // Check resolveOwnProperty.
     if (!Traits::singleton.resolveOwnProperty(cx, wrapper, target, holder, id, desc))
         return false;
 
@@ -2607,18 +2320,16 @@ XrayWrapper<Base, Traits>::getPropertyKe
  * wrapped object (i.e. - whether it is safe from a security perspective to
  * unwrap the wrapper).
  */
 
 template<typename Base, typename Traits>
 const xpc::XrayWrapper<Base, Traits>
 xpc::XrayWrapper<Base, Traits>::singleton(0);
 
-template class PermissiveXrayXPCWN;
-template class SecurityXrayXPCWN;
 template class PermissiveXrayDOM;
 template class SecurityXrayDOM;
 template class PermissiveXrayJS;
 template class PermissiveXrayOpaque;
 
 /*
  * This callback is used by the JS engine to test if a proxy handler is for a
  * cross compartment xray with no security requirements.
--- a/js/xpconnect/wrappers/XrayWrapper.h
+++ b/js/xpconnect/wrappers/XrayWrapper.h
@@ -24,39 +24,34 @@
 
 // Xray wrappers re-resolve the original native properties on the native
 // object and always directly access to those properties.
 // Because they work so differently from the rest of the wrapper hierarchy,
 // we pull them out of the Wrapper inheritance hierarchy and create a
 // little world around them.
 
 class nsIPrincipal;
-class XPCWrappedNative;
 
 namespace xpc {
 
 namespace XrayUtils {
 
 bool
-IsXPCWNHolderClass(const JSClass* clasp);
-
-bool
 IsTransparent(JSContext* cx, JS::HandleObject wrapper, JS::HandleId id);
 
 JSObject*
 GetNativePropertiesObject(JSContext* cx, JSObject* wrapper);
 
 bool
 HasNativeProperty(JSContext* cx, JS::HandleObject wrapper, JS::HandleId id,
                   bool* hasProp);
 } // namespace XrayUtils
 
 enum XrayType {
     XrayForDOMObject,
-    XrayForWrappedNative,
     XrayForJSObject,
     XrayForOpaqueObject,
     NotXray
 };
 
 class XrayTraits
 {
 public:
@@ -141,56 +136,16 @@ private:
     JSObject* attachExpandoObject(JSContext* cx, JS::HandleObject target,
                                   JS::HandleObject exclusiveWrapper,
                                   nsIPrincipal* origin);
 
     XrayTraits(XrayTraits&) = delete;
     const XrayTraits& operator=(XrayTraits&) = delete;
 };
 
-class XPCWrappedNativeXrayTraits : public XrayTraits
-{
-public:
-    enum {
-        HasPrototype = 0
-    };
-
-    static const XrayType Type = XrayForWrappedNative;
-
-    virtual bool resolveNativeProperty(JSContext* cx, JS::HandleObject wrapper,
-                                       JS::HandleObject holder, JS::HandleId id,
-                                       JS::MutableHandle<JS::PropertyDescriptor> desc) override;
-    virtual bool resolveOwnProperty(JSContext* cx, JS::HandleObject wrapper, JS::HandleObject target,
-                                    JS::HandleObject holder, JS::HandleId id,
-                                    JS::MutableHandle<JS::PropertyDescriptor> desc) override;
-    bool defineProperty(JSContext* cx, JS::HandleObject wrapper, JS::HandleId id,
-                        JS::Handle<JS::PropertyDescriptor> desc,
-                        JS::Handle<JS::PropertyDescriptor> existingDesc,
-                        JS::ObjectOpResult& result, bool* defined)
-    {
-        *defined = false;
-        return true;
-    }
-    virtual bool enumerateNames(JSContext* cx, JS::HandleObject wrapper, unsigned flags,
-                                JS::AutoIdVector& props);
-    static bool call(JSContext* cx, JS::HandleObject wrapper,
-                     const JS::CallArgs& args, const js::Wrapper& baseInstance);
-    static bool construct(JSContext* cx, JS::HandleObject wrapper,
-                          const JS::CallArgs& args, const js::Wrapper& baseInstance);
-
-    static XPCWrappedNative* getWN(JSObject* wrapper);
-
-    virtual void preserveWrapper(JSObject* target) override;
-
-    virtual JSObject* createHolder(JSContext* cx, JSObject* wrapper) override;
-
-    static const JSClass HolderClass;
-    static XPCWrappedNativeXrayTraits singleton;
-};
-
 class DOMXrayTraits : public XrayTraits
 {
 public:
     constexpr DOMXrayTraits() = default;
 
     enum {
         HasPrototype = 1
     };
@@ -445,17 +400,17 @@ public:
 
     static OpaqueXrayTraits singleton;
 };
 
 XrayType GetXrayType(JSObject* obj);
 XrayTraits* GetXrayTraits(JSObject* obj);
 
 // NB: Base *must* derive from JSProxyHandler
-template <typename Base, typename Traits = XPCWrappedNativeXrayTraits >
+template <typename Base, typename Traits>
 class XrayWrapper : public Base {
   public:
     constexpr explicit XrayWrapper(unsigned flags)
       : Base(flags | WrapperFactory::IS_XRAY_WRAPPER_FLAG, Traits::HasPrototype)
     { };
 
     /* Standard internal methods. */
     virtual bool getOwnPropertyDescriptor(JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<jsid> id,
@@ -526,30 +481,25 @@ class XrayWrapper : public Base {
                                                         protop);
     }
 
   protected:
     bool getPropertyKeys(JSContext* cx, JS::Handle<JSObject*> wrapper, unsigned flags,
                          JS::AutoIdVector& props) const;
 };
 
-#define PermissiveXrayXPCWN xpc::XrayWrapper<js::CrossCompartmentWrapper, xpc::XPCWrappedNativeXrayTraits>
-#define SecurityXrayXPCWN xpc::XrayWrapper<js::CrossCompartmentSecurityWrapper, xpc::XPCWrappedNativeXrayTraits>
 #define PermissiveXrayDOM xpc::XrayWrapper<js::CrossCompartmentWrapper, xpc::DOMXrayTraits>
 #define SecurityXrayDOM xpc::XrayWrapper<js::CrossCompartmentSecurityWrapper, xpc::DOMXrayTraits>
 #define PermissiveXrayJS xpc::XrayWrapper<js::CrossCompartmentWrapper, xpc::JSXrayTraits>
 #define PermissiveXrayOpaque xpc::XrayWrapper<js::CrossCompartmentWrapper, xpc::OpaqueXrayTraits>
 
-extern template class PermissiveXrayXPCWN;
-extern template class SecurityXrayXPCWN;
 extern template class PermissiveXrayDOM;
 extern template class SecurityXrayDOM;
 extern template class PermissiveXrayJS;
 extern template class PermissiveXrayOpaque;
-extern template class PermissiveXrayXPCWN;
 
 class SandboxProxyHandler : public js::Wrapper {
 public:
     constexpr SandboxProxyHandler() : js::Wrapper(0)
     {
     }
 
     virtual bool getOwnPropertyDescriptor(JSContext* cx, JS::Handle<JSObject*> proxy,