Bug 1443983: Part 3 - Remove platform support for interpositions. r=mccr8
authorKris Maglione <maglione.k@gmail.com>
Wed, 07 Mar 2018 18:11:18 -0800
changeset 462288 f1431c234b4eb10d3c16067465bfc22e8699c1ed
parent 462287 a45d6d58a07d2f999b285e9a821822a21bd69ac4
child 462289 f34ad0155500e32c013d15b706986bc4726fd41c
push id1683
push usersfraser@mozilla.com
push dateThu, 26 Apr 2018 16:43:40 +0000
treeherdermozilla-release@5af6cb21869d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmccr8
bugs1443983
milestone60.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 1443983: Part 3 - Remove platform support for interpositions. r=mccr8 This is all dead code now that the interposition service has been removed. MozReview-Commit-ID: H6eS26y1f0f
devtools/shared/base-loader.js
js/xpconnect/idl/moz.build
js/xpconnect/idl/nsIAddonInterposition.idl
js/xpconnect/idl/xpccomponents.idl
js/xpconnect/src/Sandbox.cpp
js/xpconnect/src/XPCComponents.cpp
js/xpconnect/src/XPCJSRuntime.cpp
js/xpconnect/src/XPCWrappedNativeJSOps.cpp
js/xpconnect/src/XPCWrappedNativeScope.cpp
js/xpconnect/src/nsXPConnect.cpp
js/xpconnect/src/xpcprivate.h
js/xpconnect/tests/unit/test_interposition.js
js/xpconnect/tests/unit/xpcshell.ini
js/xpconnect/wrappers/AddonWrapper.cpp
js/xpconnect/wrappers/AddonWrapper.h
js/xpconnect/wrappers/WrapperFactory.cpp
js/xpconnect/wrappers/moz.build
--- a/devtools/shared/base-loader.js
+++ b/devtools/shared/base-loader.js
@@ -142,17 +142,16 @@ function Sandbox(options) {
   options = {
     // Do not expose `Components` if you really need them (bad idea!) you
     // still can expose via prototype.
     wantComponents: false,
     sandboxName: options.name,
     sandboxPrototype: "prototype" in options ? options.prototype : {},
     invisibleToDebugger: "invisibleToDebugger" in options ?
                          options.invisibleToDebugger : false,
-    waiveInterposition: false
   };
 
   let sandbox = Cu.Sandbox(systemPrincipal, options);
 
   delete sandbox.Components;
 
   return sandbox;
 }
--- a/js/xpconnect/idl/moz.build
+++ b/js/xpconnect/idl/moz.build
@@ -1,17 +1,16 @@
 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 XPIDL_SOURCES += [
     'mozIJSSubScriptLoader.idl',
-    'nsIAddonInterposition.idl',
     'nsIXPConnect.idl',
     'nsIXPCScriptable.idl',
     'xpccomponents.idl',
     'xpcIJSGetFactory.idl',
     'xpcIJSModuleLoader.idl',
     'xpcIJSWeakReference.idl',
     'xpcjsid.idl',
 ]
deleted file mode 100644
--- a/js/xpconnect/idl/nsIAddonInterposition.idl
+++ /dev/null
@@ -1,67 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsISupports.idl"
-
-/**
- * This interface allows Firefox to expose different implementations of its own
- * classes to add-ons. Once an interposition is created, it must be assigned to
- * an add-on using Cu.setAddonInterposition (JS) or xpc::SetAddonInterposition
- * (C++). In both cases, the arguments should be the add-on ID and the
- * interposition object (which must be an nsIAddonInterposition). This must
- * happen before any compartments are created for the given add-on.
- *
- * Every time the add-on accesses a property on any object outside its own set
- * of compartments, XPConnect will call the interposition's
- * interpose method. If the interposition wants to replace the given
- * property, it should return a replacement property descriptor for it. If not,
- * it should return null.
- */
-[scriptable,uuid(d05cc5fd-ad88-41a6-854c-36fd94d69ddb)]
-interface nsIAddonInterposition : nsISupports
-{
-    /**
-     * Returns a replacement property descriptor for a browser object.
-     *
-     * @param addonId The ID of the add-on accessing the property.
-     * @param target The browser object being accessed.
-     * @param iface The IID of the interface the property is associated with. This
-     *              parameter is only available for XPCWrappedNative targets. As
-     *              such, it's only useful as an optimization to avoid
-     *              instanceof checks on the target.
-     * @param prop The name of the property being accessed.
-     * @return A property descriptor or null.
-     */
-    jsval interposeProperty(in jsval addonId,
-                            in jsval target,
-                            in nsIIDPtr iface,
-                            in jsval prop);
-    /**
-     * We're intercepting calls from add-ons scopes into non-addon scopes.
-     *
-     * @param addonId The ID of the add-on accessing the property.
-     * @param originalFunc The function object being intercepted.
-     * @param originalThis The |this| value for the intercepted call.
-     * @param args The arguments of the original call in an array.
-     * @return The result of the call. NOTE: after the call interception,
-     * the original function will not be called automatically, so the
-     * implementer has to do that.
-     */
-    jsval interposeCall(in jsval addonId,
-                        in jsval originalFunc,
-                        in jsval originalThis,
-                        in jsval args);
-
-    /**
-     * For the first time when the interposition is registered the engine
-     * calls getWhitelist and expects an array of strings. The strings are
-     * the name of properties the interposition wants interposeProperty
-     * to be called. It can be an empty array.
-     * Note: for CPOWs interposeProperty is always called regardless if
-     * the name of the property is on the whitelist or not.
-     */
-    jsval getWhitelist();
-};
--- a/js/xpconnect/idl/xpccomponents.idl
+++ b/js/xpconnect/idl/xpccomponents.idl
@@ -5,17 +5,16 @@
 
 #include "nsISupports.idl"
 
 %{C++
 #include "jspubtd.h"
 %}
 
 interface xpcIJSWeakReference;
-interface nsIAddonInterposition;
 interface nsIClassInfo;
 interface nsIComponentManager;
 interface nsICycleCollectorListener;
 interface nsIFile;
 interface nsIURI;
 interface nsIJSCID;
 interface nsIJSIID;
 interface nsIPrincipal;
@@ -687,25 +686,16 @@ interface nsIXPCComponents_Utils : nsISu
      *
      * The string formats and values may change at any time. Do not depend on
      * this from addon code.
      */
     [implicit_jscontext]
     ACString getCompartmentLocation(in jsval obj);
 
     [implicit_jscontext]
-    void setAddonInterposition(in ACString addonId, in nsIAddonInterposition interposition);
-
-    /*
-     * Enables call interpositions from addon scopes to any functions in the scope of |target|.
-     */
-    [implicit_jscontext]
-    void setAddonCallInterposition(in jsval target);
-
-    [implicit_jscontext]
     void allowCPOWsInAddon(in ACString addonId, in bool allow);
 
     /*
      * Return a fractional number of milliseconds from process
      * startup, measured with a monotonic clock.
      */
     double now();
 
