Merge m-c to b-i
authorPhil Ringnalda <philringnalda@gmail.com>
Sat, 07 Dec 2013 11:21:04 -0800
changeset 175102 b59fb194a3aef4aad12c44a02dab86d88fcadfb5
parent 175101 4b6889b0418d62053e24f41f372fe626b774cc7d (current diff)
parent 175045 b50d803d0ad59c12c1348de0ba63ee6aa451d8eb (diff)
child 175103 5d73962305dd2b54cd234216e88256fc93805bfb
push id445
push userffxbld
push dateMon, 10 Mar 2014 22:05:19 +0000
treeherdermozilla-release@dc38b741b04e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone28.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge m-c to b-i
dom/base/ScriptSettings.cpp
dom/base/ScriptSettings.h
dom/ipc/TabChild.cpp
dom/ipc/TabChild.h
dom/src/geolocation/nsGeolocation.cpp
js/xpconnect/tests/chrome/test_scriptSettings.xul
--- a/CLOBBER
+++ b/CLOBBER
@@ -13,9 +13,9 @@
 #          |               |
 #          O <-- Clobber   O  <-- Clobber
 #
 # Note: The description below will be part of the error message shown to users.
 #
 # Modifying this file will now automatically clobber the buildbot machines \o/
 #
 
-Bug 933585 - clobber required on windows
+Bug 937317 required a clobber on Windows landing, backout probably will too
--- a/accessible/src/html/HTMLFormControlAccessible.cpp
+++ b/accessible/src/html/HTMLFormControlAccessible.cpp
@@ -9,28 +9,28 @@
 #include "nsAccUtils.h"
 #include "nsEventShell.h"
 #include "nsTextEquivUtils.h"
 #include "Relation.h"
 #include "Role.h"
 #include "States.h"
 
 #include "nsContentList.h"
+#include "nsCxPusher.h"
 #include "mozilla/dom/HTMLInputElement.h"
 #include "nsIAccessibleRelation.h"
 #include "nsIDOMNSEditableElement.h"
 #include "nsIDOMHTMLTextAreaElement.h"
 #include "nsIEditor.h"
 #include "nsIFormControl.h"
 #include "nsINameSpaceManager.h"
 #include "nsIPersistentProperties2.h"
 #include "nsISelectionController.h"
 #include "nsIServiceManager.h"
 #include "nsITextControlFrame.h"
-#include "mozilla/dom/ScriptSettings.h"
 
 #include "mozilla/FloatingPoint.h"
 #include "mozilla/Preferences.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::a11y;
 
@@ -465,17 +465,18 @@ HTMLTextFieldAccessible::GetEditor() con
 {
   nsCOMPtr<nsIDOMNSEditableElement> editableElt(do_QueryInterface(mContent));
   if (!editableElt)
     return nullptr;
 
   // nsGenericHTMLElement::GetEditor has a security check.
   // Make sure we're not restricted by the permissions of
   // whatever script is currently running.
-  mozilla::dom::AutoSystemCaller asc;
+  nsCxPusher pusher;
+  pusher.PushNull();
 
   nsCOMPtr<nsIEditor> editor;
   editableElt->GetEditor(getter_AddRefs(editor));
 
   return editor.forget();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -1540,17 +1540,16 @@ public:
   static nsresult ProcessViewportInfo(nsIDocument *aDocument,
                                       const nsAString &viewportInfo);
 
   static nsIScriptContext* GetContextForEventHandlers(nsINode* aNode,
                                                       nsresult* aRv);
 
   static JSContext *GetCurrentJSContext();
   static JSContext *GetSafeJSContext();
-  static JSContext *GetCurrentJSContextForThread();
   static JSContext *GetDefaultJSContextForThread();
 
   /**
    * Case insensitive comparison between two strings. However it only ignores
    * case for ASCII characters a-z.
    */
   static bool EqualsIgnoreASCIICase(const nsAString& aStr1,
                                     const nsAString& aStr2);
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -5258,27 +5258,16 @@ nsContentUtils::GetDefaultJSContextForTh
   if (MOZ_LIKELY(NS_IsMainThread())) {
     return GetSafeJSContext();
   } else {
     return workers::GetCurrentThreadJSContext();
   }
 }
 
 /* static */
