Bug 1480244: Part 4 - Make child message managers non-global objects. r=bz
authorKris Maglione <maglione.k@gmail.com>
Fri, 10 Aug 2018 14:03:18 -0700
changeset 431547 c7a263321e999b1806b8facd31177ca026a7a33f
parent 431546 7d6c6e052339d90767d18403826f0a316521074f
child 431548 b712d41d474554d13447594ebc0ce8b2cccd0f47
push id34443
push usercsabou@mozilla.com
push dateWed, 15 Aug 2018 00:53:32 +0000
treeherdermozilla-central@b80906e2fbc9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs1480244
milestone63.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 1480244: Part 4 - Make child message managers non-global objects. r=bz This is mostly self-explanatory. However, the patch also contains some minor changes to frame scripts which expect to be able to call message manager methods with a null target object, which stops working when they stop being global objects. MozReview-Commit-ID: HDT2RvK3F3L
browser/components/sessionstore/test/browser_send_async_message_oom.js
dom/base/ContentFrameMessageManager.cpp
dom/base/ContentFrameMessageManager.h
dom/base/ContentProcessMessageManager.cpp
dom/base/ContentProcessMessageManager.h
dom/base/InProcessTabChildMessageManager.cpp
dom/base/InProcessTabChildMessageManager.h
dom/base/MessageListenerManager.cpp
dom/base/moz.build
dom/base/nsFrameMessageManager.cpp
dom/base/nsFrameMessageManager.h
dom/chrome-webidl/MessageManager.webidl
dom/ipc/ContentChild.cpp
dom/ipc/SharedMap.cpp
dom/ipc/TabChild.cpp
dom/ipc/TabChild.h
testing/marionette/listener.js
--- a/browser/components/sessionstore/test/browser_send_async_message_oom.js
+++ b/browser/components/sessionstore/test/browser_send_async_message_oom.js
@@ -24,18 +24,18 @@ function frameScript() {
     return function(name, ...args) {
       if (name != "SessionStore:update") {
         return original(name, ...args);
       }
       throw new Components.Exception("Simulated OOM", Cr.NS_ERROR_OUT_OF_MEMORY);
     };
   };
 