--- a/js/xpconnect/src/Sandbox.cpp
+++ b/js/xpconnect/src/Sandbox.cpp
@@ -1165,17 +1165,16 @@ xpc::CreateSandboxObject(JSContext* cx, 
         return NS_ERROR_FAILURE;
 
     RealmPrivate* realmPriv = RealmPrivate::Get(sandbox);
     realmPriv->writeToGlobalPrototype = options.writeToGlobalPrototype;
 
     CompartmentPrivate* priv = CompartmentPrivate::Get(sandbox);
     priv->allowWaivers = options.allowWaivers;
     priv->isWebExtensionContentScript = options.isWebExtensionContentScript;
-    priv->waiveInterposition = options.waiveInterposition;
     priv->isContentXBLCompartment = options.isContentXBLScope;
 
     // Set up the wantXrays flag, which indicates whether xrays are desired even
     // for same-origin access.
     //
     // This flag has historically been ignored for chrome sandboxes due to
     // quirks in the wrapping implementation that have now been removed. Indeed,
     // same-origin Xrays for chrome->chrome access seems a bit superfluous.
@@ -1728,17 +1727,16 @@ SandboxOptions::Parse()
 {
     /* All option names must be ASCII-only. */
     bool ok = ParseObject("sandboxPrototype", &proto) &&
               ParseBoolean("wantXrays", &wantXrays) &&
               ParseBoolean("allowWaivers", &allowWaivers) &&
               ParseBoolean("wantComponents", &wantComponents) &&
               ParseBoolean("wantExportHelpers", &wantExportHelpers) &&
               ParseBoolean("isWebExtensionContentScript", &isWebExtensionContentScript) &&
-              ParseBoolean("waiveInterposition", &waiveInterposition) &&
               ParseString("sandboxName", sandboxName) &&
               ParseObject("sameZoneAs", &sameZoneAs) &&
               ParseBoolean("freshZone", &freshZone) &&
               ParseBoolean("invisibleToDebugger", &invisibleToDebugger) &&
               ParseBoolean("discardSource", &discardSource) &&
               ParseJSString("addonId", &addonId) &&
               ParseBoolean("writeToGlobalPrototype", &writeToGlobalPrototype) &&
               ParseGlobalProperties() &&
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -30,17 +30,16 @@
 #include "mozilla/dom/StructuredCloneTags.h"
 #include "mozilla/dom/WindowBinding.h"
 #include "mozilla/Scheduler.h"
 #include "nsZipArchive.h"
 #include "nsIDOMFileList.h"
 #include "nsWindowMemoryReporter.h"
 #include "nsDOMClassInfo.h"
 #include "ShimInterfaceInfo.h"
-#include "nsIAddonInterposition.h"
 #include "nsIException.h"
 #include "nsIScriptError.h"
 #include "nsISimpleEnumerator.h"
 #include "nsPIDOMWindow.h"
 #include "nsGlobalWindow.h"
 #include "nsScriptError.h"
 #include "GeckoProfiler.h"
 
@@ -3102,43 +3101,16 @@ nsXPCComponents_Utils::GetCompartmentLoc
     obj = js::CheckedUnwrap(obj);
     MOZ_ASSERT(obj);
 
     result = xpc::CompartmentPrivate::Get(obj)->GetLocation();
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXPCComponents_Utils::SetAddonInterposition(const nsACString& addonIdStr,
-                                             nsIAddonInterposition* interposition,
-                                             JSContext* cx)
-{
-    JSAddonId* addonId = xpc::NewAddonId(cx, addonIdStr);
-    if (!addonId)
-        return NS_ERROR_FAILURE;
-    if (!XPCWrappedNativeScope::SetAddonInterposition(cx, addonId, interposition))
-        return NS_ERROR_FAILURE;
-
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsXPCComponents_Utils::SetAddonCallInterposition(HandleValue target,
-                                                 JSContext* cx)
-{
-    NS_ENSURE_TRUE(target.isObject(), NS_ERROR_INVALID_ARG);
-    RootedObject targetObj(cx, &target.toObject());
-    targetObj = js::CheckedUnwrap(targetObj);
-    NS_ENSURE_TRUE(targetObj, NS_ERROR_INVALID_ARG);
-
-    xpc::CompartmentPrivate::Get(targetObj)->SetAddonCallInterposition();
-    return NS_OK;
-}
-
-NS_IMETHODIMP
 nsXPCComponents_Utils::AllowCPOWsInAddon(const nsACString& addonIdStr,
                                          bool allow,
                                          JSContext* cx)
 {
     JSAddonId* addonId = xpc::NewAddonId(cx, addonIdStr);
     if (!addonId)
         return NS_ERROR_FAILURE;
     if (!XPCWrappedNativeScope::AllowCPOWsInAddon(cx, addonId, allow))
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -166,19 +166,16 @@ public:
 };
 
 namespace xpc {
 
 CompartmentPrivate::CompartmentPrivate(JSCompartment* c)
     : wantXrays(false)
     , allowWaivers(true)
     , isWebExtensionContentScript(false)
-    , hasInterposition(false)
-    , waiveInterposition(false)
-    , addonCallInterposition(false)
     , allowCPOWs(false)
     , isContentXBLCompartment(false)
     , isAddonCompartment(false)
     , universalXPConnectEnabled(false)
     , forcePermissiveCOWs(false)
     , wasNuked(false)
     , mWrappedJSMap(JSObject2WrappedJSMap::newMap(XPC_JS_MAP_LENGTH))
 {
--- a/js/xpconnect/src/XPCWrappedNativeJSOps.cpp
+++ b/js/xpconnect/src/XPCWrappedNativeJSOps.cpp
@@ -5,18 +5,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* JavaScript JSClasses and JSOps for our Wrapped Native JS Objects. */
 
 #include "xpcprivate.h"
 #include "xpc_make_class.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/Preferences.h"
-#include "nsIAddonInterposition.h"
-#include "AddonWrapper.h"
 #include "js/Class.h"
 #include "js/Printf.h"
 
 using namespace mozilla;
 using namespace JS;
 
 /***************************************************************************/
 
@@ -393,30 +391,16 @@ DefinePropertyIfFound(XPCCallContext& cc
         RootedValue val(ccx);
         AutoResolveName arn(ccx, id);
         if (resolved)
             *resolved = true;
         return member->GetConstantValue(ccx, iface, val.address()) &&
                JS_DefinePropertyById(ccx, obj, id, val, propFlags);
     }
 
-    if (scope->HasInterposition()) {
-        Rooted<PropertyDescriptor> desc(ccx);
-        if (!xpc::InterposeProperty(ccx, obj, iface->GetIID(), id, &desc))
-            return false;
-
-        if (desc.object()) {
-            AutoResolveName arn(ccx, id);
-            if (resolved)
-                *resolved = true;
-            desc.attributesRef() |= JSPROP_RESOLVING;
-            return JS_DefinePropertyById(ccx, obj, id, desc);
-        }
-    }
-
     if (id == xpccx->GetStringID(XPCJSContext::IDX_TO_STRING) ||
         id == xpccx->GetStringID(XPCJSContext::IDX_TO_SOURCE) ||
         (scr &&
          scr->DontEnumQueryInterface() &&
          id == xpccx->GetStringID(XPCJSContext::IDX_QUERY_INTERFACE)))
         propFlags &= ~JSPROP_ENUMERATE;
 
     RootedValue funval(ccx);
--- a/js/xpconnect/src/XPCWrappedNativeScope.cpp
+++ b/js/xpconnect/src/XPCWrappedNativeScope.cpp
@@ -8,58 +8,41 @@
 
 #include "xpcprivate.h"
 #include "XPCWrapper.h"
 #include "nsContentUtils.h"
 #include "nsCycleCollectionNoteRootCallback.h"
 #include "ExpandedPrincipal.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/Preferences.h"
-#include "nsIAddonInterposition.h"
 #include "nsIXULRuntime.h"
 #include "mozJSComponentLoader.h"
 
 #include "mozilla/dom/BindingUtils.h"
 
 using namespace mozilla;
 using namespace xpc;
 using namespace JS;
 
 /***************************************************************************/
 
 XPCWrappedNativeScope* XPCWrappedNativeScope::gScopes = nullptr;
 XPCWrappedNativeScope* XPCWrappedNativeScope::gDyingScopes = nullptr;
 bool XPCWrappedNativeScope::gShutdownObserverInitialized = false;
-XPCWrappedNativeScope::InterpositionMap* XPCWrappedNativeScope::gInterpositionMap = nullptr;
-InterpositionWhitelistArray* XPCWrappedNativeScope::gInterpositionWhitelists = nullptr;
 XPCWrappedNativeScope::AddonSet* XPCWrappedNativeScope::gAllowCPOWAddonSet = nullptr;
 
 NS_IMPL_ISUPPORTS(XPCWrappedNativeScope::ClearInterpositionsObserver, nsIObserver)
 
 NS_IMETHODIMP
 XPCWrappedNativeScope::ClearInterpositionsObserver::Observe(nsISupports* subject,
                                                             const char* topic,
                                                             const char16_t* data)
 {
     MOZ_ASSERT(strcmp(topic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0);
 
-    // The interposition map holds strong references to interpositions, which
-    // may themselves be involved in cycles. We need to drop these strong
-    // references before the cycle collector shuts down. Otherwise we'll
-    // leak. This observer always runs before CC shutdown.
-    if (gInterpositionMap) {
-        delete gInterpositionMap;
-        gInterpositionMap = nullptr;
-    }
-
-    if (gInterpositionWhitelists) {
-        delete gInterpositionWhitelists;
-        gInterpositionWhitelists = nullptr;
-    }
-
     if (gAllowCPOWAddonSet) {
         delete gAllowCPOWAddonSet;
         gAllowCPOWAddonSet = nullptr;
     }
 
     nsContentUtils::UnregisterShutdownObserver(this);
     return NS_OK;
 }
@@ -139,41 +122,17 @@ XPCWrappedNativeScope::XPCWrappedNativeS
     if (mUseContentXBLScope) {
         const js::Class* clasp = js::GetObjectClass(mGlobalJSObject);
         mUseContentXBLScope = !strcmp(clasp->name, "Window");
     }
     if (mUseContentXBLScope) {
         mUseContentXBLScope = principal && !nsContentUtils::IsSystemPrincipal(principal);
     }
 
-    JSAddonId* addonId = JS::AddonIdOfObject(aGlobal);
-    if (gInterpositionMap) {
-        bool isSystem = nsContentUtils::IsSystemPrincipal(principal);
-        bool waiveInterposition = priv->waiveInterposition;
-        InterpositionMap::Ptr interposition = gInterpositionMap->lookup(addonId);
-        if (!waiveInterposition && interposition) {
-            MOZ_RELEASE_ASSERT(isSystem);
-            mInterposition = interposition->value();
-            priv->hasInterposition = HasInterposition();
-        }
-        // We also want multiprocessCompatible add-ons to have a default interposition.
-        if (!mInterposition && addonId && isSystem) {
-            bool interpositionEnabled = mozilla::Preferences::GetBool(
-                "extensions.interposition.enabled", false);
-            if (interpositionEnabled) {
-                mInterposition = do_GetService("@mozilla.org/addons/default-addon-shims;1");
-                MOZ_ASSERT(mInterposition);
-                priv->hasInterposition = true;
-                UpdateInterpositionWhitelist(cx, mInterposition);
-            }
-        }
-        MOZ_ASSERT(HasInterposition() == priv->hasInterposition);
-    }
-
-    if (addonId) {
+    if (JSAddonId* addonId = JS::AddonIdOfObject(aGlobal)) {
         // We forbid CPOWs unless they're specifically allowed.
         priv->allowCPOWs = gAllowCPOWAddonSet ? gAllowCPOWAddonSet->has(addonId) : false;
         MOZ_ASSERT(!mozJSComponentLoader::Get()->IsLoaderGlobal(aGlobal),
                    "Don't load addons into the shared JSM global");
     }
 }
 
 // static
@@ -770,41 +729,16 @@ XPCWrappedNativeScope::SetExpandoChain(J
     MOZ_ASSERT(js::IsObjectInContextCompartment(target, cx));
     MOZ_ASSERT_IF(chain, ObjectScope(chain) == this);
     if (!mXrayExpandos.initialized() && !mXrayExpandos.init(cx))
         return false;
     return mXrayExpandos.put(cx, target, chain);
 }
 
 /* static */ bool
-XPCWrappedNativeScope::SetAddonInterposition(JSContext* cx,
-                                             JSAddonId* addonId,
-                                             nsIAddonInterposition* interp)
-{
-    if (!gInterpositionMap) {
-        gInterpositionMap = new InterpositionMap();
-        bool ok = gInterpositionMap->init();
-        NS_ENSURE_TRUE(ok, false);
-
-        if (!gShutdownObserverInitialized) {
-            gShutdownObserverInitialized = true;
-            nsContentUtils::RegisterShutdownObserver(new ClearInterpositionsObserver());
-        }
-    }
-    if (interp) {
-        bool ok = gInterpositionMap->put(addonId, interp);
-        NS_ENSURE_TRUE(ok, false);
-        UpdateInterpositionWhitelist(cx, interp);
-    } else {
-        gInterpositionMap->remove(addonId);
-    }
-    return true;
-}
-
-/* static */ bool
 XPCWrappedNativeScope::AllowCPOWsInAddon(JSContext* cx,
                                          JSAddonId* addonId,
                                          bool allow)
 {
     if (!gAllowCPOWAddonSet) {
         gAllowCPOWAddonSet = new AddonSet();
         bool ok = gAllowCPOWAddonSet->init();
         NS_ENSURE_TRUE(ok, false);
@@ -818,131 +752,16 @@ XPCWrappedNativeScope::AllowCPOWsInAddon
         bool ok = gAllowCPOWAddonSet->put(addonId);
         NS_ENSURE_TRUE(ok, false);
     } else {
         gAllowCPOWAddonSet->remove(addonId);
     }
     return true;
 }
 
-nsCOMPtr<nsIAddonInterposition>
-XPCWrappedNativeScope::GetInterposition()
-{
-    return mInterposition;
-}
-
-/* static */ InterpositionWhitelist*
-XPCWrappedNativeScope::GetInterpositionWhitelist(nsIAddonInterposition* interposition)
-{
-    if (!gInterpositionWhitelists)
-        return nullptr;
-
-    InterpositionWhitelistArray& wls = *gInterpositionWhitelists;
-    for (size_t i = 0; i < wls.Length(); i++) {
-        if (wls[i].interposition == interposition)
-            return &wls[i].whitelist;
-    }
-
-    return nullptr;
-}
-
-/* static */ bool
-XPCWrappedNativeScope::UpdateInterpositionWhitelist(JSContext* cx,
-                                                    nsIAddonInterposition* interposition)
-{
-    // We want to set the interpostion whitelist only once.
-    InterpositionWhitelist* whitelist = GetInterpositionWhitelist(interposition);
-    if (whitelist)
-        return true;
-
-    // The hashsets in gInterpositionWhitelists do not have a copy constructor so
-    // a reallocation for the array will lead to a memory corruption. If you
-    // need more interpositions, change the capacity of the array please.
-    static const size_t MAX_INTERPOSITION = 8;
-    if (!gInterpositionWhitelists)
-        gInterpositionWhitelists = new InterpositionWhitelistArray(MAX_INTERPOSITION);
-
-    MOZ_RELEASE_ASSERT(MAX_INTERPOSITION > gInterpositionWhitelists->Length() + 1);
-    InterpositionWhitelistPair* newPair = gInterpositionWhitelists->AppendElement();
-    newPair->interposition = interposition;
-    if (!newPair->whitelist.init()) {
-        JS_ReportOutOfMemory(cx);
-        return false;
-    }
-
-    whitelist = &newPair->whitelist;
-
-    RootedValue whitelistVal(cx);
-    nsresult rv = interposition->GetWhitelist(&whitelistVal);
-    if (NS_FAILED(rv)) {
-        JS_ReportErrorASCII(cx, "Could not get the whitelist from the interposition.");
-        return false;
-    }
-
-    if (!whitelistVal.isObject()) {
-        JS_ReportErrorASCII(cx, "Whitelist must be an array.");
-        return false;
-    }
-
-    // We want to enter the whitelist's compartment to avoid any wrappers.
-    // To be on the safe side let's make sure that it's a system compartment
-    // and we don't accidentally trigger some content function here by parsing
-    // the whitelist object.
-    RootedObject whitelistObj(cx, &whitelistVal.toObject());
-    whitelistObj = js::UncheckedUnwrap(whitelistObj);
-    if (!AccessCheck::isChrome(whitelistObj)) {
-        JS_ReportErrorASCII(cx, "Whitelist must be from system scope.");
-        return false;
-    }
-
-    {
-        JSAutoCompartment ac(cx, whitelistObj);
-
-        bool isArray;
-        if (!JS_IsArrayObject(cx, whitelistObj, &isArray))
-            return false;
-
-        if (!isArray) {
-            JS_ReportErrorASCII(cx, "Whitelist must be an array.");
-            return false;
-        }
-
-        uint32_t length;
-        if (!JS_GetArrayLength(cx, whitelistObj, &length))
-            return false;
-
-        for (uint32_t i = 0; i < length; i++) {
-            RootedValue idval(cx);
-            if (!JS_GetElement(cx, whitelistObj, i, &idval))
-                return false;
-
-            if (!idval.isString()) {
-                JS_ReportErrorASCII(cx, "Whitelist must contain strings only.");
-                return false;
-            }
-
-            RootedString str(cx, idval.toString());
-            str = JS_AtomizeAndPinJSString(cx, str);
-            if (!str) {
-                JS_ReportErrorASCII(cx, "String internization failed.");
-                return false;
-            }
-
-            // By internizing the id's we ensure that they won't get
-            // GCed so we can use them as hash keys.
-            jsid id = INTERNED_STRING_TO_JSID(cx, str);
-            if (!whitelist->put(JSID_BITS(id))) {
-                JS_ReportOutOfMemory(cx);
-                return false;
-            }
-        }
-    }
-
-    return true;
-}
 
 /***************************************************************************/
 
 // static
 void
 XPCWrappedNativeScope::DebugDumpAllScopes(int16_t depth)
 {
 #ifdef DEBUG
--- a/js/xpconnect/src/nsXPConnect.cpp
+++ b/js/xpconnect/src/nsXPConnect.cpp
@@ -1187,31 +1187,16 @@ NewAddonId(JSContext* cx, const nsACStri
 {
     JS::RootedString str(cx, JS_NewStringCopyN(cx, id.BeginReading(), id.Length()));
     if (!str)
         return nullptr;
     return JS::NewAddonId(cx, str);
 }
 
 bool
-SetAddonInterposition(const nsACString& addonIdStr, nsIAddonInterposition* interposition)
-{
-    JSAddonId* addonId;
-    // We enter the junk scope just to allocate a string, which actually will go
-    // in the system zone.
-    AutoJSAPI jsapi;
-    if (!jsapi.Init(xpc::PrivilegedJunkScope()))
-        return false;
-    addonId = NewAddonId(jsapi.cx(), addonIdStr);
-    if (!addonId)
-        return false;
-    return XPCWrappedNativeScope::SetAddonInterposition(jsapi.cx(), addonId, interposition);
-}
-
-bool
 AllowCPOWsInAddon(const nsACString& addonIdStr, bool allow)
 {
     JSAddonId* addonId;
     // We enter the junk scope just to allocate a string, which actually will go
     // in the system zone.
     AutoJSAPI jsapi;
     if (!jsapi.Init(xpc::PrivilegedJunkScope()))
         return false;
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -853,31 +853,19 @@ XPC_WN_GetterSetter(JSContext* cx, unsig
 // XPC_WN_Shared_Proto_Enumerate or something rather than checking for
 // 4 classes?
 static inline bool IS_PROTO_CLASS(const js::Class* clazz)
 {
     return clazz == &XPC_WN_NoMods_Proto_JSClass ||
            clazz == &XPC_WN_ModsAllowed_Proto_JSClass;
 }
 
-typedef js::HashSet<size_t,
-                    js::DefaultHasher<size_t>,
-                    js::SystemAllocPolicy> InterpositionWhitelist;
-
-struct InterpositionWhitelistPair {
-    nsIAddonInterposition* interposition;
-    InterpositionWhitelist whitelist;
-};
-
-typedef nsTArray<InterpositionWhitelistPair> InterpositionWhitelistArray;
-
 /***************************************************************************/
 // XPCWrappedNativeScope is one-to-one with a JS global object.
 
-class nsIAddonInterposition;
 class nsXPCComponentsBase;
 class XPCWrappedNativeScope final
 {
 public:
 
     XPCJSRuntime*
     GetRuntime() const {return XPCJSRuntime::Get();}
 
@@ -981,21 +969,16 @@ public:
     AddSizeOfAllScopesIncludingThis(ScopeSizeInfo* scopeSizeInfo);
 
     void
     AddSizeOfIncludingThis(ScopeSizeInfo* scopeSizeInfo);
 
     static bool
     IsDyingScope(XPCWrappedNativeScope* scope);
 
-    typedef js::HashMap<JSAddonId*,
-                        nsCOMPtr<nsIAddonInterposition>,
-                        js::PointerHasher<JSAddonId*>,
-                        js::SystemAllocPolicy> InterpositionMap;
-
     typedef js::HashSet<JSAddonId*,
                         js::PointerHasher<JSAddonId*>,
                         js::SystemAllocPolicy> AddonSet;
 
     // Gets the appropriate scope object for XBL in this scope. The context
     // must be same-compartment with the global upon entering, and the scope
     // object is wrapped into the compartment of the global.
     JSObject* EnsureContentXBLScope(JSContext* cx);
@@ -1010,27 +993,16 @@ public:
 
     bool IsContentXBLScope() { return xpc::IsContentXBLCompartment(Compartment()); }
     bool AllowContentXBLScope();
     bool UseContentXBLScope() { return mUseContentXBLScope; }
     void ClearContentXBLScope() { mContentXBLScope = nullptr; }
 
     bool IsAddonScope() { return xpc::IsAddonCompartment(Compartment()); }
 
-    inline bool HasInterposition() { return mInterposition; }
-    nsCOMPtr<nsIAddonInterposition> GetInterposition();
-
-    static bool SetAddonInterposition(JSContext* cx,
-                                      JSAddonId* addonId,
-                                      nsIAddonInterposition* interp);
-
-    static InterpositionWhitelist* GetInterpositionWhitelist(nsIAddonInterposition* interposition);
-    static bool UpdateInterpositionWhitelist(JSContext* cx,
-                                             nsIAddonInterposition* interposition);
-
     static bool AllowCPOWsInAddon(JSContext* cx, JSAddonId* addonId, bool allow);
 
 protected:
     virtual ~XPCWrappedNativeScope();
 
     XPCWrappedNativeScope() = delete;
 
 private:
@@ -1041,21 +1013,18 @@ private:
         NS_DECL_ISUPPORTS
         NS_DECL_NSIOBSERVER
     };
 
     static XPCWrappedNativeScope* gScopes;
     static XPCWrappedNativeScope* gDyingScopes;
 
     static bool                      gShutdownObserverInitialized;
-    static InterpositionMap*         gInterpositionMap;
     static AddonSet*                 gAllowCPOWAddonSet;
 
-    static InterpositionWhitelistArray* gInterpositionWhitelists;
-
     Native2WrappedNativeMap*         mWrappedNativeMap;
     ClassInfo2WrappedNativeProtoMap* mWrappedNativeProtoMap;
     RefPtr<nsXPCComponentsBase>    mComponents;
     XPCWrappedNativeScope*           mNext;
     // The JS global object for this scope.  If non-null, this will be the
     // default parent for the XPCWrappedNatives that have us as the scope,
     // unless a PreCreate hook overrides it.  Note that this _may_ be null (see
     // constructor).
@@ -1064,20 +1033,16 @@ private:
     // XBL Scope. This is is a lazily-created sandbox for non-system scopes.
     // EnsureContentXBLScope() decides whether it needs to be created or not.
     // This reference is wrapped into the compartment of mGlobalJSObject.
     JS::ObjectPtr                    mContentXBLScope;
 
     // Lazily created sandboxes for addon code.
     nsTArray<JS::ObjectPtr>          mAddonScopes;
 
-    // This is a service that will be use to interpose on some property accesses on
-    // objects from other scope, for add-on compatibility reasons.
-    nsCOMPtr<nsIAddonInterposition>  mInterposition;
-
     JS::WeakMapPtr<JSObject*, JSObject*> mXrayExpandos;
 
     // For remote XUL domains, we run all XBL in the content scope for compat
     // reasons (though we sometimes pref this off for automation). We separately
     // track the result of this decision (mAllowContentXBLScope), from the decision
     // of whether to actually _use_ an XBL scope (mUseContentXBLScope), which depends
     // on the type of global and whether the compartment is system principal
     // or not.
@@ -2744,17 +2709,16 @@ public:
     explicit SandboxOptions(JSContext* cx = xpc_GetSafeJSContext(),
                             JSObject* options = nullptr)
         : OptionsBase(cx, options)
         , wantXrays(true)
         , allowWaivers(true)
         , wantComponents(true)
         , wantExportHelpers(false)
         , isWebExtensionContentScript(false)
-        , waiveInterposition(false)
         , proto(cx)
         , addonId(cx)
         , writeToGlobalPrototype(false)
         , sameZoneAs(cx)
         , freshZone(false)
         , isContentXBLScope(false)
         , invisibleToDebugger(false)
         , discardSource(false)
@@ -2765,17 +2729,16 @@ public:
 
     virtual bool Parse() override;
 
     bool wantXrays;
     bool allowWaivers;
     bool wantComponents;
     bool wantExportHelpers;
     bool isWebExtensionContentScript;
-    bool waiveInterposition;
     JS::RootedObject proto;
     nsCString sandboxName;
     JS::RootedString addonId;
     bool writeToGlobalPrototype;
     JS::RootedObject sameZoneAs;
     bool freshZone;
     bool isContentXBLScope;
     bool invisibleToDebugger;
@@ -3031,31 +2994,16 @@ public:
     // disable the writeToGlobalPrototype behavior (when resolving standard
     // classes, for example).
     bool skipWriteToGlobalPrototype;
 
     // This compartment corresponds to a WebExtension content script, and
     // receives various bits of special compatibility behavior.
     bool isWebExtensionContentScript;
 
-    // True if wrappers in this compartment will interpose on some property
-    // accesses on objects from other compartments, for add-on compatibility
-    // reasons.
-    bool hasInterposition;
-
-    // Even if an add-on needs interposition, it does not necessary need it
-    // for every compartment. If this flag is set we waive interposition for
-    // this compartment.
-    bool waiveInterposition;
-
-    // If this flag is set, we intercept function calls on vanilla JS function
-    // objects from this compartment if the caller compartment has the
-    // hasInterposition flag set.
-    bool addonCallInterposition;
-
     // If CPOWs are disabled for browser code via the
     // dom.ipc.cpows.forbid-unsafe-from-browser preferences, then only
     // add-ons can use CPOWs. This flag allows a non-addon scope
     // to opt into CPOWs. It's necessary for the implementation of
     // RemoteAddonsParent.jsm.
     bool allowCPOWs;
 
     // True if this compartment is a content XBL compartment. Every global in
@@ -3128,18 +3076,16 @@ public:
     void SetLocationURI(nsIURI* aLocationURI) {
         if (!aLocationURI)
             return;
         if (locationURI)
             return;
         locationURI = aLocationURI;
     }
 
-    void SetAddonCallInterposition() { addonCallInterposition = true; }
-
     JSObject2WrappedJSMap* GetWrappedJSMap() const { return mWrappedJSMap; }
     void UpdateWeakPointersAfterGC();
 
     size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf);
 
 private:
     nsCString location;
     nsCOMPtr<nsIURI> locationURI;
deleted file mode 100644
--- a/js/xpconnect/tests/unit/test_interposition.js
+++ /dev/null
@@ -1,161 +0,0 @@
-ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-
-const ADDONID = "bogus-addon@mozilla.org";
-
-let gExpectedProp;
-function expectAccess(prop, f)
-{
-  gExpectedProp = prop;
-  f();
-  Assert.equal(gExpectedProp, undefined);
-}
-
-let getter_run = false;
-function test_getter()
-{
-  Assert.equal(getter_run, false);
-  getter_run = true;
-  return 200;
-}
-
-let setter_run = false;
-function test_setter(v)
-{
-  Assert.equal(setter_run, false);
-  Assert.equal(v, 300);
-  setter_run = true;
-}
-
-let TestInterposition = {
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIAddonInterposition,
-                                         Ci.nsISupportsWeakReference]),
-
-  getWhitelist: function() {
-    return ["abcxyz", "utils", "dataprop", "getterprop", "setterprop",
-            "objprop", "defineprop", "configurableprop"];
-  },
-
-  interposeProperty: function(addonId, target, iid, prop) {
-    Assert.equal(addonId, ADDONID);
-    Assert.equal(gExpectedProp, prop);
-    gExpectedProp = undefined;
-
-    if (prop == "dataprop") {
-      return { configurable: false, enumerable: true, writable: false, value: 100 };
-    } else if (prop == "getterprop") {
-      return { configurable: false, enumerable: true, get: test_getter };
-    } else if (prop == "setterprop") {
-      return { configurable: false, enumerable: true, get: test_getter, set: test_setter };
-    } else if (prop == "utils") {
-      Assert.equal(iid, Ci.nsIXPCComponents.number);
-      return null;
-    } else if (prop == "objprop") {
-      gExpectedProp = "objprop"; // allow recursive access here
-      return { configurable: false, enumerable: true, writable: false, value: { objprop: 1 } };
-    } else if (prop == "configurableprop") {
-      return { configurable: true, enumerable: true, writable: false, value: 10 };
-    }
-
-    return null;
-  },
-
-  interposeCall: function(addonId, originalFunc, originalThis, args) {
-    Assert.equal(addonId, ADDONID);
-    args.splice(0, 0, addonId);
-    return originalFunc.apply(originalThis, args);
-  }
-};
-
-function run_test()
-{
-  Cu.setAddonInterposition(ADDONID, TestInterposition);
-
-  Cu.importGlobalProperties(["XMLHttpRequest"]);
-
-  let sandbox = Cu.Sandbox(this, {addonId: ADDONID});
-  sandbox.outerObj = new XMLHttpRequest();
-
-  expectAccess("abcxyz", () => {
-    Cu.evalInSandbox("outerObj.abcxyz = 12;", sandbox);
-  });
-
-  expectAccess("utils", () => {
-    Cu.evalInSandbox("Components.utils;", sandbox);
-  });
-
-  expectAccess("dataprop", () => {
-    Assert.equal(Cu.evalInSandbox("outerObj.dataprop;", sandbox), 100);
-  });
-
-  expectAccess("dataprop", () => {
-    try {
-      Cu.evalInSandbox("'use strict'; outerObj.dataprop = 400;", sandbox);
-      Assert.ok(false); // it should throw
-    } catch (e) {}
-  });
-
-  expectAccess("objprop", () => {
-    Cu.evalInSandbox("outerObj.objprop.objprop;", sandbox);
-    gExpectedProp = undefined;
-  });
-
-  expectAccess("getterprop", () => {
-    Assert.equal(Cu.evalInSandbox("outerObj.getterprop;", sandbox), 200);
-    Assert.equal(getter_run, true);
-    getter_run = false;
-  });
-
-  expectAccess("getterprop", () => {
-    try {
-      Cu.evalInSandbox("'use strict'; outerObj.getterprop = 400;", sandbox);
-      Assert.ok(false); // it should throw
-    } catch (e) {}
-    Assert.equal(getter_run, false);
-  });
-
-  expectAccess("setterprop", () => {
-    Assert.equal(Cu.evalInSandbox("outerObj.setterprop;", sandbox), 200);
-    Assert.equal(getter_run, true);
-    getter_run = false;
-    Assert.equal(setter_run, false);
-  });
-
-  expectAccess("setterprop", () => {
-    Cu.evalInSandbox("'use strict'; outerObj.setterprop = 300;", sandbox);
-    Assert.equal(getter_run, false);
-    Assert.equal(setter_run, true);
-    setter_run = false;
-  });
-
-  // Make sure that calling Object.defineProperty succeeds as long as
-  // we're not interposing on that property.
-  expectAccess("defineprop", () => {
-    Cu.evalInSandbox("'use strict'; Object.defineProperty(outerObj, 'defineprop', {configurable:true, enumerable:true, writable:true, value:10});", sandbox);
-  });
-
-  // Related to above: make sure we can delete those properties too.
-  expectAccess("defineprop", () => {
-    Cu.evalInSandbox("'use strict'; delete outerObj.defineprop;", sandbox);
-  });
-
-  // Make sure we get configurable=false even if the interposition
-  // sets it to true.
-  expectAccess("configurableprop", () => {
-    let desc = Cu.evalInSandbox("Object.getOwnPropertyDescriptor(outerObj, 'configurableprop')", sandbox);
-    Assert.equal(desc.configurable, false);
-  });
-
-  let moduleScope = Cu.Sandbox(this);
-  moduleScope.ADDONID = ADDONID;
-  moduleScope.equal = equal;
-  function funToIntercept(addonId) {
-    equal(addonId, ADDONID);
-    counter++;
-  }
-  sandbox.moduleFunction = Cu.evalInSandbox(funToIntercept.toSource() + "; funToIntercept", moduleScope);
-  Cu.evalInSandbox("var counter = 0;", moduleScope);
-  Cu.evalInSandbox("Components.utils.setAddonCallInterposition(this);", moduleScope);
-  Cu.evalInSandbox("moduleFunction()", sandbox);
-  Assert.equal(Cu.evalInSandbox("counter", moduleScope), 1);
-  Cu.setAddonInterposition(ADDONID, null);
-}
--- a/js/xpconnect/tests/unit/xpcshell.ini
+++ b/js/xpconnect/tests/unit/xpcshell.ini
@@ -70,17 +70,16 @@ support-files =
 [test_defineModuleGetter.js]
 [test_file.js]
 [test_blob.js]
 [test_blob2.js]
 [test_file2.js]
 [test_getCallerLocation.js]
 [test_import.js]
 [test_import_fail.js]
-[test_interposition.js]
 [test_isModuleLoaded.js]
 [test_js_weak_references.js]
 [test_onGarbageCollection-01.js]
 head = head_ongc.js
 [test_onGarbageCollection-02.js]
 head = head_ongc.js
 [test_onGarbageCollection-03.js]
 head = head_ongc.js
deleted file mode 100644
--- a/js/xpconnect/wrappers/AddonWrapper.cpp
+++ /dev/null
@@ -1,300 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* vim: set ts=8 sts=4 et sw=4 tw=99: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "AddonWrapper.h"
-#include "WrapperFactory.h"
-#include "XrayWrapper.h"
-#include "jsapi.h"
-#include "jsfriendapi.h"
-#include "nsIAddonInterposition.h"
-#include "xpcprivate.h"
-#include "mozilla/dom/BindingUtils.h"
-#include "nsGlobalWindow.h"
-
-#include "GeckoProfiler.h"
-
-#include "nsID.h"
-
-using namespace js;
-using namespace JS;
-
-namespace xpc {
-
-static inline void
-ReportASCIIErrorWithId(JSContext* cx, const char* msg, HandleId id)
-{
-    RootedValue idv(cx);
-    if (!JS_IdToValue(cx, id, &idv))
-        return;
-    RootedString idstr(cx, JS::ToString(cx, idv));
-    if (!idstr)
-        return;
-    JSAutoByteString bytes;
-    if (!bytes.encodeUtf8(cx, idstr))
-        return;
-    JS_ReportErrorUTF8(cx, msg, bytes.ptr());
-}
-
-bool
-RequiresInterpositions(JSContext* cx, HandleObject unwrapped)
-{
-    Rooted<PropertyDescriptor> desc(cx);
-    JSAutoCompartment ac(cx, unwrapped);
-
-    if (!JS_GetOwnPropertyDescriptor(cx, unwrapped, "requiresAddonInterpositions", &desc)) {
-        JS_ClearPendingException(cx);
-        return false;
-    }
-
-    return desc.hasValue() && desc.value().isTrue();
-}
-
-bool
-InterposeProperty(JSContext* cx, HandleObject target, const nsIID* iid, HandleId id,
-                  MutableHandle<PropertyDescriptor> descriptor)
-{
-    // We only want to do interpostion on DOM instances,
-    // wrapped natives, or if the object explicitly requests it.
-    RootedObject unwrapped(cx, UncheckedUnwrap(target));
-    const js::Class* clasp = js::GetObjectClass(unwrapped);
-    bool isCPOW = jsipc::IsWrappedCPOW(unwrapped);
-
-    if (!mozilla::dom::IsDOMClass(clasp) &&
-        !IS_WN_CLASS(clasp) &&
-        !IS_PROTO_CLASS(clasp) &&
-        clasp != &OuterWindowProxyClass &&
-        !isCPOW &&
-        !RequiresInterpositions(cx, unwrapped)) {
-        return true;
-    }
-
-    XPCWrappedNativeScope* scope = ObjectScope(CurrentGlobalOrNull(cx));
-    MOZ_ASSERT(scope->HasInterposition());
-
-    nsCOMPtr<nsIAddonInterposition> interp = scope->GetInterposition();
-    InterpositionWhitelist* wl = XPCWrappedNativeScope::GetInterpositionWhitelist(interp);
-    // We do InterposeProperty only if the id is on the whitelist of the interpostion
-    // or if the target is a CPOW.
-    if ((!wl || !wl->has(JSID_BITS(id.get()))) && !isCPOW)
-        return true;
-
-    JSAddonId* addonId = AddonIdOfObject(target);
-    RootedValue addonIdValue(cx, StringValue(StringOfAddonId(addonId)));
-    RootedValue prop(cx, IdToValue(id));
-    RootedValue targetValue(cx, ObjectValue(*target));
-    RootedValue descriptorVal(cx);
-    nsresult rv = interp->InterposeProperty(addonIdValue, targetValue,
-                                            iid, prop, &descriptorVal);
-    if (NS_FAILED(rv)) {
-        xpc::Throw(cx, rv);
-        return false;
-    }
-
-    if (!descriptorVal.isObject())
-        return true;
-
-    // We need to be careful parsing descriptorVal. |cx| is in the compartment
-    // of the add-on and the descriptor is in the compartment of the
-    // interposition. We could wrap the descriptor in the add-on's compartment
-    // and then parse it. However, parsing the descriptor fetches properties
-    // from it, and we would try to interpose on those property accesses. So
-    // instead we parse in the interposition's compartment and then wrap the
-    // descriptor.
-
-    {
-        JSAutoCompartment ac(cx, &descriptorVal.toObject());
-        if (!JS::ObjectToCompletePropertyDescriptor(cx, target, descriptorVal, descriptor))
-            return false;
-    }
-
-    // Always make the property non-configurable regardless of what the
-    // interposition wants.
-    descriptor.setAttributes(descriptor.attributes() | JSPROP_PERMANENT);
-
-    if (!JS_WrapPropertyDescriptor(cx, descriptor))
-        return false;
-
-    return true;
-}
-
-bool
-InterposeCall(JSContext* cx, JS::HandleObject target, const JS::CallArgs& args, bool* done)
-{
-    *done = false;
-    XPCWrappedNativeScope* scope = ObjectScope(CurrentGlobalOrNull(cx));
-    MOZ_ASSERT(scope->HasInterposition());
-
-    nsCOMPtr<nsIAddonInterposition> interp = scope->GetInterposition();
-
-    RootedObject unwrappedTarget(cx, UncheckedUnwrap(target));
-    bool hasInterpostion = xpc::CompartmentPrivate::Get(unwrappedTarget)->addonCallInterposition;
-
-    if (!hasInterpostion)
-        return true;
-
-    // If there is a call interpostion, we don't want to propogate the
-    // call to Base:
-    *done = true; 
-
-    JSAddonId* addonId = AddonIdOfObject(target);
-    RootedValue addonIdValue(cx, StringValue(StringOfAddonId(addonId)));
-    RootedValue targetValue(cx, ObjectValue(*target));
-    RootedValue thisValue(cx, args.thisv());
-    RootedObject argsArray(cx, ConvertArgsToArray(cx, args));
-    if (!argsArray)
-        return false;
-
-    RootedValue argsVal(cx, ObjectValue(*argsArray));
-    RootedValue returnVal(cx);
-
-    nsresult rv = interp->InterposeCall(addonIdValue, targetValue,
-                                        thisValue, argsVal, args.rval());
-    if (NS_FAILED(rv)) {
-        xpc::Throw(cx, rv);
-        return false;
-    }
-
-    return true;
-}
-
-template<typename Base>
-bool AddonWrapper<Base>::call(JSContext* cx, JS::Handle<JSObject*> wrapper,
-                              const JS::CallArgs& args) const
-{
-    bool done = false;
-    if (!InterposeCall(cx, wrapper, args, &done))
-        return false;
-
-    return done || Base::call(cx, wrapper, args);
-}
-
-template<typename Base>
-bool
-AddonWrapper<Base>::getPropertyDescriptor(JSContext* cx, HandleObject wrapper,
-                                          HandleId id, MutableHandle<PropertyDescriptor> desc) const
-{
-    if (!InterposeProperty(cx, wrapper, nullptr, id, desc))
-        return false;
-
-    if (desc.object())
-        return true;
-
-    return Base::getPropertyDescriptor(cx, wrapper, id, desc);
-}
-
-template<typename Base>
-bool
-AddonWrapper<Base>::getOwnPropertyDescriptor(JSContext* cx, HandleObject wrapper,
-                                             HandleId id, MutableHandle<PropertyDescriptor> desc) const
-{
-    if (!InterposeProperty(cx, wrapper, nullptr, id, desc))
-        return false;
-
-    if (desc.object())
-        return true;
-
-    return Base::getOwnPropertyDescriptor(cx, wrapper, id, desc);
-}
-
-template<typename Base>
-bool
-AddonWrapper<Base>::get(JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<Value> receiver,
-                        JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) const
-{
-    AUTO_PROFILER_LABEL("AddonWrapper::get", OTHER);
-
-    Rooted<PropertyDescriptor> desc(cx);
-    if (!InterposeProperty(cx, wrapper, nullptr, id, &desc))
-        return false;
-
-    if (!desc.object())
-        return Base::get(cx, wrapper, receiver, id, vp);
-
-    if (desc.getter()) {
-        return Call(cx, receiver, desc.getterObject(), HandleValueArray::empty(), vp);
-    } else {
-        vp.set(desc.value());
-        return true;
-    }
-}
-
-template<typename Base>
-bool
-AddonWrapper<Base>::set(JSContext* cx, JS::HandleObject wrapper, JS::HandleId id, JS::HandleValue v,
-                        JS::HandleValue receiver, JS::ObjectOpResult& result) const
-{
-    Rooted<PropertyDescriptor> desc(cx);
-    if (!InterposeProperty(cx, wrapper, nullptr, id, &desc))
-        return false;
-
-    if (!desc.object())
-        return Base::set(cx, wrapper, id, v, receiver, result);
-
-    if (desc.setter()) {
-        MOZ_ASSERT(desc.hasSetterObject());
-        JS::AutoValueVector args(cx);
-        if (!args.append(v))
-            return false;
-        RootedValue fval(cx, ObjectValue(*desc.setterObject()));
-        RootedValue ignored(cx);
-        if (!JS::Call(cx, receiver, fval, args, &ignored))
-            return false;
-        return result.succeed();
-    }
-
-    return result.failCantSetInterposed();
-}
-
-template<typename Base>
-bool
-AddonWrapper<Base>::defineProperty(JSContext* cx, HandleObject wrapper, HandleId id,
-                                   Handle<PropertyDescriptor> desc,
-                                   ObjectOpResult& result) const
-{
-    Rooted<PropertyDescriptor> interpDesc(cx);
-    if (!InterposeProperty(cx, wrapper, nullptr, id, &interpDesc))
-        return false;
-
-    if (!interpDesc.object())
-        return Base::defineProperty(cx, wrapper, id, desc, result);
-
-    ReportASCIIErrorWithId(cx, "unable to modify interposed property %s", id);
-    return false;
-}
-
-template<typename Base>
-bool
-AddonWrapper<Base>::delete_(JSContext* cx, HandleObject wrapper, HandleId id,
-                            ObjectOpResult& result) const
-{
-    Rooted<PropertyDescriptor> desc(cx);
-    if (!InterposeProperty(cx, wrapper, nullptr, id, &desc))
-        return false;
-
-    if (!desc.object())
-        return Base::delete_(cx, wrapper, id, result);
-
-    ReportASCIIErrorWithId(cx, "unable to delete interposed property %s", id);
-    return false;
-}
-
-#define AddonWrapperCC AddonWrapper<CrossCompartmentWrapper>
-#define AddonWrapperXrayXPCWN AddonWrapper<PermissiveXrayXPCWN>
-#define AddonWrapperXrayDOM AddonWrapper<PermissiveXrayDOM>
-
-template<> const AddonWrapperCC AddonWrapperCC::singleton(0);
-template<> const AddonWrapperXrayXPCWN AddonWrapperXrayXPCWN::singleton(0);
-template<> const AddonWrapperXrayDOM AddonWrapperXrayDOM::singleton(0);
-
-template class AddonWrapperCC;
-template class AddonWrapperXrayXPCWN;
-template class AddonWrapperXrayDOM;
-
-#undef AddonWrapperCC
-#undef AddonWrapperXrayXPCWN
-#undef AddonWrapperXrayDOM
-
-} // namespace xpc
deleted file mode 100644
--- a/js/xpconnect/wrappers/AddonWrapper.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* vim: set ts=8 sts=4 et sw=4 tw=99: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef AddonWrapper_h
-#define AddonWrapper_h
-
-#include "mozilla/Attributes.h"
-
-#include "nsID.h"
-
-#include "js/Wrapper.h"
-
-namespace xpc {
-
-bool
-InterposeProperty(JSContext* cx, JS::HandleObject target, const nsIID* iid, JS::HandleId id,
-                  JS::MutableHandle<JS::PropertyDescriptor> descriptor);
-
-bool
-InterposeCall(JSContext* cx, JS::HandleObject wrapper,
-              const JS::CallArgs& args, bool& done);
-
-template<typename Base>
-class AddonWrapper : public Base {
-  public:
-    explicit constexpr AddonWrapper(unsigned flags) : Base(flags) { }
-
-    virtual bool getOwnPropertyDescriptor(JSContext* cx, JS::Handle<JSObject*> wrapper,
-                                          JS::Handle<jsid> id,
-                                          JS::MutableHandle<JS::PropertyDescriptor> desc) const override;
-    virtual bool defineProperty(JSContext* cx, JS::HandleObject proxy, JS::HandleId id,
-                                JS::Handle<JS::PropertyDescriptor> desc,
-                                JS::ObjectOpResult& result) const override;
-    virtual bool delete_(JSContext* cx, JS::HandleObject proxy, JS::HandleId id,
-                         JS::ObjectOpResult& result) const override;
-    virtual bool get(JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<JS::Value> receiver,
-                     JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) const override;
-    virtual bool set(JSContext* cx, JS::HandleObject wrapper, JS::HandleId id, JS::HandleValue v,
-                     JS::HandleValue receiver, JS::ObjectOpResult& result) const override;
-    virtual bool call(JSContext* cx, JS::Handle<JSObject*> wrapper,
-                      const JS::CallArgs& args) const override;
-
-    virtual bool getPropertyDescriptor(JSContext* cx, JS::Handle<JSObject*> wrapper,
-                                       JS::Handle<jsid> id,
-                                       JS::MutableHandle<JS::PropertyDescriptor> desc) const override;
-
-    static const AddonWrapper singleton;
-};
-
-} // namespace xpc
-
-#endif // AddonWrapper_h
--- a/js/xpconnect/wrappers/WrapperFactory.cpp
+++ b/js/xpconnect/wrappers/WrapperFactory.cpp
@@ -1,17 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* vim: set ts=8 sts=4 et sw=4 tw=99: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "WaiveXrayWrapper.h"
 #include "FilteringWrapper.h"
-#include "AddonWrapper.h"
 #include "XrayWrapper.h"
 #include "AccessCheck.h"
 #include "XPCWrapper.h"
 #include "ChromeObjectWrapper.h"
 #include "WrapperFactory.h"
 
 #include "xpcprivate.h"
 #include "XPCMaps.h"
@@ -424,41 +423,16 @@ SelectWrapper(bool securityWrapper, Xray
     // functions exposed from the XBL scope. We could remove this exception,
     // if needed, by using ExportFunction to generate the content-side
     // representations of XBL methods.
     if (xrayType == XrayForJSObject && IsInContentXBLScope(obj))
         return &FilteringWrapper<CrossCompartmentSecurityWrapper, OpaqueWithCall>::singleton;
     return &FilteringWrapper<CrossCompartmentSecurityWrapper, Opaque>::singleton;
 }
 
-static const Wrapper*
-SelectAddonWrapper(JSContext* cx, HandleObject obj, const Wrapper* wrapper)
-{
-    JSAddonId* originAddon = JS::AddonIdOfObject(obj);
-    JSAddonId* targetAddon = JS::AddonIdOfObject(JS::CurrentGlobalOrNull(cx));
-
-    MOZ_ASSERT(AccessCheck::isChrome(JS::CurrentGlobalOrNull(cx)));
-    MOZ_ASSERT(targetAddon);
-
-    if (targetAddon == originAddon)
-        return wrapper;
-
-    // Add-on interposition only supports certain wrapper types, so we check if
-    // we would have used one of the supported ones.
-    if (wrapper == &CrossCompartmentWrapper::singleton)
-        return &AddonWrapper<CrossCompartmentWrapper>::singleton;
-    else if (wrapper == &PermissiveXrayXPCWN::singleton)
-        return &AddonWrapper<PermissiveXrayXPCWN>::singleton;
-    else if (wrapper == &PermissiveXrayDOM::singleton)
-        return &AddonWrapper<PermissiveXrayDOM>::singleton;
-
-    // |wrapper| is not supported for interposition, so we don't do it.
-    return wrapper;
-}
-
 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");
@@ -553,21 +527,16 @@ WrapperFactory::Rewrap(JSContext* cx, Ha
 
         // If Xrays are warranted, the caller may waive them for non-security
         // wrappers (unless explicitly forbidden from doing so).
         bool waiveXrays = wantXrays && !securityWrapper &&
                           targetCompartmentPrivate->allowWaivers &&
                           HasWaiveXrayFlag(obj);
 
         wrapper = SelectWrapper(securityWrapper, xrayType, waiveXrays, obj);
-
-        // If we want to apply add-on interposition in the target compartment,
-        // then we try to "upgrade" the wrapper to an interposing one.
-        if (targetCompartmentPrivate->hasInterposition)
-            wrapper = SelectAddonWrapper(cx, obj, wrapper);
     }
 
     if (!targetSubsumesOrigin &&
         !originCompartmentPrivate->forcePermissiveCOWs) {
         // Do a belt-and-suspenders check against exposing eval()/Function() to
         // non-subsuming content.  But don't worry about doing it in the
         // SpecialPowers case.
         if (JSFunction* fun = JS_GetObjectFunction(obj)) {
--- a/js/xpconnect/wrappers/moz.build
+++ b/js/xpconnect/wrappers/moz.build
@@ -5,17 +5,16 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 EXPORTS += [
     'WrapperFactory.h',
 ]
 
 UNIFIED_SOURCES += [
     'AccessCheck.cpp',
-    'AddonWrapper.cpp',
     'ChromeObjectWrapper.cpp',
     'FilteringWrapper.cpp',
     'WaiveXrayWrapper.cpp',
     'WrapperFactory.cpp',
 ]
 
 # XrayWrapper needs to be built separately becaue of template instantiations.
 SOURCES += [