-JSContext *
-nsContentUtils::GetCurrentJSContextForThread()
-{
-  if (MOZ_LIKELY(NS_IsMainThread())) {
-    return GetCurrentJSContext();
-  } else {
-    return workers::GetCurrentThreadJSContext();
-  }
-}
-
-/* static */
 nsresult
 nsContentUtils::ASCIIToLower(nsAString& aStr)
 {
   PRUnichar* iter = aStr.BeginWriting();
   PRUnichar* end = aStr.EndWriting();
   if (MOZ_UNLIKELY(!iter || !end)) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
--- a/content/base/src/nsImageLoadingContent.cpp
+++ b/content/base/src/nsImageLoadingContent.cpp
@@ -34,24 +34,24 @@
 
 #include "nsIChannel.h"
 #include "nsIStreamListener.h"
 
 #include "nsIFrame.h"
 #include "nsIDOMNode.h"
 
 #include "nsContentUtils.h"
+#include "nsCxPusher.h"
 #include "nsLayoutUtils.h"
 #include "nsIContentPolicy.h"
 #include "nsEventDispatcher.h"
 #include "nsSVGEffects.h"
 
 #include "mozAutoDocUpdate.h"
 #include "mozilla/dom/Element.h"
-#include "mozilla/dom/ScriptSettings.h"
 
 #if defined(XP_WIN)
 // Undefine LoadImage to prevent naming conflict with Windows.
 #undef LoadImage
 #endif
 
 using namespace mozilla;
 
@@ -1189,16 +1189,22 @@ nsImageLoadingContent::ClearCurrentReque
 
 void
 nsImageLoadingContent::ClearPendingRequest(nsresult aReason,
                                            uint32_t aFlags)
 {
   if (!mPendingRequest)
     return;
 
+  // Push a null JSContext on the stack so that code that runs within
+  // the below code doesn't think it's being called by JS. See bug
+  // 604262.
+  nsCxPusher pusher;
+  pusher.PushNull();
+
   // Deregister this image from the refresh driver so it no longer receives
   // notifications.
   nsLayoutUtils::DeregisterImageRequest(GetFramePresContext(), mPendingRequest,
                                         &mPendingRequestRegistered);
 
   UntrackImage(mPendingRequest, aFlags);
   mPendingRequest->CancelAndForgetObserver(aReason);
   mPendingRequest = nullptr;
@@ -1248,31 +1254,41 @@ nsImageLoadingContent::BindToTree(nsIDoc
                                   nsIContent* aBindingParent,
                                   bool aCompileEventHandlers)
 {
   // We may be entering the document, so if our image should be tracked,
   // track it.
   if (!aDocument)
     return;
 
+  // Push a null JSContext on the stack so that callbacks triggered by the
+  // below code won't think they're being called from JS.
+  nsCxPusher pusher;
+  pusher.PushNull();
+
   TrackImage(mCurrentRequest);
   TrackImage(mPendingRequest);
 
   if (mCurrentRequestFlags & REQUEST_BLOCKS_ONLOAD)
     aDocument->BlockOnload();
 }
 
 void
 nsImageLoadingContent::UnbindFromTree(bool aDeep, bool aNullParent)
 {
   // We may be leaving the document, so if our image is tracked, untrack it.
   nsCOMPtr<nsIDocument> doc = GetOurCurrentDoc();
   if (!doc)
     return;
 
+  // Push a null JSContext on the stack so that callbacks triggered by the
+  // below code won't think they're being called from JS.
+  nsCxPusher pusher;
+  pusher.PushNull();
+
   UntrackImage(mCurrentRequest);
   UntrackImage(mPendingRequest);
 
   if (mCurrentRequestFlags & REQUEST_BLOCKS_ONLOAD)
     doc->UnblockOnload(false);
 }
 
 void
--- a/content/events/src/nsDOMEventTargetHelper.cpp
+++ b/content/events/src/nsDOMEventTargetHelper.cpp
@@ -4,17 +4,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsDOMEventTargetHelper.h"
 #include "nsContentUtils.h"
 #include "nsEventDispatcher.h"
 #include "nsIDocument.h"
 #include "prprf.h"
 #include "nsGlobalWindow.h"
-#include "ScriptSettings.h"
 #include "mozilla/Likely.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMEventTargetHelper)
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsDOMEventTargetHelper)
@@ -270,17 +269,17 @@ nsresult
 nsDOMEventTargetHelper::SetEventHandler(nsIAtom* aType,
                                         JSContext* aCx,
                                         const JS::Value& aValue)
 {
   nsRefPtr<EventHandlerNonNull> handler;
   JSObject* callable;
   if (aValue.isObject() &&
       JS_ObjectIsCallable(aCx, callable = &aValue.toObject())) {
-    handler = new EventHandlerNonNull(callable, mozilla::dom::GetIncumbentGlobal());
+    handler = new EventHandlerNonNull(callable);
   }
   SetEventHandler(aType, EmptyString(), handler);
   return NS_OK;
 }
 
 void
 nsDOMEventTargetHelper::GetEventHandler(nsIAtom* aType,
                                         JSContext* aCx,
--- a/content/events/src/nsEventListenerManager.cpp
+++ b/content/events/src/nsEventListenerManager.cpp
@@ -878,33 +878,29 @@ nsEventListenerManager::CompileEventHand
 
   if (handler) {
     nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(mTarget);
     // Bind it
     JS::Rooted<JSObject*> boundHandler(cx);
     JS::Rooted<JSObject*> scope(cx, listener->GetEventScope());
     context->BindCompiledEventHandler(mTarget, scope, handler, &boundHandler);
     aListenerStruct = nullptr;
-    // Note - We pass null for aIncumbentGlobal below. We could also pass the
-    // compilation global, but since the handler is guaranteed to be scripted,
-    // there's no need to use an override, since the JS engine will always give
-    // us the right answer.
     if (!boundHandler) {
       listener->ForgetHandler();
     } else if (listener->EventName() == nsGkAtoms::onerror && win) {
       nsRefPtr<OnErrorEventHandlerNonNull> handlerCallback =
-        new OnErrorEventHandlerNonNull(boundHandler, /* aIncumbentGlobal = */ nullptr);
+        new OnErrorEventHandlerNonNull(boundHandler);
       listener->SetHandler(handlerCallback);
     } else if (listener->EventName() == nsGkAtoms::onbeforeunload && win) {
       nsRefPtr<OnBeforeUnloadEventHandlerNonNull> handlerCallback =
-        new OnBeforeUnloadEventHandlerNonNull(boundHandler, /* aIncumbentGlobal = */ nullptr);
+        new OnBeforeUnloadEventHandlerNonNull(boundHandler);
       listener->SetHandler(handlerCallback);
     } else {
       nsRefPtr<EventHandlerNonNull> handlerCallback =
-        new EventHandlerNonNull(boundHandler, /* aIncumbentGlobal = */ nullptr);
+        new EventHandlerNonNull(boundHandler);
       listener->SetHandler(handlerCallback);
     }
   }
 
   return result;
 }
 
 nsresult
--- a/content/html/content/src/nsTextEditorState.cpp
+++ b/content/html/content/src/nsTextEditorState.cpp
@@ -33,21 +33,21 @@
 #include "nsISelectionPrivate.h"
 #include "nsPIDOMWindow.h"
 #include "nsServiceManagerUtils.h"
 #include "nsIEditor.h"
 #include "nsTextEditRules.h"
 #include "mozilla/Selection.h"
 #include "nsEventListenerManager.h"
 #include "nsContentUtils.h"
+#include "nsCxPusher.h"
 #include "mozilla/Preferences.h"
 #include "nsTextNode.h"
 #include "nsIController.h"
 #include "mozilla/TextEvents.h"
-#include "mozilla/dom/ScriptSettings.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 static NS_DEFINE_CID(kTextEditorCID, NS_TEXTEDITOR_CID);
 
 static nsINativeKeyBindings *sNativeInputBindings = nullptr;
 static nsINativeKeyBindings *sNativeTextAreaBindings = nullptr;
@@ -1278,22 +1278,23 @@ nsTextEditorState::PrepareEditor(const n
 
     // Get the DOM document
     nsCOMPtr<nsIDOMDocument> domdoc = do_QueryInterface(shell->GetDocument());
     if (!domdoc)
       return NS_ERROR_FAILURE;
 
     // What follows is a bit of a hack.  The editor uses the public DOM APIs
     // for its content manipulations, and it causes it to fail some security
-    // checks deep inside when initializing. So we explictly make it clear that
-    // we're native code.
+    // checks deep inside when initializing.  So we push a null JSContext
+    // on the JS stack here to make it clear that we're native code.
     // Note that any script that's directly trying to access our value
     // has to be going through some scriptable object to do that and that
     // already does the relevant security checks.
-    AutoSystemCaller asc;
+    nsCxPusher pusher;
+    pusher.PushNull();
 
     rv = newEditor->Init(domdoc, GetRootNode(), mSelCon, editorFlags);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   // Initialize the controller for the editor
 
   if (!SuppressEventHandlers(presContext)) {
@@ -1771,18 +1772,19 @@ nsTextEditorState::GetValue(nsAString& a
     // access its own DOM nodes!  Let's try to deal with that by pushing a null
     // JSContext on the JSContext stack to make it clear that we're native
     // code.  Note that any script that's directly trying to access our value
     // has to be going through some scriptable object to do that and that
     // already does the relevant security checks.
     // XXXbz if we could just get the textContent of our anonymous content (eg
     // if plaintext editor didn't create <br> nodes all over), we wouldn't need
     // this.
-    { /* Scope for AutoSystemCaller. */
-      AutoSystemCaller asc;
+    { /* Scope for context pusher */
+      nsCxPusher pusher;
+      pusher.PushNull();
 
       mEditor->OutputToString(NS_LITERAL_STRING("text/plain"), flags,
                               aValue);
     }
     if (canCache) {
       mCachedValue = aValue;
     } else {
       mCachedValue.Truncate();
@@ -1850,18 +1852,19 @@ nsTextEditorState::SetValue(const nsAStr
       if (!domDoc) {
         NS_WARNING("Why don't we have a document?");
         return;
       }
 
       // Time to mess with our security context... See comments in GetValue()
       // for why this is needed.  Note that we have to do this up here, because
       // otherwise SelectAll() will fail.
-      {
-        AutoSystemCaller asc;
+      { /* Scope for context pusher */
+        nsCxPusher pusher;
+        pusher.PushNull();
 
         nsCOMPtr<nsISelection> domSel;
         nsCOMPtr<nsISelectionPrivate> selPriv;
         mSelCon->GetSelection(nsISelectionController::SELECTION_NORMAL,
                               getter_AddRefs(domSel));
         if (domSel)
         {
           selPriv = do_QueryInterface(domSel);
--- a/content/xbl/src/nsXBLPrototypeHandler.cpp
+++ b/content/xbl/src/nsXBLPrototypeHandler.cpp
@@ -317,17 +317,17 @@ nsXBLPrototypeHandler::ExecuteHandler(Ev
 
   // Now, wrap the bound handler into the content compartment and use it.
   JSAutoCompartment ac2(cx, globalObject);
   if (!JS_WrapObject(cx, &bound)) {
     return NS_ERROR_FAILURE;
   }
 
   nsRefPtr<EventHandlerNonNull> handlerCallback =
-    new EventHandlerNonNull(bound, /* aIncumbentGlobal = */ nullptr);
+    new EventHandlerNonNull(bound);
 
   nsEventHandler eventHandler(handlerCallback);
 
   // Execute it.
   nsCOMPtr<nsIJSEventListener> eventListener;
   rv = NS_NewJSEventListener(globalObject,
                              scriptTarget, onEventAtom,
                              eventHandler,
deleted file mode 100644
--- a/dom/base/ScriptSettings.cpp
+++ /dev/null
@@ -1,191 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-// vim: ft=cpp tw=78 sw=2 et ts=2
-/* 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/ScriptSettings.h"
-#include "mozilla/ThreadLocal.h"
-#include "mozilla/Assertions.h"
-
-#include "jsapi.h"
-#include "xpcpublic.h"
-#include "nsIGlobalObject.h"
-#include "nsIScriptGlobalObject.h"
-#include "nsIScriptContext.h"
-#include "nsContentUtils.h"
-#include "nsTArray.h"
-
-namespace mozilla {
-namespace dom {
-
-class ScriptSettingsStack;
-static mozilla::ThreadLocal<ScriptSettingsStack*> sScriptSettingsTLS;
-
-ScriptSettingsStackEntry ScriptSettingsStackEntry::SystemSingleton;
-
-class ScriptSettingsStack {
-public:
-  static ScriptSettingsStack& Ref() {
-    return *sScriptSettingsTLS.get();
-  }
-  ScriptSettingsStack() {};
-
-  void Push(ScriptSettingsStackEntry* aSettings) {
-    // The bottom-most entry must always be a candidate entry point.
-    MOZ_ASSERT_IF(mStack.Length() == 0 || mStack.LastElement()->IsSystemSingleton(),
-                  aSettings->mIsCandidateEntryPoint);
-    mStack.AppendElement(aSettings);
-  }
-
-  void PushSystem() {
-    mStack.AppendElement(&ScriptSettingsStackEntry::SystemSingleton);
-  }
-
-  void Pop() {
-    MOZ_ASSERT(mStack.Length() > 0);
-    mStack.RemoveElementAt(mStack.Length() - 1);
-  }
-
-  nsIGlobalObject* Incumbent() {
-    if (!mStack.Length()) {
-      return nullptr;
-    }
-    return mStack.LastElement()->mGlobalObject;
-  }
-
-  nsIGlobalObject* EntryPoint() {
-    if (!mStack.Length())
-      return nullptr;
-    for (int i = mStack.Length() - 1; i >= 0; --i) {
-      if (mStack[i]->mIsCandidateEntryPoint) {
-        return mStack[i]->mGlobalObject;
-      }
-    }
-    MOZ_ASSUME_UNREACHABLE("Non-empty stack should always have an entry point");
-  }
-
-private:
-  // These pointers are caller-owned.
-  nsTArray<ScriptSettingsStackEntry*> mStack;
-};
-
-void
-InitScriptSettings()
-{
-  if (!sScriptSettingsTLS.initialized()) {
-    bool success = sScriptSettingsTLS.init();
-    if (!success) {
-      MOZ_CRASH();
-    }
-  }
-
-  ScriptSettingsStack* ptr = new ScriptSettingsStack();
-  sScriptSettingsTLS.set(ptr);
-}
-
-void DestroyScriptSettings()
-{
-  ScriptSettingsStack* ptr = sScriptSettingsTLS.get();
-  MOZ_ASSERT(ptr);
-  sScriptSettingsTLS.set(nullptr);
-  delete ptr;
-}
-
-// Note: When we're ready to expose it, GetEntryGlobal will look similar to
-// GetIncumbentGlobal below.
-
-nsIGlobalObject*
-GetIncumbentGlobal()
-{
-  // We need the current JSContext in order to check the JS for
-  // scripted frames that may have appeared since anyone last
-  // manipulated the stack. If it's null, that means that there
-  // must be no entry point on the stack, and therefore no incumbent
-  // global either.
-  JSContext *cx = nsContentUtils::GetCurrentJSContextForThread();
-  if (!cx) {
-    MOZ_ASSERT(ScriptSettingsStack::Ref().EntryPoint() == nullptr);
-    return nullptr;
-  }
-
-  // See what the JS engine has to say. If we've got a scripted caller
-  // override in place, the JS engine will lie to us and pretend that
-  // there's nothing on the JS stack, which will cause us to check the
-  // incumbent script stack below.
-  JS::RootedScript script(cx);
-  if (JS_DescribeScriptedCaller(cx, &script, nullptr)) {
-    JS::RootedObject global(cx, JS_GetGlobalFromScript(script));
-    MOZ_ASSERT(global);
-    return xpc::GetNativeForGlobal(global);
-  }
-
-  // Ok, nothing from the JS engine. Let's use whatever's on the
-  // explicit stack.
-  return ScriptSettingsStack::Ref().Incumbent();
-}
-
-AutoEntryScript::AutoEntryScript(nsIGlobalObject* aGlobalObject,
-                                 bool aIsMainThread,
-                                 JSContext* aCx)
-  : mStack(ScriptSettingsStack::Ref())
-  , mEntry(aGlobalObject, /* aCandidate = */ true)
-{
-  MOZ_ASSERT(aGlobalObject);
-  if (!aCx) {
-    // If the caller didn't provide a cx, hunt one down. This isn't exactly
-    // fast, but the callers that care about performance can pass an explicit
-    // cx for now. Eventually, the whole cx pushing thing will go away
-    // entirely.
-    MOZ_ASSERT(aIsMainThread, "cx is mandatory off-main-thread");
-    nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(aGlobalObject);
-    if (sgo && sgo->GetScriptContext()) {
-      aCx = sgo->GetScriptContext()->GetNativeContext();
-    }
-    if (!aCx) {
-      aCx = nsContentUtils::GetSafeJSContext();
-    }
-  }
-  if (aIsMainThread) {
-    mCxPusher.Push(aCx);
-  }
-  mAc.construct(aCx, aGlobalObject->GetGlobalJSObject());
-  mStack.Push(&mEntry);
-}
-
-AutoEntryScript::~AutoEntryScript()
-{
-  MOZ_ASSERT(mStack.Incumbent() == mEntry.mGlobalObject);
-  mStack.Pop();
-}
-
-AutoIncumbentScript::AutoIncumbentScript(nsIGlobalObject* aGlobalObject)
-  : mStack(ScriptSettingsStack::Ref())
-  , mEntry(aGlobalObject, /* aCandidate = */ false)
-  , mCallerOverride(nsContentUtils::GetCurrentJSContextForThread())
-{
-  mStack.Push(&mEntry);
-}
-
-AutoIncumbentScript::~AutoIncumbentScript()
-{
-  MOZ_ASSERT(mStack.Incumbent() == mEntry.mGlobalObject);
-  mStack.Pop();
-}
-
-AutoSystemCaller::AutoSystemCaller(bool aIsMainThread)
-  : mStack(ScriptSettingsStack::Ref())
-{
-  if (aIsMainThread) {
-    mCxPusher.PushNull();
-  }
-  mStack.PushSystem();
-}
-
-AutoSystemCaller::~AutoSystemCaller()
-{
-  mStack.Pop();
-}
-
-} // namespace dom
-} // namespace mozilla
deleted file mode 100644
--- a/dom/base/ScriptSettings.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-// vim: ft=cpp tw=78 sw=2 et ts=2
-/* 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/. */
-
-/* Utilities for managing the script settings object stack defined in webapps */
-
-#ifndef mozilla_dom_ScriptSettings_h
-#define mozilla_dom_ScriptSettings_h
-
-#include "nsCxPusher.h"
-#include "MainThreadUtils.h"
-#include "nsIGlobalObject.h"
-
-#include "mozilla/Maybe.h"
-
-class nsIGlobalObject;
-
-namespace mozilla {
-namespace dom {
-
-/*
- * System-wide setup/teardown routines. Init and Destroy should be invoked
- * once each, at startup and shutdown (respectively).
- */
-void InitScriptSettings();
-void DestroyScriptSettings();
-
-// Note: We don't yet expose GetEntryGlobal, because in order for it to be
-// correct, we first need to replace a bunch of explicit cx pushing in the
-// browser with AutoEntryScript. But GetIncumbentGlobal is simpler, because it
-// can mostly be inferred from the JS stack.
-nsIGlobalObject* GetIncumbentGlobal();
-
-class ScriptSettingsStack;
-struct ScriptSettingsStackEntry {
-  nsCOMPtr<nsIGlobalObject> mGlobalObject;
-  bool mIsCandidateEntryPoint;
-
-  ScriptSettingsStackEntry(nsIGlobalObject *aGlobal, bool aCandidate)
-    : mGlobalObject(aGlobal)
-    , mIsCandidateEntryPoint(aCandidate)
-  {
-    MOZ_ASSERT(mGlobalObject);
-    MOZ_ASSERT(mGlobalObject->GetGlobalJSObject(),
-               "Must have an actual JS global for the duration on the stack");
-    MOZ_ASSERT(JS_IsGlobalObject(mGlobalObject->GetGlobalJSObject()),
-               "No outer windows allowed");
-  }
-
-  ~ScriptSettingsStackEntry() {
-    // We must have an actual JS global for the entire time this is on the stack.
-    MOZ_ASSERT_IF(mGlobalObject, mGlobalObject->GetGlobalJSObject());
-  }
-
-  bool IsSystemSingleton() { return this == &SystemSingleton; }
-  static ScriptSettingsStackEntry SystemSingleton;
-
-private:
-  ScriptSettingsStackEntry() : mGlobalObject(nullptr)
-                             , mIsCandidateEntryPoint(true)
-  {}
-};
-
-/*
- * A class that represents a new script entry point.
- */
-class AutoEntryScript {
-public:
-  AutoEntryScript(nsIGlobalObject* aGlobalObject,
-                  bool aIsMainThread = NS_IsMainThread(),
-                  // Note: aCx is mandatory off-main-thread.
-                  JSContext* aCx = nullptr);
-  ~AutoEntryScript();
-
-private:
-  dom::ScriptSettingsStack& mStack;
-  dom::ScriptSettingsStackEntry mEntry;
-  nsCxPusher mCxPusher;
-  mozilla::Maybe<JSAutoCompartment> mAc; // This can de-Maybe-fy when mCxPusher
-                                         // goes away.
-};
-
-/*
- * A class that can be used to force a particular incumbent script on the stack.
- */
-class AutoIncumbentScript {
-public:
-  AutoIncumbentScript(nsIGlobalObject* aGlobalObject);
-  ~AutoIncumbentScript();
-private:
-  dom::ScriptSettingsStack& mStack;
-  dom::ScriptSettingsStackEntry mEntry;
-  JS::AutoHideScriptedCaller mCallerOverride;
-};
-
-/*
- * A class used for C++ to indicate that existing entry and incumbent scripts
- * should not apply to anything in scope, and that callees should act as if
- * they were invoked "from C++".
- */
-class AutoSystemCaller {
-public:
-  AutoSystemCaller(bool aIsMainThread = NS_IsMainThread());
-  ~AutoSystemCaller();
-private:
-  dom::ScriptSettingsStack& mStack;
-  nsCxPusher mCxPusher;
-};
-
-} // namespace dom
-} // namespace mozilla
-
-#endif // mozilla_dom_ScriptSettings_h
--- a/dom/base/moz.build
+++ b/dom/base/moz.build
@@ -54,17 +54,16 @@ EXPORTS.mozilla.dom += [
     'DOMError.h',
     'DOMException.h',
     'DOMRequest.h',
     'MessageChannel.h',
     'MessagePort.h',
     'MessagePortList.h',
     'Navigator.h',
     'ScreenOrientation.h',
-    'ScriptSettings.h',
     'StructuredCloneTags.h',
     'URL.h',
 ]
 
 UNIFIED_SOURCES += [
     'BarProps.cpp',
     'CompositionStringSynthesizer.cpp',
     'Crypto.cpp',
@@ -90,17 +89,16 @@ UNIFIED_SOURCES += [
     'nsPerformance.cpp',
     'nsQueryContentEventResult.cpp',
     'nsScreen.cpp',
     'nsScriptNameSpaceManager.cpp',
     'nsStructuredCloneContainer.cpp',
     'nsWindowMemoryReporter.cpp',
     'nsWindowRoot.cpp',
     'nsWrapperCache.cpp',
-    'ScriptSettings.cpp',
     'URL.cpp',
     'WindowNamedPropertiesHandler.cpp',
 ]
 
 # these files couldn't be in UNIFIED_SOURCES for now for reasons given below:
 SOURCES += [
     # this file doesn't like windows.h
     'MessagePort.cpp',
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -39,17 +39,16 @@
 // Helper Classes
 #include "nsJSUtils.h"
 #include "jsapi.h"              // for JSAutoRequest
 #include "js/OldDebugAPI.h"     // for JS_ClearWatchPointsForObject
 #include "jswrapper.h"
 #include "nsReadableUtils.h"
 #include "nsDOMClassInfo.h"
 #include "nsJSEnvironment.h"
-#include "ScriptSettings.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Likely.h"
 
 // Other Classes
 #include "nsEventListenerManager.h"
 #include "mozilla/dom/BarProps.h"
 #include "nsContentCID.h"
 #include "nsLayoutStatics.h"
@@ -207,17 +206,16 @@
 #include "TimeChangeObserver.h"
 #include "mozilla/dom/AudioContext.h"
 #include "mozilla/dom/BrowserElementDictionariesBinding.h"
 #include "mozilla/dom/FunctionBinding.h"
 #include "mozilla/dom/WindowBinding.h"
 #include "nsITabChild.h"
 #include "nsIDOMMediaQueryList.h"
 #include "mozilla/dom/DOMJSClass.h"
-#include "mozilla/dom/ScriptSettings.h"
 
 #ifdef MOZ_WEBSPEECH
 #include "mozilla/dom/SpeechSynthesis.h"
 #endif
 
 #ifdef MOZ_JSDEBUGGER
 #include "jsdIDebuggerService.h"
 #endif
@@ -4944,17 +4942,17 @@ nsGlobalWindow::RequestAnimationFrame(co
                                       JSContext* cx,
                                       int32_t* aHandle)
 {
   if (!aCallback.isObject() || !JS_ObjectIsCallable(cx, &aCallback.toObject())) {
     return NS_ERROR_INVALID_ARG;
   }
 
   nsRefPtr<FrameRequestCallback> callback =
-    new FrameRequestCallback(&aCallback.toObject(), GetIncumbentGlobal());
+    new FrameRequestCallback(&aCallback.toObject());
 
   ErrorResult rv;
   *aHandle = RequestAnimationFrame(*callback, rv);
 
   return rv.ErrorCode();
 }
 
 NS_IMETHODIMP
@@ -11210,28 +11208,28 @@ nsGlobalWindow::OpenInternal(const nsASt
     if (!aCalledNoScript) {
       // We asserted at the top of this function that aNavigate is true for
       // !aCalledNoScript.
       rv = pwwatch->OpenWindow2(this, url.get(), name_ptr, options_ptr,
                                 /* aCalledFromScript = */ true,
                                 aDialog, aNavigate, argv,
                                 getter_AddRefs(domReturn));
     } else {
-      // Force a system caller here so that the window watcher won't screw us
+      // Push a null JSContext here so that the window watcher won't screw us
       // up.  We do NOT want this case looking at the JS context on the stack
       // when searching.  Compare comments on
       // nsIDOMWindow::OpenWindow and nsIWindowWatcher::OpenWindow.
 
       // Note: Because nsWindowWatcher is so broken, it's actually important
-      // that we don't force a system caller here, because that screws it up
-      // when it tries to compute the caller principal to associate with dialog
+      // that we don't push a null cx here, because that screws it up when it
+      // tries to compute the caller principal to associate with dialog
       // arguments. That whole setup just really needs to be rewritten. :-(
-      Maybe<AutoSystemCaller> asc;
+      nsCxPusher pusher;
       if (!aContentModal) {
-        asc.construct();
+        pusher.PushNull();
       }
 
 
       rv = pwwatch->OpenWindow2(this, url.get(), name_ptr, options_ptr,
                                 /* aCalledFromScript = */ false,
                                 aDialog, aNavigate, aExtraArgument,
                                 getter_AddRefs(domReturn));
 
@@ -13233,17 +13231,17 @@ nsGlobalWindow::DisableNetworkEvent(uint
     return NS_OK;                                                            \
   }                                                                          \
   NS_IMETHODIMP nsGlobalWindow::SetOn##name_(JSContext *cx,                  \
                                              const JS::Value &v) {           \
     nsRefPtr<EventHandlerNonNull> handler;                                   \
     JSObject *callable;                                                      \
     if (v.isObject() &&                                                      \
         JS_ObjectIsCallable(cx, callable = &v.toObject())) {                 \
-      handler = new EventHandlerNonNull(callable, GetIncumbentGlobal());     \
+      handler = new EventHandlerNonNull(callable);                           \
     }                                                                        \
     SetOn##name_(handler);                                                   \
     return NS_OK;                                                            \
   }
 #define ERROR_EVENT(name_, id_, type_, struct_)                              \
   NS_IMETHODIMP nsGlobalWindow::GetOn##name_(JSContext *cx,                  \
                                              JS::Value *vp) {                \
     nsEventListenerManager *elm = GetExistingListenerManager();              \
@@ -13263,17 +13261,17 @@ nsGlobalWindow::DisableNetworkEvent(uint
     if (!elm) {                                                              \
       return NS_ERROR_OUT_OF_MEMORY;                                         \
     }                                                                        \
                                                                              \
     nsRefPtr<OnErrorEventHandlerNonNull> handler;                            \
     JSObject *callable;                                                      \
     if (v.isObject() &&                                                      \
         JS_ObjectIsCallable(cx, callable = &v.toObject())) {                 \
-      handler = new OnErrorEventHandlerNonNull(callable, GetIncumbentGlobal()); \
+      handler = new OnErrorEventHandlerNonNull(callable);                    \
     }                                                                        \
     elm->SetEventHandler(handler);                                           \
     return NS_OK;                                                            \
   }
 #define BEFOREUNLOAD_EVENT(name_, id_, type_, struct_)                       \
   NS_IMETHODIMP nsGlobalWindow::GetOn##name_(JSContext *cx,                  \
                                              JS::Value *vp) {                \
     nsEventListenerManager *elm = GetExistingListenerManager();              \
@@ -13294,17 +13292,17 @@ nsGlobalWindow::DisableNetworkEvent(uint
     if (!elm) {                                                              \
       return NS_ERROR_OUT_OF_MEMORY;                                         \
     }                                                                        \
                                                                              \
     nsRefPtr<OnBeforeUnloadEventHandlerNonNull> handler;                     \
     JSObject *callable;                                                      \
     if (v.isObject() &&                                                      \
         JS_ObjectIsCallable(cx, callable = &v.toObject())) {                 \
-      handler = new OnBeforeUnloadEventHandlerNonNull(callable, GetIncumbentGlobal()); \
+      handler = new OnBeforeUnloadEventHandlerNonNull(callable);             \
     }                                                                        \
     elm->SetEventHandler(handler);                                           \
     return NS_OK;                                                            \
   }
 #define WINDOW_ONLY_EVENT EVENT
 #define TOUCH_EVENT EVENT
 #include "nsEventNameList.h"
 #undef TOUCH_EVENT
--- a/dom/base/nsJSTimeoutHandler.cpp
+++ b/dom/base/nsJSTimeoutHandler.cpp
@@ -355,17 +355,17 @@ nsJSScriptTimeoutHandler::Init(nsGlobalW
     if (nsJSUtils::GetCallingLocation(cx, &filename, &mLineNo)) {
       mFileName.Assign(filename);
     }
   } else if (funobj) {
     *aAllowEval = true;
 
     mozilla::HoldJSObjects(this);
 
-    mFunction = new Function(funobj, GetIncumbentGlobal());
+    mFunction = new Function(funobj);
 
     // Create our arg array.  argc is the number of arguments passed
     // to setTimeout or setInterval; the first two are our callback
     // and the delay, so only arguments after that need to go in our
     // array.
     // std::max(argc - 2, 0) wouldn't work right because argc is unsigned.
     uint32_t argCount = std::max(argc, 2u) - 2;
 
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -22,17 +22,16 @@
 #include "nsIXPConnect.h"
 #include "WrapperFactory.h"
 #include "xpcprivate.h"
 #include "XPCQuickStubs.h"
 #include "XrayWrapper.h"
 #include "nsPrintfCString.h"
 #include "prprf.h"
 
-#include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/dom/DOMError.h"
 #include "mozilla/dom/DOMErrorBinding.h"
 #include "mozilla/dom/HTMLObjectElement.h"
 #include "mozilla/dom/HTMLObjectElementBinding.h"
 #include "mozilla/dom/HTMLSharedObjectElement.h"
 #include "mozilla/dom/HTMLEmbedElementBinding.h"
 #include "mozilla/dom/HTMLAppletElementBinding.h"
 #include "WorkerPrivate.h"
@@ -2011,22 +2010,22 @@ ConstructJSImplementation(JSContext* aCx
 {
   // Get the window to use as a parent and for initialization.
   nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobal.GetAsSupports());
   if (!window) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  // Make sure to divorce ourselves from the calling JS while creating and
+  // Make sure to have nothing on the JS context stack while creating and
   // initializing the object, so exceptions from that will get reported
   // properly, since those are never exceptions that a spec wants to be thrown.
-  {
-    AutoSystemCaller asc;
-
+  {  // Scope for the nsCxPusher
+    nsCxPusher pusher;
+    pusher.PushNull();
     // Get the XPCOM component containing the JS implementation.
     nsCOMPtr<nsISupports> implISupports = do_CreateInstance(aContractId);
     if (!implISupports) {
       NS_WARNING("Failed to get JS implementation for contract");
       aRv.Throw(NS_ERROR_FAILURE);
       return nullptr;
     }
     // Initialize the object, if it implements nsIDOMGlobalPropertyInitializer.
--- a/dom/bindings/CallbackFunction.h
+++ b/dom/bindings/CallbackFunction.h
@@ -20,19 +20,18 @@
 #include "mozilla/dom/CallbackObject.h"
 
 namespace mozilla {
 namespace dom {
 
 class CallbackFunction : public CallbackObject
 {
 public:
-  explicit CallbackFunction(JSObject* aCallable,
-                            nsIGlobalObject* aIncumbentGlobal)
-    : CallbackObject(aCallable, aIncumbentGlobal)
+  explicit CallbackFunction(JSObject* aCallable)
+    : CallbackObject(aCallable)
   {
     MOZ_ASSERT(JS_ObjectIsCallable(nullptr, mCallback));
   }
 
   JS::Handle<JSObject*> Callable() const
   {
     return Callback();
   }
--- a/dom/bindings/CallbackInterface.h
+++ b/dom/bindings/CallbackInterface.h
@@ -19,19 +19,18 @@
 #include "mozilla/dom/CallbackObject.h"
 
 namespace mozilla {
 namespace dom {
 
 class CallbackInterface : public CallbackObject
 {
 public:
-  explicit CallbackInterface(JSObject* aCallback,
-                             nsIGlobalObject *aIncumbentGlobal)
-    : CallbackObject(aCallback, aIncumbentGlobal)
+  explicit CallbackInterface(JSObject* aCallback)
+    : CallbackObject(aCallback)
   {
   }
 
 protected:
   bool GetCallableProperty(JSContext* cx, const char* aPropName,
                            JS::MutableHandle<JS::Value> aCallable);
 
 };
--- a/dom/bindings/CallbackObject.cpp
+++ b/dom/bindings/CallbackObject.cpp
@@ -14,44 +14,41 @@
 #include "nsIScriptContext.h"
 #include "nsPIDOMWindow.h"
 #include "nsJSUtils.h"
 #include "nsCxPusher.h"
 #include "nsIScriptSecurityManager.h"
 #include "xpcprivate.h"
 #include "WorkerPrivate.h"
 #include "nsGlobalWindow.h"
-#include "WorkerScope.h"
 
 namespace mozilla {
 namespace dom {
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CallbackObject)
   NS_INTERFACE_MAP_ENTRY(mozilla::dom::CallbackObject)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(CallbackObject)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(CallbackObject)
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(CallbackObject)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(CallbackObject)
   tmp->DropCallback();
-  NS_IMPL_CYCLE_COLLECTION_UNLINK(mIncumbentGlobal)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(CallbackObject)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIncumbentGlobal)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(CallbackObject)
   NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mCallback)
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
-CallbackObject::CallSetup::CallSetup(CallbackObject* aCallback,
+CallbackObject::CallSetup::CallSetup(JS::Handle<JSObject*> aCallback,
                                      ErrorResult& aRv,
                                      ExceptionHandling aExceptionHandling,
                                      JSCompartment* aCompartment)
   : mCx(nullptr)
   , mCompartment(aCompartment)
   , mErrorResult(aRv)
   , mExceptionHandling(aExceptionHandling)
   , mIsMainThread(NS_IsMainThread())
@@ -61,19 +58,18 @@ CallbackObject::CallSetup::CallSetup(Cal
   }
   // We need to produce a useful JSContext here.  Ideally one that the callback
   // is in some sense associated with, so that we can sort of treat it as a
   // "script entry point".  Though once we actually have script entry points,
   // we'll need to do the script entry point bits once we have an actual
   // callable.
 
   // First, find the real underlying callback.
-  JSObject* realCallback = js::UncheckedUnwrap(aCallback->CallbackPreserveColor());
+  JSObject* realCallback = js::UncheckedUnwrap(aCallback);
   JSContext* cx = nullptr;
-  nsIGlobalObject* globalObject = nullptr;
 
   if (mIsMainThread) {
     // Now get the global and JSContext for this callback.
     nsGlobalWindow* win = xpc::WindowGlobalOrNull(realCallback);
     if (win) {
       // Make sure that if this is a window it's the current inner, since the
       // nsIScriptContext and hence JSContext are associated with the outer
       // window.  Which means that if someone holds on to a function from a
@@ -84,63 +80,52 @@ CallbackObject::CallSetup::CallSetup(Cal
       if (!outer || win != outer->GetCurrentInnerWindow()) {
         // Just bail out from here
         return;
       }
       cx = win->GetContext() ? win->GetContext()->GetNativeContext()
                              // This happens - Removing it causes
                              // test_bug293235.xul to go orange.
                              : nsContentUtils::GetSafeJSContext();
-      globalObject = win;
     } else {
-      // No DOM Window. Store the global and use the SafeJSContext.
-      JSObject* glob = js::GetGlobalForObjectCrossCompartment(realCallback);
-      globalObject = xpc::GetNativeForGlobal(glob);
-      MOZ_ASSERT(globalObject);
+      // No DOM Window. Use the SafeJSContext.
       cx = nsContentUtils::GetSafeJSContext();
     }
+
+    // Make sure our JSContext is pushed on the stack.
+    mCxPusher.Push(cx);
   } else {
     cx = workers::GetCurrentThreadJSContext();
-    globalObject = workers::GetCurrentThreadWorkerPrivate()->GlobalScope();
   }
 
-  mAutoEntryScript.construct(globalObject, mIsMainThread, cx);
-  if (aCallback->IncumbentGlobalOrNull()) {
-    mAutoIncumbentScript.construct(aCallback->IncumbentGlobalOrNull());
-  }
-
-  // Unmark the callable (by invoking Callback() and not the CallbackPreserveColor()
-  // variant), and stick it in a Rooted before it can go gray again.
+  // Unmark the callable, and stick it in a Rooted before it can go gray again.
   // Nothing before us in this function can trigger a CC, so it's safe to wait
   // until here it do the unmark. This allows us to order the following two
   // operations _after_ the Push() above, which lets us take advantage of the
   // JSAutoRequest embedded in the pusher.
   //
   // We can do this even though we're not in the right compartment yet, because
   // Rooted<> does not care about compartments.
-  mRootedCallable.construct(cx, aCallback->Callback());
+  JS::ExposeObjectToActiveJS(aCallback);
+  mRootedCallable.construct(cx, aCallback);
 
   if (mIsMainThread) {
     // Check that it's ok to run this callback at all.
-    // Make sure to use realCallback to get the global of the callback object,
-    // not the wrapper.
+    // Make sure to unwrap aCallback before passing it in to get the global of
+    // the callback object, not the wrapper.
     bool allowed = nsContentUtils::GetSecurityManager()->
-      ScriptAllowed(js::GetGlobalForObjectCrossCompartment(realCallback));
+      ScriptAllowed(js::GetGlobalForObjectCrossCompartment(js::UncheckedUnwrap(aCallback)));
 
     if (!allowed) {
       return;
     }
   }
 
   // Enter the compartment of our callback, so we can actually work with it.
-  //
-  // Note that if the callback is a wrapper, this will not be the same
-  // compartment that we ended up in with mAutoEntryScript above, because the
-  // entry point is based off of the unwrapped callback (realCallback).
-  mAc.construct(cx, mRootedCallable.ref());
+  mAc.construct(cx, aCallback);
 
   // And now we're ready to go.
   mCx = cx;
 
   // Make sure the JS engine doesn't report exceptions we want to re-throw
   if (mExceptionHandling == eRethrowContentExceptions ||
       mExceptionHandling == eRethrowExceptions) {
     mSavedJSContextOptions = JS::ContextOptionsRef(cx);
@@ -204,21 +189,27 @@ CallbackObject::CallSetup::~CallSetup()
       nsJSUtils::ReportPendingException(mCx);
     }
   }
 
   // To get our nesting right we have to destroy our JSAutoCompartment first.
   // But be careful: it might not have been constructed at all!
   mAc.destroyIfConstructed();
 
-  mAutoIncumbentScript.destroyIfConstructed();
-  mAutoEntryScript.destroyIfConstructed();
+  // XXXbz For that matter why do we need to manually call ScriptEvaluated at
+  // all?  nsCxPusher::Pop will do that nowadays if !mScriptIsRunning, so the
+  // concerns from bug 295983 don't seem relevant anymore.  Do we want to make
+  // sure it's still called when !mScriptIsRunning?  I guess play it safe for
+  // now and do what CallEventHandler did, which is call always.
+
+  // Popping an nsCxPusher is safe even if it never got pushed.
+  mCxPusher.Pop();
 
   // It is important that this is the last thing we do, after leaving the
-  // compartment and undoing all our entry/incumbent script changes
+  // compartment and popping the context.
   if (mIsMainThread) {
     nsContentUtils::LeaveMicroTask();
   }
 }
 
 already_AddRefed<nsISupports>
 CallbackObjectHolderBase::ToXPCOMCallback(CallbackObject* aCallback,
                                           const nsIID& aIID) const
--- a/dom/bindings/CallbackObject.h
+++ b/dom/bindings/CallbackObject.h
@@ -20,18 +20,18 @@
 #include "nsISupports.h"
 #include "nsISupportsImpl.h"
 #include "nsCycleCollectionParticipant.h"
 #include "jswrapper.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/HoldDropJSObjects.h"
 #include "mozilla/Util.h"
-#include "mozilla/dom/ScriptSettings.h"
 #include "nsContentUtils.h"
+#include "nsCxPusher.h"
 #include "nsWrapperCache.h"
 #include "nsJSEnvironment.h"
 #include "xpcpublic.h"
 
 namespace mozilla {
 namespace dom {
 
 #define DOM_CALLBACKOBJECT_IID \
@@ -41,23 +41,19 @@ namespace dom {
 class CallbackObject : public nsISupports
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(DOM_CALLBACKOBJECT_IID)
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(CallbackObject)
 
-  // The caller may pass a global object which will act as an override for the
-  // incumbent script settings object when the callback is invoked (overriding
-  // the entry point computed from aCallback). If no override is required, the
-  // caller should pass null.
-  explicit CallbackObject(JSObject* aCallback, nsIGlobalObject *aIncumbentGlobal)
+  explicit CallbackObject(JSObject* aCallback)
   {
-    Init(aCallback, aIncumbentGlobal);
+    Init(aCallback);
   }
 
   virtual ~CallbackObject()
   {
     DropCallback();
   }
 
   JS::Handle<JSObject*> Callback() const
@@ -76,77 +72,69 @@ public:
    */
   JS::Handle<JSObject*> CallbackPreserveColor() const
   {
     // Calling fromMarkedLocation() is safe because we trace our mCallback, and
     // because the value of mCallback cannot change after if has been set.
     return JS::Handle<JSObject*>::fromMarkedLocation(mCallback.address());
   }
 
-  nsIGlobalObject* IncumbentGlobalOrNull() const
-  {
-    return mIncumbentGlobal;
-  }
-
   enum ExceptionHandling {
     // Report any exception and don't throw it to the caller code.
     eReportExceptions,
     // Throw an exception to the caller code if the thrown exception is a
     // binding object for a DOMError from the caller's scope, otherwise report
     // it.
     eRethrowContentExceptions,
     // Throw any exception to the caller code.
     eRethrowExceptions
   };
 
 protected:
   explicit CallbackObject(CallbackObject* aCallbackObject)
   {
-    Init(aCallbackObject->mCallback, aCallbackObject->mIncumbentGlobal);
+    Init(aCallbackObject->mCallback);
   }
 
 private:
-  inline void Init(JSObject* aCallback, nsIGlobalObject* aIncumbentGlobal)
+  inline void Init(JSObject* aCallback)
   {
     MOZ_ASSERT(aCallback && !mCallback);
     // Set mCallback before we hold, on the off chance that a GC could somehow
     // happen in there... (which would be pretty odd, granted).
     mCallback = aCallback;
     mozilla::HoldJSObjects(this);
-
-    mIncumbentGlobal = aIncumbentGlobal;
   }
 
   CallbackObject(const CallbackObject&) MOZ_DELETE;
   CallbackObject& operator =(const CallbackObject&) MOZ_DELETE;
 
 protected:
   void DropCallback()
   {
     if (mCallback) {
       mCallback = nullptr;
       mozilla::DropJSObjects(this);
     }
   }
 
   JS::Heap<JSObject*> mCallback;
-  nsCOMPtr<nsIGlobalObject> mIncumbentGlobal;
 
   class MOZ_STACK_CLASS CallSetup
   {
     /**
      * A class that performs whatever setup we need to safely make a
      * call while this class is on the stack, After the constructor
      * returns, the call is safe to make if GetContext() returns
      * non-null.
      */
   public:
     // If aExceptionHandling == eRethrowContentExceptions then aCompartment
     // needs to be set to the caller's compartment.
-    CallSetup(CallbackObject* aCallback, ErrorResult& aRv,
+    CallSetup(JS::Handle<JSObject*> aCallable, ErrorResult& aRv,
               ExceptionHandling aExceptionHandling,
               JSCompartment* aCompartment = nullptr);
     ~CallSetup();
 
     JSContext* GetContext() const
     {
       return mCx;
     }
@@ -160,27 +148,27 @@ protected:
     // Members which can go away whenever
     JSContext* mCx;
 
     // Caller's compartment. This will only have a sensible value if
     // mExceptionHandling == eRethrowContentExceptions.
     JSCompartment* mCompartment;
 
     // And now members whose construction/destruction order we need to control.
-    Maybe<AutoEntryScript> mAutoEntryScript;
-    Maybe<AutoIncumbentScript> mAutoIncumbentScript;
+
+    nsCxPusher mCxPusher;
 
     // Constructed the rooter within the scope of mCxPusher above, so that it's
     // always within a request during its lifetime.
     Maybe<JS::Rooted<JSObject*> > mRootedCallable;
 
     // Can't construct a JSAutoCompartment without a JSContext either.  Also,
-    // Put mAc after mAutoEntryScript so that we exit the compartment before
-    // we pop the JSContext. Though in practice we'll often manually order
-    // those two things.
+    // Put mAc after mCxPusher so that we exit the compartment before we pop the
+    // JSContext.  Though in practice we'll often manually order those two
+    // things.
     Maybe<JSAutoCompartment> mAc;
 
     // An ErrorResult to possibly re-throw exceptions on and whether
     // we should re-throw them.
     ErrorResult& mErrorResult;
     const ExceptionHandling mExceptionHandling;
     JS::ContextOptions mSavedJSContextOptions;
     const bool mIsMainThread;
@@ -344,17 +332,38 @@ public:
 
   // Try to return a WebIDLCallbackT version of this object.
   already_AddRefed<WebIDLCallbackT> ToWebIDLCallback() const
   {
     if (HasWebIDLCallback()) {
       nsRefPtr<WebIDLCallbackT> callback = GetWebIDLCallback();
       return callback.forget();
     }
-    return nullptr;
+
+    XPCOMCallbackT* callback = GetXPCOMCallback();
+    if (!callback) {
+      return nullptr;
+    }
+
+    nsCOMPtr<nsIXPConnectWrappedJS> wrappedJS = do_QueryInterface(callback);
+    if (!wrappedJS) {
+      return nullptr;
+    }
+
+    AutoSafeJSContext cx;
+
+    JS::Rooted<JSObject*> obj(cx, wrappedJS->GetJSObject());
+    if (!obj) {
+      return nullptr;
+    }
+
+    JSAutoCompartment ac(cx, obj);
+
+    nsRefPtr<WebIDLCallbackT> newCallback = new WebIDLCallbackT(obj);
+    return newCallback.forget();
   }
 
 private:
   static const uintptr_t XPCOMCallbackFlag = 1u;
 
   friend void
   ImplCycleCollectionUnlink<WebIDLCallbackT,
                             XPCOMCallbackT>(CallbackObjectHolder& aField);
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -3338,17 +3338,17 @@ for (uint32_t i = 0; i < length; ++i) {
 
         if descriptor.interface.isCallback():
             name = descriptor.interface.identifier.name
             if type.nullable() or isCallbackReturnValue:
                 declType = CGGeneric("nsRefPtr<%s>" % name);
             else:
                 declType = CGGeneric("OwningNonNull<%s>" % name)
             conversion = (
-                "${declName} = new %s(&${val}.toObject(), mozilla::dom::GetIncumbentGlobal());\n" % name)
+                "${declName} = new %s(&${val}.toObject());\n" % name)
 
             template = wrapObjectTemplate(conversion, type,
                                           "${declName} = nullptr",
                                           failureCode)
             return JSToNativeConversionInfo(template, declType=declType,
                                             dealWithOptional=isOptional)
 
         # This is an interface that we implement as a concrete class
@@ -3671,17 +3671,17 @@ for (uint32_t i = 0; i < length; ++i) {
         assert not type.treatNonCallableAsNull() or type.nullable()
 
         name = type.unroll().identifier.name
         if type.nullable():
             declType = CGGeneric("nsRefPtr<%s>" % name);
         else:
             declType = CGGeneric("OwningNonNull<%s>" % name)
         conversion = (
-            "  ${declName} = new %s(&${val}.toObject(), mozilla::dom::GetIncumbentGlobal());\n" % name)
+            "  ${declName} = new %s(&${val}.toObject());\n" % name)
 
         if allowTreatNonCallableAsNull and type.treatNonCallableAsNull():
             haveCallable = "JS_ObjectIsCallable(cx, &${val}.toObject())"
             if not isDefinitelyObject:
                 haveCallable = "${val}.isObject() && " + haveCallable
             if defaultValue is not None:
                 assert(isinstance(defaultValue, IDLNullValue))
                 haveCallable = "${haveValue} && " + haveCallable
@@ -10416,17 +10416,17 @@ class CGJSImplClass(CGBindingImplClass):
         if descriptor.interface.hasChildInterfaces():
             decorators = ""
             # We need a public virtual destructor our subclasses can use
             destructor = ClassDestructor(virtual=True, visibility="public")
         else:
             decorators = "MOZ_FINAL"
             destructor = None
 
-        baseConstructors=["mImpl(new %s(aJSImplObject, /* aIncumbentGlobal = */ nullptr))" % jsImplName(descriptor.name),
+        baseConstructors=["mImpl(new %s(aJSImplObject))" % jsImplName(descriptor.name),
                           "mParent(aParent)"]
         parentInterface = descriptor.interface.parent
         while parentInterface:
             if parentInterface.isJSImplemented():
                 baseConstructors.insert(
                     0, "%s(aJSImplObject, aParent)" % parentClass )
                 break
             parentInterface = parentInterface.parent
@@ -10543,22 +10543,22 @@ class CGCallback(CGClass):
                 realMethods.extend(self.getMethodImpls(method))
         CGClass.__init__(self, name,
                          bases=[ClassBase(baseName)],
                          constructors=self.getConstructors(),
                          methods=realMethods+getters+setters)
 
     def getConstructors(self):
         return [ClassConstructor(
-            [Argument("JSObject*", "aCallback"), Argument("nsIGlobalObject*", "aIncumbentGlobal")],
+            [Argument("JSObject*", "aCallback")],
             bodyInHeader=True,
             visibility="public",
             explicit=True,
             baseConstructors=[
-                "%s(aCallback, aIncumbentGlobal)" % self.baseName,
+                "%s(aCallback)" % self.baseName
                 ])]
 
     def getMethodImpls(self, method):
         assert method.needThisHandling
         args = list(method.args)
         # Strip out the JSContext*/JSObject* args
         # that got added.
         assert args[0].name == "cx" and args[0].argType == "JSContext*"
@@ -10573,17 +10573,17 @@ class CGCallback(CGClass):
         # method, insert our optional argument for deciding whether the
         # CallSetup should re-throw exceptions on aRv.
         args.append(Argument("ExceptionHandling", "aExceptionHandling",
                              "eReportExceptions"))
         # And now insert our template argument.
         argsWithoutThis = list(args)
         args.insert(0, Argument("const T&",  "thisObj"))
 
-        setupCall = ("CallSetup s(this, aRv, aExceptionHandling);\n"
+        setupCall = ("CallSetup s(CallbackPreserveColor(), aRv, aExceptionHandling);\n"
                      "if (!s.GetContext()) {\n"
                      "  aRv.Throw(NS_ERROR_UNEXPECTED);\n"
                      "  return${errorReturn};\n"
                      "}\n")
 
         bodyWithThis = string.Template(
             setupCall+
             "JS::Rooted<JSObject*> thisObjJS(s.GetContext(),\n"
@@ -10863,17 +10863,17 @@ class CallbackMember(CGNativeMember):
         # well as a JSContext.
         return [Argument("JSContext*", "cx"),
                 Argument("JS::Handle<JSObject*>", "aThisObj")] + args
 
     def getCallSetup(self):
         if self.needThisHandling:
             # It's been done for us already
             return ""
-        callSetup = "CallSetup s(this, aRv"
+        callSetup = "CallSetup s(CallbackPreserveColor(), aRv"
         if self.rethrowContentException:
             # getArgs doesn't add the aExceptionHandling argument but does add
             # aCompartment for us.
             callSetup += ", eRethrowContentExceptions, aCompartment"
         else:
             callSetup += ", aExceptionHandling"
         callSetup += ");"
         return string.Template(
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -2487,17 +2487,16 @@ NS_IMPL_CYCLE_COLLECTION_INHERITED_1(Tab
                                      mMessageManager)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TabChildGlobal)
   NS_INTERFACE_MAP_ENTRY(nsIMessageListenerManager)
   NS_INTERFACE_MAP_ENTRY(nsIMessageSender)
   NS_INTERFACE_MAP_ENTRY(nsISyncMessageSender)
   NS_INTERFACE_MAP_ENTRY(nsIContentFrameMessageManager)
   NS_INTERFACE_MAP_ENTRY(nsIScriptObjectPrincipal)
-  NS_INTERFACE_MAP_ENTRY(nsIGlobalObject)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(ContentFrameMessageManager)
 NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
 
 NS_IMPL_ADDREF_INHERITED(TabChildGlobal, nsDOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(TabChildGlobal, nsDOMEventTargetHelper)
 
 /* [notxpcom] boolean markForCC (); */
 // This method isn't automatically forwarded safely because it's notxpcom, so
@@ -2552,25 +2551,15 @@ TabChildGlobal::Atob(const nsAString& aA
 }
 
 JSContext*
 TabChildGlobal::GetJSContextForEventHandlers()
 {
   return nsContentUtils::GetSafeJSContext();
 }
 
-nsIPrincipal*
+nsIPrincipal* 
 TabChildGlobal::GetPrincipal()
 {
   if (!mTabChild)
     return nullptr;
   return mTabChild->GetPrincipal();
 }
-
-JSObject*
-TabChildGlobal::GetGlobalJSObject()
-{
-  NS_ENSURE_TRUE(mTabChild, nullptr);
-  nsCOMPtr<nsIXPConnectJSObjectHolder> ref = mTabChild->GetGlobal();
-  NS_ENSURE_TRUE(ref, nullptr);
-  return ref->GetJSObject();
-}
-
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -46,18 +46,17 @@ class RenderFrameChild;
 namespace dom {
 
 class TabChild;
 class PContentDialogChild;
 class ClonedMessageData;
 
 class TabChildGlobal : public nsDOMEventTargetHelper,
                        public nsIContentFrameMessageManager,
-                       public nsIScriptObjectPrincipal,
-                       public nsIGlobalObject
+                       public nsIScriptObjectPrincipal
 {
 public:
   TabChildGlobal(TabChild* aTabChild);
   void Init();
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(TabChildGlobal, nsDOMEventTargetHelper)
   NS_FORWARD_SAFE_NSIMESSAGELISTENERMANAGER(mMessageManager)
   NS_FORWARD_SAFE_NSIMESSAGESENDER(mMessageManager)
@@ -123,17 +122,16 @@ public:
   PreHandleEvent(nsEventChainPreVisitor& aVisitor)
   {
     aVisitor.mForceContentDispatch = true;
     return NS_OK;
   }
 
   virtual JSContext* GetJSContextForEventHandlers() MOZ_OVERRIDE;
   virtual nsIPrincipal* GetPrincipal() MOZ_OVERRIDE;
-  virtual JSObject* GetGlobalJSObject() MOZ_OVERRIDE;
 
   nsCOMPtr<nsIContentFrameMessageManager> mMessageManager;
   TabChild* mTabChild;
 };
 
 class ContentListener MOZ_FINAL : public nsIDOMEventListener
 {
 public:
--- a/dom/src/geolocation/nsGeolocation.cpp
+++ b/dom/src/geolocation/nsGeolocation.cpp
@@ -10,16 +10,17 @@
 #include "nsISettingsService.h"
 
 #include "nsGeolocation.h"
 #include "nsDOMClassInfoID.h"
 #include "nsComponentManagerUtils.h"
 #include "nsServiceManagerUtils.h"
 #include "nsContentUtils.h"
 #include "nsContentPermissionHelper.h"
+#include "nsCxPusher.h"
 #include "nsIDocument.h"
 #include "nsIObserverService.h"
 #include "nsPIDOMWindow.h"
 #include "nsThreadUtils.h"
 #include "mozilla/Services.h"
 #include "mozilla/unused.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/ClearOnShutdown.h"
@@ -289,16 +290,20 @@ JSObject*
 PositionError::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
 {
   return PositionErrorBinding::Wrap(aCx, aScope, this);
 }
 
 void
 PositionError::NotifyCallback(const GeoPositionErrorCallback& aCallback)
 {
+  // Ensure that the proper context is on the stack (bug 452762)
+  nsCxPusher pusher;
+  pusher.PushNull();
+
   nsAutoMicroTask mt;
   if (aCallback.HasWebIDLCallback()) {
     PositionErrorCallback* callback = aCallback.GetWebIDLCallback();
 
     if (callback) {
       ErrorResult err;
       callback->Call(*this, err);
     }
@@ -514,16 +519,19 @@ nsGeolocationRequest::SendLocation(nsIDO
 
   mLocator->SetCachedPosition(wrapped);
   if (!mIsWatchPositionRequest) {
     // Cancel timer and position updates in case the position
     // callback spins the event loop
     Shutdown();
   }
 
+  // Ensure that the proper context is on the stack (bug 452762)
+  nsCxPusher pusher;
+  pusher.PushNull();
   nsAutoMicroTask mt;
   if (mCallback.HasWebIDLCallback()) {
     ErrorResult err;
     PositionCallback* callback = mCallback.GetWebIDLCallback();
 
     MOZ_ASSERT(callback);
     callback->Call(*wrapped, err);
   } else {
--- a/js/jsd/jsd_xpc.cpp
+++ b/js/jsd/jsd_xpc.cpp
@@ -31,21 +31,20 @@
 
 /* XXX DOM dependency */
 #include "nsIScriptContext.h"
 #include "nsPIDOMWindow.h"
 #include "nsDOMJSUtils.h"
 #include "SandboxPrivate.h"
 #include "nsJSPrincipals.h"
 #include "nsContentUtils.h"
-#include "mozilla/dom/ScriptSettings.h"
+#include "nsCxPusher.h"
 
 using mozilla::AutoSafeJSContext;
 using mozilla::AutoPushJSContext;
-using mozilla::dom::AutoSystemCaller;
 
 /*
  * defining CAUTIOUS_SCRIPTHOOK makes jsds disable GC while calling out to the
  * script hook.  This was a hack to avoid some js engine problems that should
  * be fixed now (see Mozilla bug 77636).
  */
 #undef CAUTIOUS_SCRIPTHOOK
 
@@ -3000,17 +2999,18 @@ jsdService::WrapValue(const JS::Value &v
 
 
 NS_IMETHODIMP
 jsdService::EnterNestedEventLoop (jsdINestCallback *callback, uint32_t *_rval)
 {
     // Nesting event queues is a thing of the past.  Now, we just spin the
     // current event loop.
     nsresult rv = NS_OK;
-    AutoSystemCaller asc;
+    nsCxPusher pusher;
+    pusher.PushNull();
     uint32_t nestLevel = ++mNestedLoopLevel;
     nsCOMPtr<nsIThread> thread = do_GetCurrentThread();
 
     if (callback) {
         DoPause(nullptr, true);
         rv = callback->OnNest();
         DoUnPause(nullptr, true);
     }
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -6093,54 +6093,22 @@ JS_DescribeScriptedCaller(JSContext *cx,
     script.set(nullptr);
     if (lineno)
         *lineno = 0;
 
     NonBuiltinScriptFrameIter i(cx);
     if (i.done())
         return false;
 
-    // If the caller is hidden, the embedding wants us to return null here so
-    // that it can check its own stack.
-    if (i.activation()->scriptedCallerIsHidden())
-        return false;
-
     script.set(i.script());
     if (lineno)
         *lineno = js::PCToLineNumber(i.script(), i.pc());
     return true;
 }
 
-namespace JS {
-
-JS_PUBLIC_API(void)
-HideScriptedCaller(JSContext *cx)
-{
-    MOZ_ASSERT(cx);
-
-    // If there's no accessible activation on the stack, we'll return null from
-    // JS_DescribeScriptedCaller anyway, so there's no need to annotate
-    // anything.
-    Activation *act = cx->runtime()->mainThread.activation();
-    if (!act)
-        return;
-    act->hideScriptedCaller();
-}
-
-JS_PUBLIC_API(void)
-UnhideScriptedCaller(JSContext *cx)
-{
-    Activation *act = cx->runtime()->mainThread.activation();
-    if (!act)
-        return;
-    act->unhideScriptedCaller();
-}
-
-} /* namespace JS */
-
 #ifdef JS_THREADSAFE
 static PRStatus
 CallOnce(void *func)
 {
     JSInitCallback init = JS_DATA_TO_FUNC_PTR(JSInitCallback, func);
     return init() ? PR_SUCCESS : PR_FAILURE;
 }
 #endif
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -4571,63 +4571,20 @@ JS_CharsToId(JSContext* cx, JS::TwoByteC
  *  Test if the given string is a valid ECMAScript identifier
  */
 extern JS_PUBLIC_API(bool)
 JS_IsIdentifier(JSContext *cx, JS::HandleString str, bool *isIdentifier);
 
 /*
  * Return the current script and line number of the most currently running
  * frame. Returns true if a scripted frame was found, false otherwise.
- *
- * If a the embedding has hidden the scripted caller for the topmost activation
- * record, this will also return false.
  */
 extern JS_PUBLIC_API(bool)
 JS_DescribeScriptedCaller(JSContext *cx, JS::MutableHandleScript script, unsigned *lineno);
 
-namespace JS {
-
-/*
- * Informs the JS engine that the scripted caller should be hidden. This can be
- * used by the embedding to maintain an override of the scripted caller in its
- * calculations, by hiding the scripted caller in the JS engine and pushing data
- * onto a separate stack, which it inspects when JS_DescribeScriptedCaller
- * returns null.
- *
- * We maintain a counter on each activation record. Add() increments the counter
- * of the topmost activation, and Remove() decrements it. The count may never
- * drop below zero, and must always be exactly zero when the activation is
- * popped from the stack.
- */
-extern JS_PUBLIC_API(void)
-HideScriptedCaller(JSContext *cx);
-
-extern JS_PUBLIC_API(void)
-UnhideScriptedCaller(JSContext *cx);
-
-class AutoHideScriptedCaller
-{
-  public:
-    AutoHideScriptedCaller(JSContext *cx
-                           MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
-      : mContext(cx)
-    {
-        MOZ_GUARD_OBJECT_NOTIFIER_INIT;
-        HideScriptedCaller(mContext);
-    }
-    ~AutoHideScriptedCaller() {
-        UnhideScriptedCaller(mContext);
-    }
-
-  protected:
-    JSContext *mContext;
-    MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
-};
-
-} /* namepsace JS */
 
 /*
  * Encode/Decode interpreted scripts and functions to/from memory.
  */
 
 extern JS_PUBLIC_API(void *)
 JS_EncodeScript(JSContext *cx, JS::HandleScript script, uint32_t *lengthp);
 
--- a/js/src/vm/Stack-inl.h
+++ b/js/src/vm/Stack-inl.h
@@ -828,26 +828,24 @@ AbstractFramePtr::popWith(JSContext *cx)
         MOZ_ASSUME_UNREACHABLE("Invalid frame");
 }
 
 Activation::Activation(JSContext *cx, Kind kind)
   : cx_(cx),
     compartment_(cx->compartment()),
     prev_(cx->mainThread().activation_),
     savedFrameChain_(0),
-    hideScriptedCallerCount_(0),
     kind_(kind)
 {
     cx->mainThread().activation_ = this;
 }
 
 Activation::~Activation()
 {
     JS_ASSERT(cx_->mainThread().activation_ == this);
-    JS_ASSERT(hideScriptedCallerCount_ == 0);
     cx_->mainThread().activation_ = prev_;
 }
 
 InterpreterActivation::InterpreterActivation(RunState &state, JSContext *cx, StackFrame *entryFrame)
   : Activation(cx, Interpreter),
     state_(state),
     entryFrame_(entryFrame),
     opMask_(0)
--- a/js/src/vm/Stack.h
+++ b/js/src/vm/Stack.h
@@ -1162,23 +1162,16 @@ class Activation
     Activation *prev_;
 
     // Counter incremented by JS_SaveFrameChain on the top-most activation and
     // decremented by JS_RestoreFrameChain. If > 0, ScriptFrameIter should stop
     // iterating when it reaches this activation (if GO_THROUGH_SAVED is not
     // set).
     size_t savedFrameChain_;
 
-    // Counter incremented by JS::HideScriptedCaller and decremented by
-    // JS::UnhideScriptedCaller. If > 0 for the top activation,
-    // JS_DescribeScriptedCaller will return null instead of querying that
-    // activation, which should prompt the caller to consult embedding-specific
-    // data structures instead.
-    size_t hideScriptedCallerCount_;
-
     enum Kind { Interpreter, Jit, ForkJoin };
     Kind kind_;
 
     inline Activation(JSContext *cx, Kind kind_);
     inline ~Activation();
 
   public:
     JSContext *cx() const {
@@ -1220,27 +1213,16 @@ class Activation
     void restoreFrameChain() {
         JS_ASSERT(savedFrameChain_ > 0);
         savedFrameChain_--;
     }
     bool hasSavedFrameChain() const {
         return savedFrameChain_ > 0;
     }
 
-    void hideScriptedCaller() {
-        hideScriptedCallerCount_++;
-    }
-    void unhideScriptedCaller() {
-        JS_ASSERT(hideScriptedCallerCount_ > 0);
-        hideScriptedCallerCount_--;
-    }
-    bool scriptedCallerIsHidden() const {
-        return hideScriptedCallerCount_ > 0;
-    }
-
   private:
     Activation(const Activation &other) MOZ_DELETE;
     void operator=(const Activation &other) MOZ_DELETE;
 };
 
 // This variable holds a special opcode value which is greater than all normal
 // opcodes, and is chosen such that the bitwise or of this value with any
 // opcode is this value.
--- a/js/xpconnect/idl/xpccomponents.idl
+++ b/js/xpconnect/idl/xpccomponents.idl
@@ -115,17 +115,17 @@ interface nsIXPCComponents_utils_Sandbox
 interface ScheduledGCCallback : nsISupports
 {
     void callback();
 };
 
 /**
 * interface of Components.utils
 */
-[scriptable, uuid(e14f588b-63aa-4091-be82-a459a52f8ca6)]
+[scriptable, uuid(ef621cac-c818-464a-9fb1-9a35731a7f32)]
 interface nsIXPCComponents_Utils : nsISupports
 {
 
     /* reportError is designed to be called from JavaScript only.
      *
      * It will report a JS Error object to the JS console, and return. It
      * is meant for use in exception handler blocks which want to "eat"
      * an exception, but still want to report it to the console.
@@ -503,27 +503,16 @@ interface nsIXPCComponents_Utils : nsISu
 
     /**
      * Get a DOM classinfo for the given classname.  Only some class
      * names are supported.
      */
     nsIClassInfo getDOMClassInfo(in AString aClassName);
 
     /**
-     * Gets the incument global for the execution of this function. For internal
-     * and testing use only.
-     *
-     * If |callback| is passed, it is invoked with the incumbent global as its
-     * sole argument. This allows the incumbent global to be measured in callback
-     * environments with no scripted frames on the stack.
-     */
-    [implicit_jscontext]
-    jsval getIncumbentGlobal([optional] in jsval callback);
-
-    /**
       * Retrieve the last time, in microseconds since epoch, that a given
       * watchdog-related event occured.
       *
       * Valid categories:
       *   "RuntimeStateChange"      - Runtime switching between active and inactive states
       *   "WatchdogWakeup"          - Watchdog waking up from sleeping
       *   "WatchdogHibernateStart"  - Watchdog begins hibernating
       *   "WatchdogHibernateStop"   - Watchdog stops hibernating
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -3483,43 +3483,16 @@ NS_IMETHODIMP
 nsXPCComponents_Utils::GetDOMClassInfo(const nsAString& aClassName,
                                        nsIClassInfo** aClassInfo)
 {
     *aClassInfo = nullptr;
     return NS_ERROR_NOT_AVAILABLE;
 }
 
 NS_IMETHODIMP
-nsXPCComponents_Utils::GetIncumbentGlobal(const Value &aCallback,
-                                          JSContext *aCx, Value *aOut)
-{
-    nsCOMPtr<nsIGlobalObject> global = mozilla::dom::GetIncumbentGlobal();
-    RootedValue globalVal(aCx);
-
-    if (!global) {
-        globalVal = NullValue();
-    } else {
-        // Note: We rely on the wrap call for outerization.
-        globalVal = ObjectValue(*global->GetGlobalJSObject());
-        if (!JS_WrapValue(aCx, &globalVal))
-            return NS_ERROR_FAILURE;
-    }
-
-    // Invoke the callback, if passed.
-    if (aCallback.isObject()) {
-        Value ignored;
-        if (!JS_CallFunctionValue(aCx, nullptr, aCallback, 1, globalVal.address(), &ignored))
-            return NS_ERROR_FAILURE;
-    }
-
-    *aOut = globalVal;
-    return NS_OK;
-}
-
-NS_IMETHODIMP
 nsXPCComponents_Utils::GetWatchdogTimestamp(const nsAString& aCategory, PRTime *aOut)
 {
     WatchdogTimestampCategory category;
     if (aCategory.EqualsLiteral("RuntimeStateChange"))
         category = TimestampRuntimeStateChange;
     else if (aCategory.EqualsLiteral("WatchdogWakeup"))
         category = TimestampWatchdogWakeup;
     else if (aCategory.EqualsLiteral("WatchdogHibernateStart"))
--- a/js/xpconnect/tests/chrome/chrome.ini
+++ b/js/xpconnect/tests/chrome/chrome.ini
@@ -62,17 +62,16 @@ support-files =
 [test_expandosharing.xul]
 [test_exposeInDerived.xul]
 [test_getweakmapkeys.xul]
 [test_mozMatchesSelector.xul]
 [test_nodelists.xul]
 [test_paris_weakmap_keys.xul]
 [test_precisegc.xul]
 [test_sandboxImport.xul]
-[test_scriptSettings.xul]
 [test_weakmap_keys_preserved.xul]
 [test_weakmap_keys_preserved2.xul]
 [test_weakref.xul]
 [test_wrappers.xul]
 [test_weakmaps.xul]
 skip-if = os == "win" # Bug 820471
 [test_wrappers-2.xul]
 # Disabled until this test gets updated to test the new proxy based wrappers.
deleted file mode 100644
--- a/js/xpconnect/tests/chrome/test_scriptSettings.xul
+++ /dev/null
@@ -1,125 +0,0 @@
-<?xml version="1.0"?>
-<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
-<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=937317
--->
-<window title="Mozilla Bug 937317"
-        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
-
-  <!-- test results are displayed in the html:body -->
-  <body xmlns="http://www.w3.org/1999/xhtml">
-  <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=937317"
-     target="_blank">Mozilla Bug 937317</a>
-  </body>
-
-  <!-- test code goes here -->
-  <iframe></iframe>
-  <script type="application/javascript">
-  <![CDATA[
-
-  /** Test for the script settings stack. **/
-  SimpleTest.waitForExplicitFinish();
-  const Cu = Components.utils;
-  Cu.import("resource://gre/modules/Promise.jsm");
-  var iwin = window[0];
-
-  // Smoketest.
-  is(Cu.getIncumbentGlobal(), window, "smoketest");
-
-  // Calling a cross-compartment non-scripted function changes the
-  // compartment, but not the incumbent script settings object.
-  var sb = new Cu.Sandbox(window, { wantComponents: true });
-  is(sb.Components.utils.getIncumbentGlobal(), window, "cross-compartment sb non-scripted");
-  is(iwin.Components.utils.getIncumbentGlobal(), window, "cross-compartment win non-scripted");
-
-  // If we call a scripted function in the other compartment, that becomes
-  // the incumbent script.
-  function gib() { return Components.utils.getIncumbentGlobal(); };
-  Cu.evalInSandbox(gib.toSource(), sb);
-  iwin.eval(gib.toSource());
-  is(sb.gib(), sb, "cross-compartment sb scripted");
-  is(iwin.gib(), iwin, "cross-compartment win scripted");
-
-  // Eval-ing top-level script in another component makes that compartment the
-  // incumbent script.
-  is(Cu.evalInSandbox('Components.utils.getIncumbentGlobal()', sb), sb, 'eval sb');
-  is(iwin.eval('Components.utils.getIncumbentGlobal()'), iwin, 'eval iwin');
-
-  // Make sure that the callback mechanism works.
-  function makeCallback(expectedGlobal, deferred, kind) {
-    function cb(incumbentGlobal) {
-      is(incumbentGlobal, expectedGlobal, "Callback got the right incumbent global: " + kind);
-      if (deferred)
-        deferred.resolve();
-    }
-    info("Generated callback: " + kind);
-    return cb;
-  }
-
-  var bound = Cu.getIncumbentGlobal.bind(Cu, makeCallback(window, undefined, "simple bound"));
-  is(bound(), window, "Bound method returns the right global");
-
-  // Callbacks grab the incumbent script at the time of invocation.
-  //
-  // Note - We avoid calling the initial defer |d| so that it's not in-scope for everything below.
-  let initialDefer = Promise.defer();
-  setTimeout(Cu.getIncumbentGlobal.bind(Cu, makeCallback(window, initialDefer, "same-global setTimeout")), 0);
-  initialDefer.promise.then(function() {
-
-    // Try cross-global setTimeout where |window| is the incumbent script when the callback is created.
-    let d = Promise.defer();
-    iwin.setTimeout(Cu.getIncumbentGlobal.bind(Cu, makeCallback(window, d, "cross-global setTimeout by |window|")), 0);
-    return d.promise;
-  }).then(function() {
-
-    // Try cross-global setTimeout where |iwin| is the incumbent script when the callback is created.
-    let d = Promise.defer();
-    iwin.wrappedJSObject.timeoutFun = Cu.getIncumbentGlobal.bind(Cu, makeCallback(iwin, d, "cross-global setTimeout by |iwin|"));
-    iwin.eval('setTimeout(timeoutFun, 0);');
-    return d.promise;
-  }).then(function() {
-
-    // The incumbent script override doesn't take effect if the callback is scripted.
-    let d = Promise.defer();
-    iwin.wrappedJSObject.timeoutFun2 = Cu.getIncumbentGlobal.bind(Cu, makeCallback(iwin, d, "cross-global setTimeout of scripted function"));
-    iwin.eval('let timeoutFun2Wrapper = function() { timeoutFun2(); }');
-    setTimeout(iwin.wrappedJSObject.timeoutFun2Wrapper, 0);
-    return d.promise;
-  }).then(function() {
-
-    // Try event listeners.
-    let d = Promise.defer();
-    let body = iwin.document.body;
-    body.addEventListener('click', Cu.getIncumbentGlobal.bind(Cu, makeCallback(window, d, "cross-global event listener")));
-    body.dispatchEvent(new iwin.MouseEvent('click'));
-    return d.promise;
-
-  }).then(function() {
-
-    // Try an event handler set by |iwin|.
-    let d = Promise.defer();
-    let body = iwin.document.body;
-    iwin.wrappedJSObject.handler = Cu.getIncumbentGlobal.bind(Cu, makeCallback(iwin, d, "cross-global event handler"));
-    iwin.eval('document.body.onmousemove = handler');
-    body.dispatchEvent(new iwin.MouseEvent('mousemove'));
-    return d.promise;
-
-  }).then(function() {
-
-    // Try an event handler compiled by a content attribute.
-    let d = Promise.defer();
-    let body = iwin.document.body;
-    iwin.wrappedJSObject.innerHandler = Cu.getIncumbentGlobal.bind(Cu, makeCallback(iwin, d, "cross-global compiled event handler"));
-    iwin.eval("document.body.setAttribute('onmouseout', 'innerHandler()')");
-    body.dispatchEvent(new iwin.MouseEvent('mouseout'));
-    return d.promise;
-  }).then(function() {
-
-    SimpleTest.finish();
-  });
-
-  ]]>
-  </script>
-</window>
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -30,16 +30,17 @@
 #include "nsBidiPresUtils.h"
 #include "imgIContainer.h"
 #include "ImageOps.h"
 #include "gfxRect.h"
 #include "gfxContext.h"
 #include "nsRenderingContext.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsCSSRendering.h"
+#include "nsCxPusher.h"
 #include "nsThemeConstants.h"
 #include "nsPIDOMWindow.h"
 #include "nsIDocShell.h"
 #include "nsIWidget.h"
 #include "gfxMatrix.h"
 #include "gfxPoint3D.h"
 #include "gfxTypes.h"
 #include "nsTArray.h"
@@ -4769,16 +4770,22 @@ nsLayoutUtils::SurfaceFromElement(nsIIma
   bool wantImageSurface = (aSurfaceFlags & SFE_WANT_IMAGE_SURFACE) != 0;
   bool premultAlpha = (aSurfaceFlags & SFE_NO_PREMULTIPLY_ALPHA) == 0;
 
   if (!premultAlpha) {
     forceCopy = true;
     wantImageSurface = true;
   }
 
+  // Push a null JSContext on the stack so that code that runs within
+  // the below code doesn't think it's being called by JS. See bug
+  // 604262.
+  nsCxPusher pusher;
+  pusher.PushNull();
+
   nsCOMPtr<imgIRequest> imgRequest;
   rv = aElement->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
                             getter_AddRefs(imgRequest));
   if (NS_FAILED(rv) || !imgRequest)
     return result;
 
   uint32_t status;
   imgRequest->GetImageStatus(&status);
--- a/layout/base/nsRefreshDriver.cpp
+++ b/layout/base/nsRefreshDriver.cpp
@@ -32,27 +32,27 @@
 #include "nsLayoutUtils.h"
 #include "nsPresContext.h"
 #include "nsComponentManagerUtils.h"
 #include "prlog.h"
 #include "nsAutoPtr.h"
 #include "nsIDocument.h"
 #include "jsapi.h"
 #include "nsContentUtils.h"
+#include "nsCxPusher.h"
 #include "mozilla/Preferences.h"
 #include "nsViewManager.h"
 #include "GeckoProfiler.h"
 #include "nsNPAPIPluginInstance.h"
 #include "nsPerformance.h"
 #include "mozilla/dom/WindowBinding.h"
 #include "RestyleManager.h"
 #include "Layers.h"
 #include "imgIContainer.h"
 #include "nsIFrameRequestCallback.h"
-#include "mozilla/dom/ScriptSettings.h"
 
 using namespace mozilla;
 using namespace mozilla::widget;
 
 #ifdef PR_LOGGING
 static PRLogModuleInfo *gLog = nullptr;
 #define LOG(...) PR_LOG(gLog, PR_LOG_NOTICE, (__VA_ARGS__))
 #else
@@ -717,17 +717,18 @@ nsRefreshDriver::AdvanceTimeAndRefresh(i
     mMostRecentRefresh = TimeStamp::Now();
 
     mTestControllingRefreshes = true;
   }
 
   mMostRecentRefreshEpochTime += aMilliseconds * 1000;
   mMostRecentRefresh += TimeDuration::FromMilliseconds((double) aMilliseconds);
 
-  mozilla::dom::AutoSystemCaller asc;
+  nsCxPusher pusher;
+  pusher.PushNull();
   DoTick();
 }
 
 void
 nsRefreshDriver::RestoreNormalRefresh()
 {
   mTestControllingRefreshes = false;
   EnsureTimerStarted(false);
--- a/layout/forms/nsTextControlFrame.cpp
+++ b/layout/forms/nsTextControlFrame.cpp
@@ -37,19 +37,19 @@
 #include "nsIDOMText.h" //for multiline getselection
 #include "nsFocusManager.h"
 #include "nsTextEditRules.h"
 #include "nsPresState.h"
 #include "nsContentList.h"
 #include "nsAttrValueInlines.h"
 #include "mozilla/Selection.h"
 #include "nsContentUtils.h"
+#include "nsCxPusher.h"
 #include "nsTextNode.h"
 #include "nsStyleSet.h"
-#include "mozilla/dom/ScriptSettings.h"
 
 #define DEFAULT_COLUMN_WIDTH 20
 
 using namespace mozilla;
 
 nsIFrame*
 NS_NewTextControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
@@ -269,17 +269,18 @@ nsTextControlFrame::EnsureEditorInitiali
 
   // Make sure that editor init doesn't do things that would kill us off
   // (especially off the script blockers it'll create for its DOM mutations).
   {
     nsAutoScriptBlocker scriptBlocker;
 
     // Time to mess with our security context... See comments in GetValue()
     // for why this is needed.
-    mozilla::dom::AutoSystemCaller asc;
+    nsCxPusher pusher;
+    pusher.PushNull();
 
     // Make sure that we try to focus the content even if the method fails
     class EnsureSetFocus {
     public:
       explicit EnsureSetFocus(nsTextControlFrame* aFrame)
         : mFrame(aFrame) {}
       ~EnsureSetFocus() {
         if (nsContentUtils::IsFocusedContent(mFrame->GetContent()))
--- a/layout/generic/nsVideoFrame.cpp
+++ b/layout/generic/nsVideoFrame.cpp
@@ -18,16 +18,17 @@
 #include "nsGenericHTMLElement.h"
 #include "nsPresContext.h"
 #include "nsContentCreatorFunctions.h"
 #include "nsBoxLayoutState.h"
 #include "nsBoxFrame.h"
 #include "nsImageFrame.h"
 #include "nsIImageLoadingContent.h"
 #include "nsContentUtils.h"
+#include "nsCxPusher.h"
 #include "ImageContainer.h"
 #include "ImageLayers.h"
 #include "nsContentList.h"
 #include <algorithm>
 
 using namespace mozilla;
 using namespace mozilla::layers;
 using namespace mozilla::dom;
@@ -69,16 +70,22 @@ nsVideoFrame::CreateAnonymousContent(nsT
                                             nullptr,
                                             kNameSpaceID_XHTML,
                                             nsIDOMNode::ELEMENT_NODE);
     NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
     element = NS_NewHTMLImageElement(nodeInfo.forget());
     mPosterImage = element;
     NS_ENSURE_TRUE(mPosterImage, NS_ERROR_OUT_OF_MEMORY);
 
+    // Push a null JSContext on the stack so that code that runs
+    // within the below code doesn't think it's being called by
+    // JS. See bug 604262.
+    nsCxPusher pusher;
+    pusher.PushNull();
+
     // Set the nsImageLoadingContent::ImageState() to 0. This means that the
     // image will always report its state as 0, so it will never be reframed
     // to show frames for loading or the broken image icon. This is important,
     // as the image is native anonymous, and so can't be reframed (currently).
     nsCOMPtr<nsIImageLoadingContent> imgContent = do_QueryInterface(mPosterImage);
     NS_ENSURE_TRUE(imgContent, NS_ERROR_FAILURE);
 
     imgContent->ForceImageState(true, 0);
--- a/mfbt/ThreadLocal.h
+++ b/mfbt/ThreadLocal.h
@@ -49,20 +49,17 @@ typedef sig_atomic_t sig_safe_t;
  *
  * Only static-storage-duration (e.g. global variables, or static class members)
  * objects of this class should be instantiated. This class relies on
  * zero-initialization, which is implicit for static-storage-duration objects.
  * It doesn't have a custom default constructor, to avoid static initializers.
  *
  * API usage:
  *
- * // Create a TLS item.
- * //
- * // Note that init() should be invoked exactly once, before any usage of set()
- * // or get().
+ * // Create a TLS item
  * mozilla::ThreadLocal<int> tlsKey;
  * if (!tlsKey.init()) {
  *   // deal with the error
  * }
  *
  * // Set the TLS value
  * tlsKey.set(123);
  *
--- a/security/manager/pki/src/nsNSSDialogHelper.cpp
+++ b/security/manager/pki/src/nsNSSDialogHelper.cpp
@@ -3,20 +3,20 @@
  * 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 "nsNSSDialogHelper.h"
 #include "nsIWindowWatcher.h"
 #include "nsCOMPtr.h"
 #include "nsIComponentManager.h"
+#include "nsCxPusher.h"
 #include "nsIServiceManager.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIInterfaceRequestorUtils.h"
-#include "mozilla/dom/ScriptSettings.h"
 
 static const char kOpenDialogParam[] = "centerscreen,chrome,modal,titlebar";
 static const char kOpenWindowParam[] = "centerscreen,chrome,titlebar";
 
 nsresult
 nsNSSDialogHelper::openDialog(
     nsIDOMWindow *window,
     const char *url,
@@ -34,17 +34,18 @@ nsNSSDialogHelper::openDialog(
     windowWatcher->GetActiveWindow(getter_AddRefs(parent));
   }
 
   // We're loading XUL into this window, and it's happening on behalf of the
   // system, not on behalf of content. Make sure the initial about:blank window
   // gets a system principal, otherwise we'll bork when trying to wrap the
   // nsIKeyGenThread |arguments| property into the unprivileged scoope.
   MOZ_ASSERT(!strncmp("chrome://", url, strlen("chrome://")));
-  mozilla::dom::AutoSystemCaller asc;
+  nsCxPusher pusher;
+  pusher.PushNull();
 
   nsCOMPtr<nsIDOMWindow> newWindow;
   rv = windowWatcher->OpenWindow(parent,
                                  url,
                                  "_blank",
                                  modal
                                  ? kOpenDialogParam
                                  : kOpenWindowParam,
--- a/toolkit/devtools/server/nsJSInspector.cpp
+++ b/toolkit/devtools/server/nsJSInspector.cpp
@@ -1,21 +1,21 @@
 /* -*-  Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
 /* 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 "nsJSInspector.h"
 #include "nsIXPConnect.h"
 #include "nsThreadUtils.h"
+#include "nsCxPusher.h"
 #include "jsfriendapi.h"
 #include "js/OldDebugAPI.h"
 #include "mozilla/HoldDropJSObjects.h"
 #include "mozilla/ModuleUtils.h"
-#include "mozilla/dom/ScriptSettings.h"
 #include "nsServiceManagerUtils.h"
 #include "nsMemory.h"
 #include "nsArray.h"
 #include "nsTArray.h"
 
 #define JSINSPECTOR_CONTRACTID \
   "@mozilla.org/jsinspector;1"
 
@@ -68,17 +68,18 @@ NS_IMETHODIMP
 nsJSInspector::EnterNestedEventLoop(const JS::Value& requestor, uint32_t *out)
 {
   nsresult rv = NS_OK;
 
   mLastRequestor = requestor;
   mRequestors.AppendElement(requestor);
   mozilla::HoldJSObjects(this);
 
-  mozilla::dom::AutoSystemCaller asc;
+  nsCxPusher pusher;
+  pusher.PushNull();
 
   uint32_t nestLevel = ++mNestedLoopLevel;
   while (NS_SUCCEEDED(rv) && mNestedLoopLevel >= nestLevel) {
     if (!NS_ProcessNextEvent())
       rv = NS_ERROR_UNEXPECTED;
   }
 
   NS_ASSERTION(mNestedLoopLevel <= nestLevel,
--- a/xpcom/base/CycleCollectedJSRuntime.cpp
+++ b/xpcom/base/CycleCollectedJSRuntime.cpp
@@ -54,17 +54,16 @@
 // To improve debugging, if WantAllTraces() is true all JS objects are
 // traversed.
 
 #include "mozilla/CycleCollectedJSRuntime.h"
 #include <algorithm>
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/DOMJSClass.h"
-#include "mozilla/dom/ScriptSettings.h"
 #include "jsprf.h"
 #include "nsCycleCollectionNoteRootCallback.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsCycleCollector.h"
 #include "nsDOMJSUtils.h"
 #include "nsIException.h"
 #include "nsThreadUtils.h"
 #include "xpcpublic.h"
@@ -437,18 +436,16 @@ static const JSZoneParticipant sJSZoneCy
 
 CycleCollectedJSRuntime::CycleCollectedJSRuntime(uint32_t aMaxbytes,
                                                  JSUseHelperThreads aUseHelperThreads)
   : mGCThingCycleCollectorGlobal(sGCThingCycleCollectorGlobal),
     mJSZoneCycleCollectorGlobal(sJSZoneCycleCollectorGlobal),
     mJSRuntime(nullptr),
     mJSHolders(512)
 {
-  mozilla::dom::InitScriptSettings();
-
   mJSRuntime = JS_NewRuntime(aMaxbytes, aUseHelperThreads);
   if (!mJSRuntime) {
     MOZ_CRASH();
   }
 
   if (!JS_AddExtraGCRootsTracer(mJSRuntime, TraceBlackJS, this)) {
     MOZ_CRASH();
   }
@@ -468,18 +465,16 @@ CycleCollectedJSRuntime::~CycleCollected
   MOZ_ASSERT(!mDeferredSupports.Length());
 
   // Clear mPendingException first, since it might be cycle collected.
   mPendingException = nullptr;
 
   JS_DestroyRuntime(mJSRuntime);
   mJSRuntime = nullptr;
   nsCycleCollector_forgetJSRuntime();
-
-  mozilla::dom::DestroyScriptSettings();
 }
 
 size_t
 CycleCollectedJSRuntime::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
 {
   size_t n = 0;
 
   // nullptr for the second arg;  we're not measuring anything hanging off the
--- a/xpfe/appshell/src/nsContentTreeOwner.cpp
+++ b/xpfe/appshell/src/nsContentTreeOwner.cpp
@@ -7,16 +7,17 @@
 
 // Local Includes
 #include "nsContentTreeOwner.h"
 #include "nsXULWindow.h"
 
 // Helper Classes
 #include "nsIServiceManager.h"
 #include "nsAutoPtr.h"
+#include "nsCxPusher.h"
 
 // Interfaces needed to be included
 #include "nsIDOMNode.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMNodeList.h"
 #include "nsIDOMWindow.h"
 #include "nsIDOMChromeWindow.h"
 #include "nsIBrowserDOMWindow.h"
@@ -41,17 +42,16 @@
 #include "nsIURI.h"
 #include "nsIDocument.h"
 #if defined(XP_MACOSX)
 #include "nsThreadUtils.h"
 #endif
 
 #include "mozilla/Preferences.h"
 #include "mozilla/dom/Element.h"
-#include "mozilla/dom/ScriptSettings.h"
 
 using namespace mozilla;
 
 //*****************************************************************************
 //*** nsSiteWindow declaration
 //*****************************************************************************
 
 class nsSiteWindow : public nsIEmbeddingSiteWindow
@@ -940,17 +940,18 @@ nsContentTreeOwner::ProvideWindow(nsIDOM
   chromeWin->GetBrowserDOMWindow(getter_AddRefs(browserDOMWin));
   if (!browserDOMWin) {
     return NS_OK;
   }
 
   *aWindowIsNew = (containerPref != nsIBrowserDOMWindow::OPEN_CURRENTWINDOW);
 
   {
-    dom::AutoSystemCaller asc;
+    nsCxPusher pusher;
+    pusher.PushNull();
 
     // Get a new rendering area from the browserDOMWin.  We don't want
     // to be starting any loads here, so get it with a null URI.
     return browserDOMWin->OpenURI(nullptr, aParent, containerPref,
                                   nsIBrowserDOMWindow::OPEN_NEW, aReturn);
   }
 }
 
--- a/xpfe/appshell/src/nsXULWindow.cpp
+++ b/xpfe/appshell/src/nsXULWindow.cpp
@@ -45,29 +45,28 @@
 #include "nsIWindowWatcher.h"
 #include "nsIURI.h"
 #include "nsIDOMCSSStyleDeclaration.h"
 #include "nsAppShellCID.h"
 #include "nsReadableUtils.h"
 #include "nsStyleConsts.h"
 #include "nsPresContext.h"
 #include "nsContentUtils.h"
+#include "nsCxPusher.h"
 #include "nsWebShellWindow.h" // get rid of this one, too...
 #include "nsDOMEvent.h"
 #include "nsGlobalWindow.h"
 
 #include "prenv.h"
 #include "mozilla/AutoRestore.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/dom/BarProps.h"
 #include "mozilla/dom/Element.h"
-#include "mozilla/dom/ScriptSettings.h"
 
 using namespace mozilla;
-using dom::AutoSystemCaller;
 
 #define SIZEMODE_NORMAL     NS_LITERAL_STRING("normal")
 #define SIZEMODE_MAXIMIZED  NS_LITERAL_STRING("maximized")
 #define SIZEMODE_MINIMIZED  NS_LITERAL_STRING("minimized")
 #define SIZEMODE_FULLSCREEN NS_LITERAL_STRING("fullscreen")
 
 #define WINDOWTYPE_ATTRIBUTE NS_LITERAL_STRING("windowtype")
 
@@ -354,17 +353,18 @@ NS_IMETHODIMP nsXULWindow::ShowModal()
   nsCOMPtr<nsIWidget> window = mWindow;
   nsCOMPtr<nsIXULWindow> tempRef = this;  
 
   window->SetModal(true);
   mContinueModalLoop = true;
   EnableParent(false);
 
   {
-    AutoSystemCaller asc;
+    nsCxPusher pusher;
+    pusher.PushNull();
     nsIThread *thread = NS_GetCurrentThread();
     while (mContinueModalLoop) {
       if (!NS_ProcessNextEvent(thread))
         break;
     }
   }
 
   mContinueModalLoop = false;
@@ -1762,36 +1762,38 @@ NS_IMETHODIMP nsXULWindow::CreateNewCont
   nsCOMPtr<nsIIOService> service(do_GetService(NS_IOSERVICE_CONTRACTID));
   if (service) {
     service->NewURI(urlStr, nullptr, nullptr, getter_AddRefs(uri));
   }
   NS_ENSURE_TRUE(uri, NS_ERROR_FAILURE);
 
   // We need to create a chrome window to contain the content window we're about
   // to pass back. The subject principal needs to be system while we're creating
-  // it to make things work right, so force a system caller. See bug 799348
-  // comment 13 for a description of what happens when we don't.
+  // it to make things work right, so push a null cx. See bug 799348 comment 13
+  // for a description of what happens when we don't.
+  nsCxPusher pusher;
+  pusher.PushNull();
   nsCOMPtr<nsIXULWindow> newWindow;
-  {
-    AutoSystemCaller asc;
-    appShell->CreateTopLevelWindow(this, uri,
-                                   aChromeFlags, 615, 480,
-                                   getter_AddRefs(newWindow));
-    NS_ENSURE_TRUE(newWindow, NS_ERROR_FAILURE);
-  }
+  appShell->CreateTopLevelWindow(this, uri,
+                                 aChromeFlags, 615, 480,
+                                 getter_AddRefs(newWindow));
+  NS_ENSURE_TRUE(newWindow, NS_ERROR_FAILURE);
+  pusher.Pop();
 
   // Specify that we want the window to remain locked until the chrome has loaded.
   nsXULWindow *xulWin = static_cast<nsXULWindow*>
                                    (static_cast<nsIXULWindow*>
                                                (newWindow));
 
   xulWin->LockUntilChromeLoad();
 
+  // Push nullptr onto the JSContext stack before we dispatch a native event.
   {
-    AutoSystemCaller asc;
+    nsCxPusher pusher;
+    pusher.PushNull();
     nsIThread *thread = NS_GetCurrentThread();
     while (xulWin->IsLocked()) {
       if (!NS_ProcessNextEvent(thread))
         break;
     }
  }
 
   NS_ENSURE_STATE(xulWin->mPrimaryContentShell);