-  mm.sendAsyncMessage = wrap(mm.sendAsyncMessage);
-  mm.sendSyncMessage = wrap(mm.sendSyncMessage);
+  mm.sendAsyncMessage = wrap(mm.sendAsyncMessage.bind(mm));
+  mm.sendSyncMessage = wrap(mm.sendSyncMessage.bind(mm));
 }
 
 add_task(async function() {
   // Capture original state.
   let snapshot = Services.telemetry.getHistogramById(HISTOGRAM_NAME).snapshot();
 
   // Open a browser, configure it to cause OOM.
   let newTab = BrowserTestUtils.addTab(gBrowser, "about:robots");
new file mode 100644
--- /dev/null
+++ b/dom/base/ContentFrameMessageManager.cpp
@@ -0,0 +1,25 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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 "ContentFrameMessageManager.h"
+#include "mozilla/dom/ScriptSettings.h"
+
+using namespace mozilla;
+using namespace mozilla::dom;
+
+JSObject*
+ContentFrameMessageManager::GetOrCreateWrapper()
+{
+  AutoJSAPI jsapi;
+  jsapi.Init();
+
+  JS::RootedValue val(jsapi.cx());
+  if (!GetOrCreateDOMReflectorNoWrap(jsapi.cx(), this, &val)) {
+    return nullptr;
+  }
+  MOZ_ASSERT(val.isObject());
+  return &val.toObject();
+}
--- a/dom/base/ContentFrameMessageManager.h
+++ b/dom/base/ContentFrameMessageManager.h
@@ -6,71 +6,51 @@
 
 #ifndef mozilla_dom_ContentFrameMessageManager_h
 #define mozilla_dom_ContentFrameMessageManager_h
 
 #include "mozilla/DOMEventTargetHelper.h"
 #include "mozilla/dom/MessageManagerGlobal.h"
 #include "mozilla/dom/ResolveSystemBinding.h"
 #include "nsContentUtils.h"
+#include "xpcpublic.h"
 
 namespace mozilla {
 namespace dom {
 
 /**
  * Base class for implementing the WebIDL ContentFrameMessageManager class.
  */
 class ContentFrameMessageManager : public DOMEventTargetHelper,
                                    public MessageManagerGlobal
 {
 public:
   using DOMEventTargetHelper::AddRef;
   using DOMEventTargetHelper::Release;
 
-  bool DoResolve(JSContext* aCx, JS::Handle<JSObject*> aObj,
-                 JS::Handle<jsid> aId,
-                 JS::MutableHandle<JS::PropertyDescriptor> aDesc)
-  {
-    bool found;
-    if (!SystemGlobalResolve(aCx, aObj, aId, &found)) {
-      return false;
-    }
-    if (found) {
-      FillPropertyDescriptor(aDesc, aObj, JS::UndefinedValue(), false);
-    }
-    return true;
-  }
-  static bool MayResolve(jsid aId)
-  {
-    return MayResolveAsSystemBindingName(aId);
-  }
-  void GetOwnPropertyNames(JSContext* aCx, JS::AutoIdVector& aNames,
-                           bool aEnumerableOnly, mozilla::ErrorResult& aRv)
-  {
-    JS::Rooted<JSObject*> thisObj(aCx, GetWrapper());
-    GetSystemBindingNames(aCx, thisObj, aNames, aEnumerableOnly, aRv);
-  }
-
   virtual already_AddRefed<nsPIDOMWindowOuter> GetContent(ErrorResult& aError) = 0;
   virtual already_AddRefed<nsIDocShell> GetDocShell(ErrorResult& aError) = 0;
   virtual already_AddRefed<nsIEventTarget> GetTabEventTarget() = 0;
   virtual uint64_t ChromeOuterWindowID() = 0;
 
   nsFrameMessageManager* GetMessageManager()
   {
     return mMessageManager;
   }
   void DisconnectMessageManager()
   {
     mMessageManager->Disconnect();
     mMessageManager = nullptr;
   }
 
+  JSObject* GetOrCreateWrapper();
+
 protected:
   explicit ContentFrameMessageManager(nsFrameMessageManager* aMessageManager)
-    : MessageManagerGlobal(aMessageManager)
+    : DOMEventTargetHelper(xpc::NativeGlobal(xpc::PrivilegedJunkScope()))
+    , MessageManagerGlobal(aMessageManager)
   {}
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_ContentFrameMessageManager_h
--- a/dom/base/ContentProcessMessageManager.cpp
+++ b/dom/base/ContentProcessMessageManager.cpp
@@ -6,16 +6,17 @@
 
 #include "ContentProcessMessageManager.h"
 
 #include "nsContentCID.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/dom/MessageManagerBinding.h"
 #include "mozilla/dom/ParentProcessMessageManager.h"
 #include "mozilla/dom/ResolveSystemBinding.h"
+#include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/dom/ipc/SharedMap.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 bool ContentProcessMessageManager::sWasCreated = false;
 
 ContentProcessMessageManager::ContentProcessMessageManager(nsFrameMessageManager* aMessageManager)
@@ -26,58 +27,25 @@ ContentProcessMessageManager::ContentPro
 }
 
 ContentProcessMessageManager::~ContentProcessMessageManager()
 {
   mAnonymousGlobalScopes.Clear();
   mozilla::DropJSObjects(this);
 }
 
-bool
-ContentProcessMessageManager::DoResolve(JSContext* aCx, JS::Handle<JSObject*> aObj,
-                                        JS::Handle<jsid> aId,
-                                        JS::MutableHandle<JS::PropertyDescriptor> aDesc)
-{
-    bool found;
-    if (!SystemGlobalResolve(aCx, aObj, aId, &found)) {
-      return false;
-    }
-    if (found) {
-      FillPropertyDescriptor(aDesc, aObj, JS::UndefinedValue(), false);
-    }
-    return true;
-}
-
-/* static */
-bool
-ContentProcessMessageManager::MayResolve(jsid aId)
-{
-  return MayResolveAsSystemBindingName(aId);
-}
-
-void
-ContentProcessMessageManager::GetOwnPropertyNames(JSContext* aCx, JS::AutoIdVector& aNames,
-                                                  bool aEnumerableOnly, ErrorResult& aRv)
-{
-  JS::Rooted<JSObject*> thisObj(aCx, GetWrapper());
-  GetSystemBindingNames(aCx, thisObj, aNames, aEnumerableOnly, aRv);
-}
-
 ContentProcessMessageManager*
 ContentProcessMessageManager::Get()
 {
-  nsCOMPtr<nsIGlobalObject> service = do_GetService(NS_CHILDPROCESSMESSAGEMANAGER_CONTRACTID);
+  nsCOMPtr<nsIMessageSender> service = do_GetService(NS_CHILDPROCESSMESSAGEMANAGER_CONTRACTID);
   if (!service) {
     return nullptr;
   }
-  ContentProcessMessageManager* global = static_cast<ContentProcessMessageManager*>(service.get());
-  if (global) {
-    sWasCreated = true;
-  }
-  return global;
+  sWasCreated = true;
+  return static_cast<ContentProcessMessageManager*>(service.get());
 }
 
 already_AddRefed<mozilla::dom::ipc::SharedMap>
 ContentProcessMessageManager::SharedData()
 {
   if (ContentChild* child = ContentChild::GetSingleton()) {
     return do_AddRef(child->SharedData());
   }
@@ -97,74 +65,75 @@ ContentProcessMessageManager::MarkForCC(
   MarkScopesForCC();
   MessageManagerGlobal::MarkForCC();
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(ContentProcessMessageManager)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(ContentProcessMessageManager)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMessageManager)
-  tmp->TraverseHostObjectURIs(cb);
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(ContentProcessMessageManager)
   NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
   tmp->nsMessageManagerScriptExecutor::Trace(aCallbacks, aClosure);
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ContentProcessMessageManager)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mMessageManager)
   tmp->nsMessageManagerScriptExecutor::Unlink();
-  tmp->UnlinkHostObjectURIs();
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ContentProcessMessageManager)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIMessageSender)
   NS_INTERFACE_MAP_ENTRY(nsIMessageSender)
-  NS_INTERFACE_MAP_ENTRY(nsIScriptObjectPrincipal)
-  NS_INTERFACE_MAP_ENTRY(nsIGlobalObject)
   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(ContentProcessMessageManager)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(ContentProcessMessageManager)
 
 bool
 ContentProcessMessageManager::Init()
 {
   if (mInitialized) {
     return true;
   }
   mInitialized = true;
 
-  return InitChildGlobalInternal(NS_LITERAL_CSTRING("processChildGlobal"));
+  return nsMessageManagerScriptExecutor::Init();
+}
+
+JSObject*
+ContentProcessMessageManager::WrapObject(JSContext* aCx,
+                                         JS::Handle<JSObject*> aGivenProto)
+{
+  return ContentProcessMessageManager_Binding::Wrap(aCx, this, aGivenProto);
 }
 
-bool
-ContentProcessMessageManager::WrapGlobalObject(JSContext* aCx,
-                                               JS::RealmOptions& aOptions,
-                                               JS::MutableHandle<JSObject*> aReflector)
+JSObject*
+ContentProcessMessageManager::GetOrCreateWrapper()
 {
-  bool ok = ContentProcessMessageManager_Binding::Wrap(aCx, this, this, aOptions,
-                                                       nsJSPrincipals::get(mPrincipal),
-                                                       true, aReflector);
-  if (ok) {
-    // Since we can't rewrap we have to preserve the global's wrapper here.
-    PreserveWrapper(ToSupports(this));
+  AutoJSAPI jsapi;
+  jsapi.Init();
+
+  JS::RootedValue val(jsapi.cx());
+  if (!GetOrCreateDOMReflectorNoWrap(jsapi.cx(), this, &val)) {
+    return nullptr;
   }
-  return ok;
+  return &val.toObject();
 }
 
 void
 ContentProcessMessageManager::LoadScript(const nsAString& aURL)
 {
   Init();
-  JS::Rooted<JSObject*> global(mozilla::dom::RootingCx(), GetWrapper());
-  LoadScriptInternal(global, aURL, false);
+  JS::Rooted<JSObject*> messageManager(mozilla::dom::RootingCx(), GetOrCreateWrapper());
+  LoadScriptInternal(messageManager, aURL, true);
 }
 
 void
 ContentProcessMessageManager::SetInitialProcessData(JS::HandleValue aInitialData)
 {
   mMessageManager->SetInitialProcessData(aInitialData);
 }
--- a/dom/base/ContentProcessMessageManager.h
+++ b/dom/base/ContentProcessMessageManager.h
@@ -7,25 +7,23 @@
 #ifndef mozilla_dom_ContentProcessMessageManager_h
 #define mozilla_dom_ContentProcessMessageManager_h
 
 #include "mozilla/Attributes.h"
 #include "mozilla/dom/MessageManagerGlobal.h"
 #include "nsCOMPtr.h"
 #include "nsFrameMessageManager.h"
 #include "nsIScriptContext.h"
-#include "nsIScriptObjectPrincipal.h"
 #include "nsIScriptContext.h"
 #include "nsIClassInfo.h"
 #include "nsIRunnable.h"
-#include "nsIGlobalObject.h"
-#include "nsIScriptObjectPrincipal.h"
 #include "nsServiceManagerUtils.h"
 #include "nsWeakReference.h"
 #include "nsWrapperCache.h"
+#include "xpcpublic.h"
 
 namespace mozilla {
 namespace dom {
 
 namespace ipc {
   class SharedMap;
 }
 
@@ -34,54 +32,41 @@ namespace ipc {
  * processes. Each child process has exactly one instance of this class, which
  * hosts the process's process scripts, and may exchange messages with its
  * corresponding ParentProcessMessageManager on the parent side.
  */
 
 class ContentProcessMessageManager :
   public nsIMessageSender,
   public nsMessageManagerScriptExecutor,
-  public nsIGlobalObject,
-  public nsIScriptObjectPrincipal,
   public nsSupportsWeakReference,
   public ipc::MessageManagerCallback,
   public MessageManagerGlobal,
   public nsWrapperCache
 {
 public:
   explicit ContentProcessMessageManager(nsFrameMessageManager* aMessageManager);
 
-  bool DoResolve(JSContext* aCx, JS::Handle<JSObject*> aObj,
-                 JS::Handle<jsid> aId,
-                 JS::MutableHandle<JS::PropertyDescriptor> aDesc);
-  static bool MayResolve(jsid aId);
-  void GetOwnPropertyNames(JSContext* aCx, JS::AutoIdVector& aNames,
-                           bool aEnumerableOnly, ErrorResult& aRv);
-
   using ipc::MessageManagerCallback::GetProcessMessageManager;
   using MessageManagerGlobal::GetProcessMessageManager;
 
   bool Init();
 
   static ContentProcessMessageManager* Get();
   static bool WasCreated();
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(ContentProcessMessageManager, nsIMessageSender)
 
   void MarkForCC();
 
   virtual JSObject* WrapObject(JSContext* aCx,
-                               JS::Handle<JSObject*> aGivenProto) override
-  {
-    MOZ_CRASH("We should never get here!");
-  }
-  virtual bool WrapGlobalObject(JSContext* aCx,
-                                JS::RealmOptions& aOptions,
-                                JS::MutableHandle<JSObject*> aReflector) override;
+                               JS::Handle<JSObject*> aGivenProto) override;
+
+  JSObject* GetOrCreateWrapper();
 
   using MessageManagerGlobal::AddMessageListener;
   using MessageManagerGlobal::RemoveMessageListener;
   using MessageManagerGlobal::AddWeakMessageListener;
   using MessageManagerGlobal::RemoveWeakMessageListener;
 
   // ContentProcessMessageManager
   void GetInitialProcessData(JSContext* aCx,
@@ -94,23 +79,19 @@ public:
     }
     mMessageManager->GetInitialProcessData(aCx, aInitialProcessData, aError);
   }
 
   already_AddRefed<ipc::SharedMap> SharedData();
 
   NS_FORWARD_SAFE_NSIMESSAGESENDER(mMessageManager)
 
-  virtual void LoadScript(const nsAString& aURL);
+  nsIGlobalObject* GetParentObject() const { return xpc::NativeGlobal(xpc::PrivilegedJunkScope()); }
 
-  virtual JSObject* GetGlobalJSObject() override
-  {
-    return GetWrapper();
-  }
-  virtual nsIPrincipal* GetPrincipal() override { return mPrincipal; }
+  virtual void LoadScript(const nsAString& aURL);
 
   bool IsProcessScoped() const override
   {
     return true;
   }
 
   void SetInitialProcessData(JS::HandleValue aInitialData);
 
--- a/dom/base/InProcessTabChildMessageManager.cpp
+++ b/dom/base/InProcessTabChildMessageManager.cpp
@@ -118,81 +118,51 @@ InProcessTabChildMessageManager::~InProc
 // the IDL binding doesn't know what value to return.
 void
 InProcessTabChildMessageManager::MarkForCC()
 {
   MarkScopesForCC();
   MessageManagerGlobal::MarkForCC();
 }
 
-bool
-InProcessTabChildMessageManager::Init()
-{
-  // If you change this, please change GetCompartmentName() in XPCJSContext.cpp
-  // accordingly.
-  nsAutoCString id;
-  id.AssignLiteral("inProcessTabChildGlobal");
-  nsIURI* uri = mOwner->OwnerDoc()->GetDocumentURI();
-  if (uri) {
-    nsAutoCString u;
-    nsresult rv = uri->GetSpec(u);
-    NS_ENSURE_SUCCESS(rv, false);
-    id.AppendLiteral("?ownedBy=");
-    id.Append(u);
-  }
-  return InitChildGlobalInternal(id);
-}
-
 NS_IMPL_CYCLE_COLLECTION_CLASS(InProcessTabChildMessageManager)
 
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(InProcessTabChildMessageManager,
                                                   DOMEventTargetHelper)
    NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMessageManager)
    NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocShell)
-   tmp->TraverseHostObjectURIs(cb);
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(InProcessTabChildMessageManager,
                                                DOMEventTargetHelper)
   tmp->nsMessageManagerScriptExecutor::Trace(aCallbacks, aClosure);
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(InProcessTabChildMessageManager,
                                                 DOMEventTargetHelper)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mMessageManager)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocShell)
   tmp->nsMessageManagerScriptExecutor::Unlink();
