Merge mozilla-central into holly
authorMike Conley <mconley@mozilla.com>
Sat, 07 Dec 2013 17:00:43 -0500
changeset 168541 806bdab53ee18ba5dd1e86ee002bc7ab0c7a441e
parent 168539 240d9613c9e800ddc525731aadf38140c5dad1a8 (current diff)
parent 168540 b50d803d0ad59c12c1348de0ba63ee6aa451d8eb (diff)
child 168634 1c599e4e665025063bc6219f45bddb64233f1a68
push idunknown
push userunknown
push dateunknown
milestone28.0a1
Merge mozilla-central into holly
CLOBBER
dom/base/ScriptSettings.cpp
dom/base/ScriptSettings.h
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
@@ -9,16 +9,17 @@
 
 #include "nsISettingsService.h"
 
 #include "nsGeolocation.h"
 #include "nsDOMClassInfoID.h"
 #include "nsComponentManagerUtils.h"
 #include "nsServiceManagerUtils.h"
 #include "nsContentUtils.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"
@@ -288,16 +289,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);
     }
@@ -519,16 +524,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);