-  tmp->UnlinkHostObjectURIs();
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(InProcessTabChildMessageManager)
   NS_INTERFACE_MAP_ENTRY(nsIMessageSender)
   NS_INTERFACE_MAP_ENTRY(nsIInProcessContentFrameMessageManager)
-  NS_INTERFACE_MAP_ENTRY(nsIScriptObjectPrincipal)
-  NS_INTERFACE_MAP_ENTRY(nsIGlobalObject)
   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
 NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
 
 NS_IMPL_ADDREF_INHERITED(InProcessTabChildMessageManager, DOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(InProcessTabChildMessageManager, DOMEventTargetHelper)
 
-bool
-InProcessTabChildMessageManager::WrapGlobalObject(JSContext* aCx,
-                                                  JS::RealmOptions& aOptions,
-                                                  JS::MutableHandle<JSObject*> aReflector)
+JSObject*
+InProcessTabChildMessageManager::WrapObject(JSContext* aCx,
+                                            JS::Handle<JSObject*> aGivenProto)
 {
-  bool ok = ContentFrameMessageManager_Binding::Wrap(aCx, this, this, aOptions,
-                                                       nsJSPrincipals::get(mPrincipal),
-                                                       true, aReflector);
-  if (ok) {
-    // Since we can't rewrap we have to preserve the global's wrapper here.
-    PreserveWrapper(ToSupports(this));
-  }
-  return ok;
+  return ContentFrameMessageManager_Binding::Wrap(aCx, this, aGivenProto);
 }
 
 void
 InProcessTabChildMessageManager::CacheFrameLoader(nsFrameLoader* aFrameLoader)
 {
   mFrameLoader = aFrameLoader;
 }
 
@@ -348,18 +318,18 @@ void
 InProcessTabChildMessageManager::LoadFrameScript(const nsAString& aURL, bool aRunInGlobalScope)
 {
   if (!nsContentUtils::IsSafeToRunScript()) {
     nsContentUtils::AddScriptRunner(new nsAsyncScriptLoad(this, aURL, aRunInGlobalScope));
     return;
   }
   bool tmp = mLoadingScript;
   mLoadingScript = true;
-  JS::Rooted<JSObject*> global(mozilla::dom::RootingCx(), GetWrapper());
-  LoadScriptInternal(global, aURL, aRunInGlobalScope);
+  JS::Rooted<JSObject*> mm(mozilla::dom::RootingCx(), GetOrCreateWrapper());
+  LoadScriptInternal(mm, aURL, !aRunInGlobalScope);
   mLoadingScript = tmp;
 }
 
 already_AddRefed<nsFrameLoader>
 InProcessTabChildMessageManager::GetFrameLoader()
 {
   nsCOMPtr<nsIFrameLoaderOwner> owner = do_QueryInterface(mOwner);
   RefPtr<nsFrameLoader> fl = owner ? owner->GetFrameLoader() : nullptr;
--- a/dom/base/InProcessTabChildMessageManager.h
+++ b/dom/base/InProcessTabChildMessageManager.h
@@ -15,74 +15,62 @@
 #include "nsFrameMessageManager.h"
 #include "nsIScriptContext.h"
 #include "nsIScriptObjectPrincipal.h"
 #include "nsIScriptContext.h"
 #include "nsIClassInfo.h"
 #include "nsIDocShell.h"
 #include "nsCOMArray.h"
 #include "nsIRunnable.h"
-#include "nsIGlobalObject.h"
-#include "nsIScriptObjectPrincipal.h"
 #include "nsWeakReference.h"
 
 namespace mozilla {
 class EventChainPreVisitor;
 
 namespace dom {
 
 /**
  * This class implements a ContentFrameMessageManager for use by frame loaders
  * in the parent process. It is bound to a DocShell rather than a TabChild, and
  * does not use any IPC infrastructure for its message passing.
  */
 
 class InProcessTabChildMessageManager final : public ContentFrameMessageManager,
                                               public nsMessageManagerScriptExecutor,
                                               public nsIInProcessContentFrameMessageManager,
-                                              public nsIGlobalObject,
-                                              public nsIScriptObjectPrincipal,
                                               public nsSupportsWeakReference,
                                               public mozilla::dom::ipc::MessageManagerCallback
 {
   typedef mozilla::dom::ipc::StructuredCloneData StructuredCloneData;
 
 private:
   InProcessTabChildMessageManager(nsIDocShell* aShell, nsIContent* aOwner,
                                   nsFrameMessageManager* aChrome);
 
-  bool Init();
-
 public:
   static already_AddRefed<InProcessTabChildMessageManager> Create(nsIDocShell* aShell,
                                                                   nsIContent* aOwner,
                                                                   nsFrameMessageManager* aChrome)
   {
-    RefPtr<InProcessTabChildMessageManager> global =
+    RefPtr<InProcessTabChildMessageManager> mm =
       new InProcessTabChildMessageManager(aShell, aOwner, aChrome);
 
-    NS_ENSURE_TRUE(global->Init(), nullptr);
+    NS_ENSURE_TRUE(mm->Init(), nullptr);
 
-    return global.forget();
+    return mm.forget();
   }
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(InProcessTabChildMessageManager,
                                                          DOMEventTargetHelper)
 
   void MarkForCC();
 
   virtual JSObject* WrapObject(JSContext* aCx,
-                               JS::Handle<JSObject*> aGivenProto) override
-  {
-    MOZ_CRASH("We should never get here!");
-  }
-  virtual bool WrapGlobalObject(JSContext* aCx,
-                                JS::RealmOptions& aOptions,
-                                JS::MutableHandle<JSObject*> aReflector) override;
+                               JS::Handle<JSObject*> aGivenProto) override;
 
   virtual already_AddRefed<nsPIDOMWindowOuter>
     GetContent(ErrorResult& aError) override;
   virtual already_AddRefed<nsIDocShell>
     GetDocShell(ErrorResult& aError) override
   {
     nsCOMPtr<nsIDocShell> docShell(mDocShell);
     return docShell.forget();
@@ -109,17 +97,16 @@ public:
   virtual nsresult DoSendAsyncMessage(JSContext* aCx,
                                       const nsAString& aMessage,
                                       StructuredCloneData& aData,
                                       JS::Handle<JSObject *> aCpows,
                                       nsIPrincipal* aPrincipal) override;
 
   void GetEventTargetParent(EventChainPreVisitor& aVisitor) override;
 
-  virtual nsIPrincipal* GetPrincipal() override { return mPrincipal; }
   void LoadFrameScript(const nsAString& aURL, bool aRunInGlobalScope);
   void FireUnloadEvent();
   void DisconnectEventListeners();
   void Disconnect();
   void SendMessageToParent(const nsString& aMessage, bool aSync,
                            const nsString& aJSON,
                            nsTArray<nsString>* aJSONRetVal);
   nsFrameMessageManager* GetInnerManager()
@@ -132,21 +119,16 @@ public:
   {
     return mChromeMessageManager;
   }
   void SetChromeMessageManager(nsFrameMessageManager* aParent)
   {
     mChromeMessageManager = aParent;
   }
 
-  virtual JSObject* GetGlobalJSObject() override
-  {
-    return GetWrapper();
-  }
-
   already_AddRefed<nsFrameLoader> GetFrameLoader();
 
 protected:
   virtual ~InProcessTabChildMessageManager();
 
   nsCOMPtr<nsIDocShell> mDocShell;
   bool mLoadingScript;
 
--- a/dom/base/MessageListenerManager.cpp
+++ b/dom/base/MessageListenerManager.cpp
@@ -1,15 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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 "mozilla/dom/MessageListenerManager.h"
+#include "mozilla/dom/MessageBroadcaster.h"
 
 namespace mozilla {
 namespace dom {
 
 MessageListenerManager::MessageListenerManager(ipc::MessageManagerCallback* aCallback,
                                                MessageBroadcaster* aParentManager,
                                                ipc::MessageManagerFlags aFlags)
   : nsFrameMessageManager(aCallback, aFlags),
--- a/dom/base/moz.build
+++ b/dom/base/moz.build
@@ -244,16 +244,17 @@ UNIFIED_SOURCES += [
     'BorrowedAttrInfo.cpp',
     'CharacterData.cpp',
     'ChildIterator.cpp',
     'ChromeMessageBroadcaster.cpp',
     'ChromeMessageSender.cpp',
     'ChromeNodeList.cpp',
     'ChromeUtils.cpp',
     'Comment.cpp',
+    'ContentFrameMessageManager.cpp',
     'ContentProcessMessageManager.cpp',
     'Crypto.cpp',
     'CustomElementRegistry.cpp',
     'DirectionalityUtils.cpp',
     'DispatcherTrait.cpp',
     'DocGroup.cpp',
     'DocumentFragment.cpp',
     'DocumentOrShadowRoot.cpp',
--- a/dom/base/nsFrameMessageManager.cpp
+++ b/dom/base/nsFrameMessageManager.cpp
@@ -1230,17 +1230,17 @@ NS_NewGlobalMessageManager(nsISupports**
   return NS_OK;
 }
 
 nsDataHashtable<nsStringHashKey, nsMessageManagerScriptHolder*>*
   nsMessageManagerScriptExecutor::sCachedScripts = nullptr;
 StaticRefPtr<nsScriptCacheCleaner> nsMessageManagerScriptExecutor::sScriptCacheCleaner;
 
 void
-nsMessageManagerScriptExecutor::DidCreateGlobal()
+nsMessageManagerScriptExecutor::DidCreateScriptLoader()
 {
   if (!sCachedScripts) {
     sCachedScripts =
       new nsDataHashtable<nsStringHashKey, nsMessageManagerScriptHolder*>;
     sScriptCacheCleaner = new nsScriptCacheCleaner();
   }
 }
 
@@ -1266,64 +1266,65 @@ nsMessageManagerScriptExecutor::Shutdown
 
     delete sCachedScripts;
     sCachedScripts = nullptr;
     sScriptCacheCleaner = nullptr;
   }
 }
 
 void
-nsMessageManagerScriptExecutor::LoadScriptInternal(JS::Handle<JSObject*> aGlobal,
+nsMessageManagerScriptExecutor::LoadScriptInternal(JS::Handle<JSObject*> aMessageManager,
                                                    const nsAString& aURL,
-                                                   bool aRunInGlobalScope)
+                                                   bool aRunInUniqueScope)
 {
   AUTO_PROFILER_LABEL_DYNAMIC_LOSSY_NSSTRING(
     "nsMessageManagerScriptExecutor::LoadScriptInternal", OTHER, aURL);
 
   if (!sCachedScripts) {
     return;
   }
 
   JS::RootingContext* rcx = RootingCx();
   JS::Rooted<JSScript*> script(rcx);
 
   nsMessageManagerScriptHolder* holder = sCachedScripts->Get(aURL);
-  if (holder && holder->WillRunInGlobalScope() == aRunInGlobalScope) {
+  if (holder) {
     script = holder->mScript;
   } else {
-    // Don't put anything in the cache if we already have an entry
-    // with a different WillRunInGlobalScope() value.
-    bool shouldCache = !holder;
-    TryCacheLoadAndCompileScript(aURL, aRunInGlobalScope,
-                                 shouldCache, aGlobal, &script);
+    TryCacheLoadAndCompileScript(aURL, aRunInUniqueScope, true,
+                                 aMessageManager, &script);
   }
 
-  AutoEntryScript aes(aGlobal, "message manager script load");
+  AutoEntryScript aes(aMessageManager, "message manager script load");
   JSContext* cx = aes.cx();
   if (script) {
-    if (aRunInGlobalScope) {
-      JS::RootedValue rval(cx);
-      JS::CloneAndExecuteScript(cx, script, &rval);
-    } else {
+    if (aRunInUniqueScope) {
       JS::Rooted<JSObject*> scope(cx);
-      bool ok = js::ExecuteInFrameScriptEnvironment(cx, aGlobal, script, &scope);
+      bool ok = js::ExecuteInFrameScriptEnvironment(cx, aMessageManager, script, &scope);
       if (ok) {
         // Force the scope to stay alive.
         mAnonymousGlobalScopes.AppendElement(scope);
       }
+    } else {
+      JS::RootedValue rval(cx);
+      JS::AutoObjectVector envChain(cx);
+      if (!envChain.append(aMessageManager)) {
+        return;
+      }
+      JS::CloneAndExecuteScript(cx, envChain, script, &rval);
     }
   }
 }
 
 void
 nsMessageManagerScriptExecutor::TryCacheLoadAndCompileScript(
   const nsAString& aURL,
-  bool aRunInGlobalScope,
+  bool aRunInUniqueScope,
   bool aShouldCache,
-  JS::Handle<JSObject*> aGlobal,
+  JS::Handle<JSObject*> aMessageManager,
   JS::MutableHandle<JSScript*> aScriptp)
 {
   nsCString url = NS_ConvertUTF16toUTF8(aURL);
   nsCOMPtr<nsIURI> uri;
   nsresult rv = NS_NewURI(getter_AddRefs(uri), url);
   if (NS_FAILED(rv)) {
     return;
   }
@@ -1342,17 +1343,17 @@ nsMessageManagerScriptExecutor::TryCache
   // scripts can be compiled directly for the target global, and will be dropped
   // from the preloader cache after they're executed and serialized.
   bool isRunOnce = !aShouldCache || IsProcessScoped();
 
   // If the script will be reused in this session, compile it in the compilation
   // scope instead of the current global to avoid keeping the current
   // compartment alive.
   AutoJSAPI jsapi;
-  if (!jsapi.Init(isRunOnce ? aGlobal : xpc::CompilationScope())) {
+  if (!jsapi.Init(isRunOnce ? aMessageManager : xpc::CompilationScope())) {
     return;
   }
   JSContext* cx = jsapi.cx();
   JS::Rooted<JSScript*> script(cx);
 
   script = ScriptPreloader::GetChildSingleton().GetCachedScript(cx, url);
 
   if (!script) {
@@ -1392,22 +1393,17 @@ nsMessageManagerScriptExecutor::TryCache
     if (!dataStringBuf || dataStringLength == 0) {
       return;
     }
 
     JS::CompileOptions options(cx);
     options.setFileAndLine(url.get(), 1);
     options.setNoScriptRval(true);
 
-    if (aRunInGlobalScope) {
-      if (!JS::Compile(cx, options, srcBuf, &script)) {
-        return;
-      }
-    // We're going to run these against some non-global scope.
-    } else if (!JS::CompileForNonSyntacticScope(cx, options, srcBuf, &script)) {
+    if (!JS::CompileForNonSyntacticScope(cx, options, srcBuf, &script)) {
       return;
     }
   }
 
   MOZ_ASSERT(script);
   aScriptp.set(script);
 
   nsAutoCString scheme;
@@ -1415,17 +1411,17 @@ nsMessageManagerScriptExecutor::TryCache
   // We don't cache data: scripts!
   if (aShouldCache && !scheme.EqualsLiteral("data")) {
     ScriptPreloader::GetChildSingleton().NoteScript(url, url, script, isRunOnce);
 
     // If this script will only run once per process, only cache it in the
     // preloader cache, not the session cache.
     if (!isRunOnce) {
       // Root the object also for caching.
-      auto* holder = new nsMessageManagerScriptHolder(cx, script, aRunInGlobalScope);
+      auto* holder = new nsMessageManagerScriptHolder(cx, script);
       sCachedScripts->Put(aURL, holder);
     }
   }
 }
 
 void
 nsMessageManagerScriptExecutor::Trace(const TraceCallbacks& aCallbacks, void* aClosure)
 {
@@ -1436,41 +1432,19 @@ nsMessageManagerScriptExecutor::Trace(co
 
 void
 nsMessageManagerScriptExecutor::Unlink()
 {
   ImplCycleCollectionUnlink(mAnonymousGlobalScopes);
 }
 
 bool
-nsMessageManagerScriptExecutor::InitChildGlobalInternal(const nsACString& aID)
+nsMessageManagerScriptExecutor::Init()
 {
-  AutoSafeJSContext cx;
-  if (!SystemBindingInitIds(cx)) {
-    return false;
-  }
-
-  nsContentUtils::GetSecurityManager()->GetSystemPrincipal(getter_AddRefs(mPrincipal));
-
-  JS::RealmOptions options;
-  options.creationOptions().setNewCompartmentInSystemZone();
-
-  xpc::InitGlobalObjectOptions(options, mPrincipal);
-  JS::Rooted<JSObject*> global(cx);
-  if (!WrapGlobalObject(cx, options, &global)) {
-    return false;
-  }
-
-  xpc::InitGlobalObject(cx, global, 0);
-
-  // Set the location information for the new global, so that tools like
-  // about:memory may use that information.
-  xpc::SetLocationForGlobal(global, aID);
-
-  DidCreateGlobal();
+  DidCreateScriptLoader();
   return true;
 }
 
 void
 nsMessageManagerScriptExecutor::MarkScopesForCC()
 {
   for (uint32_t i = 0; i < mAnonymousGlobalScopes.Length(); ++i) {
     mAnonymousGlobalScopes[i].exposeToActiveJS();
--- a/dom/base/nsFrameMessageManager.h
+++ b/dom/base/nsFrameMessageManager.h
@@ -402,54 +402,47 @@ private:
 #endif
 };
 
 class nsScriptCacheCleaner;
 
 struct nsMessageManagerScriptHolder
 {
   nsMessageManagerScriptHolder(JSContext* aCx,
-                               JSScript* aScript,
-                               bool aRunInGlobalScope)
-   : mScript(aCx, aScript), mRunInGlobalScope(aRunInGlobalScope)
+                               JSScript* aScript)
+   : mScript(aCx, aScript)
   { MOZ_COUNT_CTOR(nsMessageManagerScriptHolder); }
 
   ~nsMessageManagerScriptHolder()
   { MOZ_COUNT_DTOR(nsMessageManagerScriptHolder); }
 
-  bool WillRunInGlobalScope() { return mRunInGlobalScope; }
-
   JS::PersistentRooted<JSScript*> mScript;
-  bool mRunInGlobalScope;
 };
 
 class nsMessageManagerScriptExecutor
 {
 public:
   static void PurgeCache();
   static void Shutdown();
 
   void MarkScopesForCC();
 protected:
   friend class nsMessageManagerScriptCx;
   nsMessageManagerScriptExecutor() { MOZ_COUNT_CTOR(nsMessageManagerScriptExecutor); }
   ~nsMessageManagerScriptExecutor() { MOZ_COUNT_DTOR(nsMessageManagerScriptExecutor); }
 
-  void DidCreateGlobal();
-  void LoadScriptInternal(JS::Handle<JSObject*> aGlobal, const nsAString& aURL,
-                          bool aRunInGlobalScope);
+  void DidCreateScriptLoader();
+  void LoadScriptInternal(JS::Handle<JSObject*> aMessageManager, const nsAString& aURL,
+                          bool aRunInUniqueScope);
   void TryCacheLoadAndCompileScript(const nsAString& aURL,
-                                    bool aRunInGlobalScope,
+                                    bool aRunInUniqueScope,
                                     bool aShouldCache,
-                                    JS::Handle<JSObject*> aGlobal,
+                                    JS::Handle<JSObject*> aMessageManager,
                                     JS::MutableHandle<JSScript*> aScriptp);
-  bool InitChildGlobalInternal(const nsACString& aID);
-  virtual bool WrapGlobalObject(JSContext* aCx,
-                                JS::RealmOptions& aOptions,
-                                JS::MutableHandle<JSObject*> aReflector) = 0;
+  bool Init();
   void Trace(const TraceCallbacks& aCallbacks, void* aClosure);
   void Unlink();
   nsCOMPtr<nsIPrincipal> mPrincipal;
   AutoTArray<JS::Heap<JSObject*>, 2> mAnonymousGlobalScopes;
 
   // Returns true if this is a process message manager. There should only be a
   // single process message manager per session, so instances of this type will
   // optimize their script loading to avoid unnecessary duplication.
--- a/dom/chrome-webidl/MessageManager.webidl
+++ b/dom/chrome-webidl/MessageManager.webidl
@@ -456,17 +456,17 @@ interface GlobalProcessScriptLoader : Pr
    * unique enough that other Gecko consumers won't accidentally choose it.
    */
   [Throws]
   readonly attribute any initialProcessData;
 
   readonly attribute MozWritableSharedMap sharedData;
 };
 
-[ChromeOnly, Global, NeedResolve]
+[ChromeOnly]
 interface ContentFrameMessageManager : EventTarget
 {
   /**
    * The current top level window in the frame or null.
    */
   [Throws]
   readonly attribute WindowProxy? content;
 
@@ -490,17 +490,17 @@ interface ContentFrameMessageManager : E
   readonly attribute long long chromeOuterWindowID;
 
 };
 // MessageManagerGlobal inherits from SyncMessageSender, which is a real interface, not a
 // mixin. This will need to change when we implement mixins according to the current
 // WebIDL spec.
 ContentFrameMessageManager implements MessageManagerGlobal;
 
-[ChromeOnly, Global, NeedResolve]
+[ChromeOnly]
 interface ContentProcessMessageManager
 {
   /**
    * Read out a copy of the object that was initialized in the parent
    * process via ProcessScriptLoader.initialProcessData.
    */
   [Throws]
   readonly attribute any initialProcessData;
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -2607,18 +2607,18 @@ ContentChild::RecvUpdateSharedData(const
     blobImpls.AppendElement(IPCBlobUtils::Deserialize(ipcBlob));
   }
 
   if (mSharedData) {
     mSharedData->Update(aMapFile, aMapSize,
                         std::move(blobImpls),
                         std::move(aChangedKeys));
   } else {
-    mSharedData = new SharedMap(ContentProcessMessageManager::Get(), aMapFile,
-                                aMapSize, std::move(blobImpls));
+    mSharedData = new SharedMap(ContentProcessMessageManager::Get()->GetParentObject(),
+                                aMapFile, aMapSize, std::move(blobImpls));
   }
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 ContentChild::RecvGeolocationUpdate(nsIDOMGeoPosition* aPosition)
 {
--- a/dom/ipc/SharedMap.cpp
+++ b/dom/ipc/SharedMap.cpp
@@ -280,17 +280,17 @@ WritableSharedMap::WritableSharedMap()
   MOZ_RELEASE_ASSERT(mMap.initialized());
 }
 
 SharedMap*
 WritableSharedMap::GetReadOnly()
 {
   if (!mReadOnly) {
     nsTArray<RefPtr<BlobImpl>> blobs(mBlobImpls);
-    mReadOnly = new SharedMap(ContentProcessMessageManager::Get(),
+    mReadOnly = new SharedMap(ContentProcessMessageManager::Get()->GetParentObject(),
                               CloneMapFile(), MapSize(), std::move(blobs));
   }
   return mReadOnly;
 }
 
 Result<Ok, nsresult>
 WritableSharedMap::Serialize()
 {
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -158,35 +158,35 @@ static const char BEFORE_FIRST_PAINT[] =
 
 nsTHashtable<nsPtrHashKey<TabChild>>* TabChild::sVisibleTabs;
 
 typedef nsDataHashtable<nsUint64HashKey, TabChild*> TabChildMap;
 static TabChildMap* sTabChildren;
 StaticMutex sTabChildrenMutex;
 
 TabChildBase::TabChildBase()
-  : mTabChildGlobal(nullptr)
+  : mTabChildMessageManager(nullptr)
 {
 }
 
 TabChildBase::~TabChildBase()
 {
   mAnonymousGlobalScopes.Clear();
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(TabChildBase)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(TabChildBase)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK(mTabChildGlobal)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK(mTabChildMessageManager)
   tmp->nsMessageManagerScriptExecutor::Unlink();
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mWebBrowserChrome)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(TabChildBase)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTabChildGlobal)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTabChildMessageManager)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWebBrowserChrome)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(TabChildBase)
   tmp->nsMessageManagerScriptExecutor::Trace(aCallbacks, aClosure);
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TabChildBase)
@@ -228,21 +228,20 @@ TabChildBase::DispatchMessageManagerMess
         ErrorResult rv;
         data.Write(cx, json, rv);
         if (NS_WARN_IF(rv.Failed())) {
             rv.SuppressException();
             return;
         }
     }
 
-    JS::Rooted<JSObject*> kungFuDeathGrip(cx, mTabChildGlobal->GetWrapper());
     // Let the BrowserElementScrolling helper (if it exists) for this
     // content manipulate the frame state.
-    RefPtr<nsFrameMessageManager> mm = mTabChildGlobal->GetMessageManager();
-    mm->ReceiveMessage(static_cast<EventTarget*>(mTabChildGlobal), nullptr,
+    RefPtr<nsFrameMessageManager> mm = mTabChildMessageManager->GetMessageManager();
+    mm->ReceiveMessage(static_cast<EventTarget*>(mTabChildMessageManager), nullptr,
                        aMessageName, false, &data, nullptr, nullptr, nullptr,
                        IgnoreErrors());
 }
 
 bool
 TabChildBase::UpdateFrameHandler(const FrameMetrics& aFrameMetrics)
 {
   MOZ_ASSERT(aFrameMetrics.GetScrollId() != FrameMetrics::NULL_SCROLL_ID);
@@ -264,17 +263,17 @@ TabChildBase::UpdateFrameHandler(const F
     return true;
   }
   return true;
 }
 
 void
 TabChildBase::ProcessUpdateFrame(const FrameMetrics& aFrameMetrics)
 {
-    if (!mTabChildGlobal) {
+    if (!mTabChildMessageManager) {
         return;
     }
 
     FrameMetrics newMetrics = aFrameMetrics;
     APZCCallbackHelper::UpdateRootFrame(newMetrics);
 }
 
 NS_IMETHODIMP
@@ -1093,25 +1092,25 @@ TabChild::DestroyWindow()
 
 void
 TabChild::ActorDestroy(ActorDestroyReason why)
 {
   mIPCOpen = false;
 
   DestroyWindow();
 
-  if (mTabChildGlobal) {
+  if (mTabChildMessageManager) {
     // We should have a message manager if the global is alive, but it
     // seems sometimes we don't.  Assert in aurora/nightly, but don't
     // crash in release builds.
-    MOZ_DIAGNOSTIC_ASSERT(mTabChildGlobal->GetMessageManager());
-    if (mTabChildGlobal->GetMessageManager()) {
+    MOZ_DIAGNOSTIC_ASSERT(mTabChildMessageManager->GetMessageManager());
+    if (mTabChildMessageManager->GetMessageManager()) {
       // The messageManager relays messages via the TabChild which
       // no longer exists.
-      mTabChildGlobal->DisconnectMessageManager();
+      mTabChildMessageManager->DisconnectMessageManager();
     }
   }
 
   CompositorBridgeChild* compositorChild = CompositorBridgeChild::Get();
   if (compositorChild) {
     compositorChild->CancelNotifyAfterRemotePaint(this);
   }
 
@@ -1141,17 +1140,17 @@ TabChild::~TabChild()
 }
 
 mozilla::ipc::IPCResult
 TabChild::RecvLoadURL(const nsCString& aURI,
                       const ShowInfo& aInfo)
 {
   if (!mDidLoadURLInit) {
     mDidLoadURLInit = true;
-    if (!InitTabChildGlobal()) {
+    if (!InitTabChildMessageManager()) {
       return IPC_FAIL_NO_REASON(this);
     }
 
     ApplyShowInfo(aInfo);
   }
 
   nsresult rv =
     WebNavigation()->LoadURI(NS_ConvertUTF8toUTF16(aURI).get(),
@@ -1246,17 +1245,17 @@ TabChild::RecvShow(const ScreenIntSize& 
   if (!mDidFakeShow) {
     nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(WebNavigation());
     if (!baseWindow) {
         NS_ERROR("WebNavigation() doesn't QI to nsIBaseWindow");
         return IPC_FAIL_NO_REASON(this);
     }
 
     baseWindow->SetVisibility(true);
-    res = InitTabChildGlobal();
+    res = InitTabChildMessageManager();
   }
 
   ApplyShowInfo(aInfo);
   RecvParentActivated(aParentIsActive);
 
   if (!res) {
     return IPC_FAIL_NO_REASON(this);
   }
@@ -1354,20 +1353,20 @@ TabChild::RecvSuppressDisplayport(const 
 }
 
 void
 TabChild::HandleDoubleTap(const CSSPoint& aPoint, const Modifiers& aModifiers,
                           const ScrollableLayerGuid& aGuid)
 {
   TABC_LOG("Handling double tap at %s with %p %p\n",
     Stringify(aPoint).c_str(),
-    mTabChildGlobal ? mTabChildGlobal->GetWrapper() : nullptr,
-    mTabChildGlobal.get());
-
-  if (!mTabChildGlobal || !mTabChildGlobal->GetWrapper()) {
+    mTabChildMessageManager ? mTabChildMessageManager->GetWrapper() : nullptr,
+    mTabChildMessageManager.get());
+
+  if (!mTabChildMessageManager) {
     return;
   }
 
   // Note: there is nothing to do with the modifiers here, as we are not
   // synthesizing any sort of mouse event.
   nsCOMPtr<nsIDocument> document = GetDocument();
   CSSRect zoomToRect = CalculateRectToZoomTo(document, aPoint);
   // The double-tap can be dispatched by any scroll frame (so |aGuid| could be
@@ -1398,36 +1397,36 @@ TabChild::RecvHandleTap(const GeckoConte
   if (!presShell->GetPresContext()) {
     return IPC_OK();
   }
   CSSToLayoutDeviceScale scale(presShell->GetPresContext()->CSSToDevPixelScale());
   CSSPoint point = APZCCallbackHelper::ApplyCallbackTransform(aPoint / scale, aGuid);
 
   switch (aType) {
   case GeckoContentController::TapType::eSingleTap:
-    if (mTabChildGlobal) {
+    if (mTabChildMessageManager) {
       mAPZEventState->ProcessSingleTap(point, scale, aModifiers, aGuid, 1);
     }
     break;
   case GeckoContentController::TapType::eDoubleTap:
     HandleDoubleTap(point, aModifiers, aGuid);
     break;
   case GeckoContentController::TapType::eSecondTap:
-    if (mTabChildGlobal) {
+    if (mTabChildMessageManager) {
       mAPZEventState->ProcessSingleTap(point, scale, aModifiers, aGuid, 2);
     }
     break;
   case GeckoContentController::TapType::eLongTap:
-    if (mTabChildGlobal) {
+    if (mTabChildMessageManager) {
       mAPZEventState->ProcessLongTap(presShell, point, scale, aModifiers, aGuid,
           aInputBlockId);
     }
     break;
   case GeckoContentController::TapType::eLongTapUp:
-    if (mTabChildGlobal) {
+    if (mTabChildMessageManager) {
       mAPZEventState->ProcessLongTapUp(presShell, point, scale, aModifiers);
     }
     break;
   }
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
@@ -2306,64 +2305,64 @@ LoadScriptInMiddleman(const nsString& aU
          // This script is needed to respond to session store requests from the
          // UI process.
       || aURL.EqualsLiteral("chrome://browser/content/content-sessionStore.js");
 }
 
 mozilla::ipc::IPCResult
 TabChild::RecvLoadRemoteScript(const nsString& aURL, const bool& aRunInGlobalScope)
 {
-  if (!InitTabChildGlobal())
+  if (!InitTabChildMessageManager())
     // This can happen if we're half-destroyed.  It's not a fatal
     // error.
     return IPC_OK();
 
-  JS::Rooted<JSObject*> global(RootingCx(), mTabChildGlobal->GetWrapper());
-  if (!global) {
+  JS::Rooted<JSObject*> mm(RootingCx(), mTabChildMessageManager->GetOrCreateWrapper());
+  if (!mm) {
     // This can happen if we're half-destroyed.  It's not a fatal error.
     return IPC_OK();
   }
 
   // Make sure we only load whitelisted scripts in middleman processes.
   if (recordreplay::IsMiddleman() && !LoadScriptInMiddleman(aURL)) {
     return IPC_OK();
   }
 
-  LoadScriptInternal(global, aURL, aRunInGlobalScope);
+  LoadScriptInternal(mm, aURL, !aRunInGlobalScope);
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 TabChild::RecvAsyncMessage(const nsString& aMessage,
                            InfallibleTArray<CpowEntry>&& aCpows,
                            const IPC::Principal& aPrincipal,
                            const ClonedMessageData& aData)
 {
   AUTO_PROFILER_LABEL_DYNAMIC_LOSSY_NSSTRING(
     "TabChild::RecvAsyncMessage", OTHER, aMessage);
 
   CrossProcessCpowHolder cpows(Manager(), aCpows);
-  if (!mTabChildGlobal) {
+  if (!mTabChildMessageManager) {
     return IPC_OK();
   }
 
-  RefPtr<nsFrameMessageManager> mm = mTabChildGlobal->GetMessageManager();
+  RefPtr<nsFrameMessageManager> mm = mTabChildMessageManager->GetMessageManager();
 
   // We should have a message manager if the global is alive, but it
   // seems sometimes we don't.  Assert in aurora/nightly, but don't
   // crash in release builds.
   MOZ_DIAGNOSTIC_ASSERT(mm);
   if (!mm) {
     return IPC_OK();
   }
 
-  JS::Rooted<JSObject*> kungFuDeathGrip(dom::RootingCx(), mTabChildGlobal->GetWrapper());
+  JS::Rooted<JSObject*> kungFuDeathGrip(dom::RootingCx(), mTabChildMessageManager->GetWrapper());
   StructuredCloneData data;
   UnpackClonedMessageDataForChild(aData, data);
-  mm->ReceiveMessage(static_cast<EventTarget*>(mTabChildGlobal), nullptr,
+  mm->ReceiveMessage(static_cast<EventTarget*>(mTabChildMessageManager), nullptr,
                      aMessage, false, &data, &cpows, aPrincipal, nullptr,
                      IgnoreErrors());
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 TabChild::RecvSwappedWithOtherRemoteLoader(const IPCTabContext& aContext)
 {
@@ -2521,21 +2520,21 @@ TabChild::RecvDestroy()
       nsContentPermissionUtils::GetContentPermissionRequestChildById(GetTabId());
 
   // Need to close undeleted ContentPermissionRequestChilds before tab is closed.
   for (auto& permissionRequestChild : childArray) {
       auto child = static_cast<RemotePermissionRequest*>(permissionRequestChild);
       child->Destroy();
   }
 
-  if (mTabChildGlobal) {
+  if (mTabChildMessageManager) {
     // Message handlers are called from the event loop, so it better be safe to
     // run script.
     MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
-    mTabChildGlobal->DispatchTrustedEvent(NS_LITERAL_STRING("unload"));
+    mTabChildMessageManager->DispatchTrustedEvent(NS_LITERAL_STRING("unload"));
   }
 
   nsCOMPtr<nsIObserverService> observerService =
     mozilla::services::GetObserverService();
 
   observerService->RemoveObserver(this, BEFORE_FIRST_PAINT);
 
   // XXX what other code in ~TabChild() should we be running here?
@@ -2758,35 +2757,31 @@ TabChild::AllocPRenderFrameChild()
 bool
 TabChild::DeallocPRenderFrameChild(PRenderFrameChild* aFrame)
 {
     delete aFrame;
     return true;
 }
 
 bool
-TabChild::InitTabChildGlobal()
+TabChild::InitTabChildMessageManager()
 {
-  if (!mTabChildGlobal) {
+  if (!mTabChildMessageManager) {
     nsCOMPtr<nsPIDOMWindowOuter> window = do_GetInterface(WebNavigation());
     NS_ENSURE_TRUE(window, false);
     nsCOMPtr<EventTarget> chromeHandler = window->GetChromeEventHandler();
     NS_ENSURE_TRUE(chromeHandler, false);
 
-    RefPtr<TabChildMessageManager> scope = mTabChildGlobal = new TabChildMessageManager(this);
-
-    NS_NAMED_LITERAL_CSTRING(globalId, "outOfProcessTabChildGlobal");
-    if (NS_WARN_IF(!InitChildGlobalInternal(globalId))) {
-        mTabChildGlobal = nullptr;
-        return false;
-    }
+    RefPtr<TabChildMessageManager> scope = mTabChildMessageManager = new TabChildMessageManager(this);
+
+    MOZ_ALWAYS_TRUE(nsMessageManagerScriptExecutor::Init());
 
     nsCOMPtr<nsPIWindowRoot> root = do_QueryInterface(chromeHandler);
     if (NS_WARN_IF(!root)) {
-        mTabChildGlobal = nullptr;
+        mTabChildMessageManager = nullptr;
         return false;
     }
     root->SetParentTarget(scope);
   }
 
   if (!mTriedBrowserInit) {
     mTriedBrowserInit = true;
     // Initialize the child side of the browser element machinery,
@@ -3005,17 +3000,17 @@ bool
 TabChild::IsVisible()
 {
   return mPuppetWidget && mPuppetWidget->IsVisible();
 }
 
 NS_IMETHODIMP
 TabChild::GetMessageManager(ContentFrameMessageManager** aResult)
 {
-  RefPtr<ContentFrameMessageManager> mm(mTabChildGlobal);
+  RefPtr<ContentFrameMessageManager> mm(mTabChildMessageManager);
   mm.forget(aResult);
   return *aResult ? NS_OK : NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 TabChild::GetWebBrowserChrome(nsIWebBrowserChrome3** aWebBrowserChrome)
 {
   NS_IF_ADDREF(*aWebBrowserChrome = mWebBrowserChrome);
@@ -3549,49 +3544,37 @@ TabChildMessageManager::~TabChildMessage
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(TabChildMessageManager)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(TabChildMessageManager,
                                                 DOMEventTargetHelper)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mMessageManager);
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mTabChild);
-  tmp->UnlinkHostObjectURIs();
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(TabChildMessageManager,
                                                   DOMEventTargetHelper)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMessageManager)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTabChild)
-  tmp->TraverseHostObjectURIs(cb);
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TabChildMessageManager)
   NS_INTERFACE_MAP_ENTRY(nsIMessageSender)
-  NS_INTERFACE_MAP_ENTRY(nsIScriptObjectPrincipal)
-  NS_INTERFACE_MAP_ENTRY(nsIGlobalObject)
   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
 NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
 
 NS_IMPL_ADDREF_INHERITED(TabChildMessageManager, DOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(TabChildMessageManager, DOMEventTargetHelper)
 
-bool
-TabChildMessageManager::WrapGlobalObject(JSContext* aCx,
-                                         JS::RealmOptions& aOptions,
-                                         JS::MutableHandle<JSObject*> aReflector)
+JSObject*
+TabChildMessageManager::WrapObject(JSContext* aCx,
+                                   JS::Handle<JSObject*> aGivenProto)
 {
-  bool ok = ContentFrameMessageManager_Binding::Wrap(aCx, this, this, aOptions,
-                                                     nsJSPrincipals::get(mTabChild->GetPrincipal()),
-                                                     true, aReflector);
-  if (ok) {
-    // Since we can't rewrap we have to preserve the global's wrapper here.
-    PreserveWrapper(ToSupports(this));
-  }
-  return ok;
+  return ContentFrameMessageManager_Binding::Wrap(aCx, this, aGivenProto);
 }
 
 void
 TabChildMessageManager::MarkForCC()
 {
   if (mTabChild) {
     mTabChild->MarkScopesForCC();
   }
@@ -3636,31 +3619,16 @@ uint64_t
 TabChildMessageManager::ChromeOuterWindowID()
 {
   if (!mTabChild) {
     return 0;
   }
   return mTabChild->ChromeOuterWindowID();
 }
 
-nsIPrincipal*
-TabChildMessageManager::GetPrincipal()
-{
-  if (!mTabChild)
-    return nullptr;
-  return mTabChild->GetPrincipal();
-}
-
-JSObject*
-TabChildMessageManager::GetGlobalJSObject()
-{
-  NS_ENSURE_TRUE(mTabChild, nullptr);
-  return GetWrapper();
-}
-
 nsresult
 TabChildMessageManager::Dispatch(TaskCategory aCategory,
                          already_AddRefed<nsIRunnable>&& aRunnable)
 {
   if (mTabChild && mTabChild->TabGroup()) {
     return mTabChild->TabGroup()->Dispatch(aCategory, std::move(aRunnable));
   }
   return DispatcherTrait::Dispatch(aCategory, std::move(aRunnable));
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -18,17 +18,16 @@
 #include "nsIDOMEventListener.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIWindowProvider.h"
 #include "nsIDOMWindow.h"
 #include "nsIDocShell.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsFrameMessageManager.h"
 #include "nsIPresShell.h"
-#include "nsIScriptObjectPrincipal.h"
 #include "nsWeakReference.h"
 #include "nsITabChild.h"
 #include "nsITooltipListener.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/dom/TabContext.h"
 #include "mozilla/dom/CoalescedMouseData.h"
 #include "mozilla/dom/CoalescedWheelData.h"
 #include "mozilla/DOMEventTargetHelper.h"
@@ -77,53 +76,43 @@ namespace dom {
 class TabChild;
 class TabGroup;
 class ClonedMessageData;
 class CoalescedMouseData;
 class CoalescedWheelData;
 
 class TabChildMessageManager : public ContentFrameMessageManager,
                                public nsIMessageSender,
-                               public nsIScriptObjectPrincipal,
-                               public nsIGlobalObject,
+                               public DispatcherTrait,
                                public nsSupportsWeakReference
 {
 public:
   explicit TabChildMessageManager(TabChild* aTabChild);
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(TabChildMessageManager, DOMEventTargetHelper)
 
   void MarkForCC();
 
-  virtual JSObject* WrapObject(JSContext* aCx,
-                               JS::Handle<JSObject*> aGivenProto) override
-  {
-    MOZ_CRASH("We should never get here!");
-  }
-  bool WrapGlobalObject(JSContext* aCx,
-                        JS::RealmOptions& aOptions,
-                        JS::MutableHandle<JSObject*> aReflector);
+  JSObject* WrapObject(JSContext* aCx,
+                       JS::Handle<JSObject*> aGivenProto) override;
 
   virtual already_AddRefed<nsPIDOMWindowOuter> GetContent(ErrorResult& aError) override;
   virtual already_AddRefed<nsIDocShell> GetDocShell(ErrorResult& aError) override;
   virtual already_AddRefed<nsIEventTarget> GetTabEventTarget() override;
   virtual uint64_t ChromeOuterWindowID() override;
 
   NS_FORWARD_SAFE_NSIMESSAGESENDER(mMessageManager)
 
   void
   GetEventTargetParent(EventChainPreVisitor& aVisitor) override
   {
     aVisitor.mForceContentDispatch = true;
   }
 
-  virtual nsIPrincipal* GetPrincipal() override;
-  virtual JSObject* GetGlobalJSObject() override;
-
   // Dispatch a runnable related to the global.
   virtual nsresult Dispatch(mozilla::TaskCategory aCategory,
                             already_AddRefed<nsIRunnable>&& aRunnable) override;
 
   virtual nsISerialEventTarget*
   EventTargetFor(mozilla::TaskCategory aCategory) const override;
 
   virtual AbstractThread*
@@ -158,23 +147,23 @@ protected:
   typedef mozilla::widget::PuppetWidget PuppetWidget;
 
 public:
   TabChildBase();
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(TabChildBase)
 
-  virtual bool WrapGlobalObject(JSContext* aCx,
-                                JS::RealmOptions& aOptions,
-                                JS::MutableHandle<JSObject*> aReflector) override
+  JSObject* WrapObject(JSContext* aCx,
+                       JS::Handle<JSObject*> aGivenProto)
   {
-    return mTabChildGlobal->WrapGlobalObject(aCx, aOptions, aReflector);
+    return mTabChildMessageManager->WrapObject(aCx, aGivenProto);
   }
 
+
   virtual nsIWebNavigation* WebNavigation() const = 0;
   virtual PuppetWidget* WebWidget() = 0;
   nsIPrincipal* GetPrincipal() { return mPrincipal; }
   virtual bool DoUpdateZoomConstraints(const uint32_t& aPresShellId,
                                        const mozilla::layers::FrameMetrics::ViewID& aViewId,
                                        const Maybe<mozilla::layers::ZoomConstraints>& aConstraints) = 0;
 
   virtual ScreenIntSize GetInnerSize() = 0;
@@ -196,17 +185,17 @@ protected:
   void DispatchMessageManagerMessage(const nsAString& aMessageName,
                                      const nsAString& aJSONData);
 
   void ProcessUpdateFrame(const mozilla::layers::FrameMetrics& aFrameMetrics);
 
   bool UpdateFrameHandler(const mozilla::layers::FrameMetrics& aFrameMetrics);
 
 protected:
-  RefPtr<TabChildMessageManager> mTabChildGlobal;
+  RefPtr<TabChildMessageManager> mTabChildMessageManager;
   nsCOMPtr<nsIWebBrowserChrome3> mWebBrowserChrome;
 };
 
 class TabChild final : public TabChildBase,
                        public PBrowserChild,
                        public nsIWebBrowserChrome2,
                        public nsIEmbeddingSiteWindow,
                        public nsIWebBrowserChromeFocus,
@@ -276,17 +265,17 @@ public:
   NS_DECL_NSITOOLTIPLISTENER
 
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(TabChild, TabChildBase)
 
   FORWARD_SHMEM_ALLOCATOR_TO(PBrowserChild)
 
   TabChildMessageManager* GetMessageManager()
   {
-    return mTabChildGlobal;
+    return mTabChildMessageManager;
   }
 
   /**
    * MessageManagerCallback methods that we override.
    */
   virtual bool DoSendBlockingMessage(JSContext* aCx,
                                      const nsAString& aMessage,
                                      StructuredCloneData& aData,
@@ -768,17 +757,17 @@ private:
   // @param aIsPreallocated  true if this is called for Preallocated Tab.
   void NotifyTabContextUpdated(bool aIsPreallocated);
 
   // Update the frameType on our docshell.
   void UpdateFrameType();
 
   void ActorDestroy(ActorDestroyReason why) override;
 
-  bool InitTabChildGlobal();
+  bool InitTabChildMessageManager();
 
   void InitRenderingState(const TextureFactoryIdentifier& aTextureFactoryIdentifier,
                           const layers::LayersId& aLayersId,
                           const mozilla::layers::CompositorOptions& aCompositorOptions,
                           PRenderFrameChild* aRenderFrame);
   void InitAPZState();
 
   void DestroyWindow();
--- a/testing/marionette/listener.js
+++ b/testing/marionette/listener.js
@@ -616,20 +616,20 @@ function deleteSession() {
  * @param {UUID} uuid
  *     Unique identifier of the request.
  * @param {AsyncContentSender.ResponseType} type
  *     Type of response.
  * @param {*} [Object] data
  *     JSON serialisable object to accompany the message.  Defaults to
  *     an empty dictionary.
  */
-function sendToServer(uuid, data = undefined) {
+let sendToServer = (uuid, data = undefined) => {
   let channel = new proxy.AsyncMessageChannel(sendAsyncMessage.bind(this));
   channel.reply(uuid, data);
-}
+};
 
 /**
  * Send asynchronous reply with value to chrome.
  *
  * @param {Object} obj
  *     JSON serialisable object of arbitrary type and complexity.
  * @param {UUID} uuid
  *     Unique identifier of the request.