Bug 887334 - Miscellaneous JSAutoCompartments. r=luke
authorBobby Holley <bobbyholley@gmail.com>
Wed, 17 Jul 2013 11:53:53 -0700
changeset 138960 09a8607459c447424033028eca4c1859af0d4203
parent 138959 fcb33ae736077a7a4f21d4137735746e12af1e3a
child 138961 9ddf00b075162269022d43ad8ccc77a0c371b79e
push id24977
push userryanvm@gmail.com
push dateFri, 19 Jul 2013 00:35:38 +0000
treeherdermozilla-central@0d0263a58f06 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs887334
milestone25.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 887334 - Miscellaneous JSAutoCompartments. r=luke
dom/base/nsGlobalWindow.cpp
dom/base/nsJSEnvironment.cpp
ipc/testshell/TestShellParent.cpp
js/src/shell/js.cpp
netwerk/base/src/ProxyAutoConfig.cpp
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -2075,16 +2075,18 @@ nsGlobalWindow::CreateOuterObject(nsGlob
   js::SetProxyExtra(outer, 0, js::PrivateValue(ToSupports(this)));
 
   return SetOuterObject(cx, outer);
 }
 
 nsresult
 nsGlobalWindow::SetOuterObject(JSContext* aCx, JS::Handle<JSObject*> aOuterObject)
 {
+  JSAutoCompartment ac(aCx, aOuterObject);
+
   // Force our context's global object to be the outer.
   // NB: JS_SetGlobalObject sets aCx->compartment.
   JS_SetGlobalObject(aCx, aOuterObject);
 
   // Set up the prototype for the outer object.
   JSObject* inner = JS_GetParent(aOuterObject);
   JS::Rooted<JSObject*> proto(aCx);
   if (!JS_GetPrototype(aCx, inner, proto.address())) {
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -1317,16 +1317,17 @@ nsJSContext::CompileScript(const PRUnich
   PROFILER_LABEL_PRINTF("JS", "Compile Script", "%s", aURL ? aURL : "");
   NS_ENSURE_TRUE(mIsInitialized, NS_ERROR_NOT_INITIALIZED);
 
   NS_ENSURE_ARG_POINTER(aPrincipal);
 
   AutoPushJSContext cx(mContext);
   JSAutoRequest ar(cx);
   JS::Rooted<JSObject*> scopeObject(mContext, GetNativeGlobal());
+  JSAutoCompartment ac(cx, scopeObject);
   xpc_UnmarkGrayObject(scopeObject);
 
   bool ok = false;
 
   nsresult rv = sSecurityManager->CanExecuteScripts(cx, aPrincipal, &ok);
   if (NS_FAILED(rv)) {
     return NS_ERROR_FAILURE;
   }
@@ -2328,17 +2329,20 @@ bool
 nsJSContext::IsContextInitialized()
 {
   return mIsInitialized;
 }
 
 void
 nsJSContext::ScriptEvaluated(bool aTerminated)
 {
-  JS_MaybeGC(mContext);
+  if (GetNativeGlobal()) {
+    JSAutoCompartment ac(mContext, GetNativeGlobal());
+    JS_MaybeGC(mContext);
+  }
 
   if (aTerminated) {
     mOperationCallbackTime = 0;
     mModalStateTime = 0;
     mActive = true;
   }
 }
 
--- a/ipc/testshell/TestShellParent.cpp
+++ b/ipc/testshell/TestShellParent.cpp
@@ -56,21 +56,19 @@ TestShellCommandParent::SetCallback(JSCo
 }
 
 JSBool
 TestShellCommandParent::RunCallback(const nsString& aResponse)
 {
   NS_ENSURE_TRUE(*mCallback.ToJSValPtr() != JSVAL_NULL && mCx, JS_FALSE);
 
   JSAutoRequest ar(mCx);
-
-  JS::Rooted<JSObject*> global(mCx, JS_GetGlobalForObject(mCx, mCallback.ToJSObject()));
-  NS_ENSURE_TRUE(global, JS_FALSE);
-
-  JSAutoCompartment ac(mCx, global);
+  NS_ENSURE_TRUE(mCallback.ToJSObject(), JS_FALSE);
+  JSAutoCompartment ac(mCx, mCallback.ToJSObject());
+  JS::Rooted<JSObject*> global(mCx, JS_GetGlobalForScopeChain(mCx));
 
   JSString* str = JS_NewUCStringCopyN(mCx, aResponse.get(), aResponse.Length());
   NS_ENSURE_TRUE(str, JS_FALSE);
 
   JS::Rooted<JS::Value> strVal(mCx, JS::StringValue(str));
 
   JS::Rooted<JS::Value> rval(mCx);
   JSBool ok = JS_CallFunctionValue(mCx, global, mCallback, 1, strVal.address(),
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -831,43 +831,46 @@ LoadScriptRelativeToScript(JSContext *cx
 }
 
 class AutoNewContext
 {
   private:
     JSContext *oldcx;
     JSContext *newcx;
     Maybe<JSAutoRequest> newRequest;
+    Maybe<AutoCompartment> newCompartment;
 
     AutoNewContext(const AutoNewContext &) MOZ_DELETE;
 
   public:
     AutoNewContext() : oldcx(NULL), newcx(NULL) {}
 
     bool enter(JSContext *cx) {
         JS_ASSERT(!JS_IsExceptionPending(cx));
         oldcx = cx;
         newcx = NewContext(JS_GetRuntime(cx));
         if (!newcx)
             return false;
         JS_SetOptions(newcx, JS_GetOptions(newcx) | JSOPTION_DONT_REPORT_UNCAUGHT);
         JS_SetGlobalObject(newcx, JS_GetGlobalForScopeChain(cx));
 
         newRequest.construct(newcx);
+        newCompartment.construct(newcx, JS_GetGlobalForScopeChain(cx));
         return true;
     }
 
     JSContext *get() { return newcx; }
 
     ~AutoNewContext() {
         if (newcx) {
             RootedValue exc(oldcx);
             bool throwing = JS_IsExceptionPending(newcx);
             if (throwing)
                 JS_GetPendingException(newcx, exc.address());
+            newCompartment.destroy();
             newRequest.destroy();
             if (throwing)
                 JS_SetPendingException(oldcx, exc);
             DestroyContext(newcx, false);
         }
     }
 };
 
@@ -2615,36 +2618,36 @@ EvalInFrame(JSContext *cx, unsigned argc
     ScriptFrameIter fi(cx);
     for (uint32_t i = 0; i < upCount; ++i, ++fi) {
         ScriptFrameIter next(fi);
         ++next;
         if (next.done())
             break;
     }
 
-    bool saved = false;
-    if (saveCurrent)
-        saved = JS_SaveFrameChain(cx);
+    AutoSaveFrameChain sfc(cx);
+    mozilla::Maybe<AutoCompartment> ac;
+    if (saveCurrent) {
+        if (!sfc.save())
+            return false;
+        ac.construct(cx, GetDefaultGlobalForContext(cx));
+    }
 
     size_t length;
     const jschar *chars = JS_GetStringCharsAndLength(cx, str, &length);
     if (!chars)
         return false;
 
     JSAbstractFramePtr frame(Jsvalify(fi.abstractFramePtr()));
     RootedScript fpscript(cx, frame.script());
     bool ok = !!frame.evaluateUCInStackFrame(cx, chars, length,
                                              fpscript->filename(),
                                              JS_PCToLineNumber(cx, fpscript,
                                                                fi.pc()),
                                              MutableHandleValue::fromMarkedLocation(vp));
-
-    if (saved)
-        JS_RestoreFrameChain(cx);
-
     return ok;
 }
 
 static JSBool
 ShapeOf(JSContext *cx, unsigned argc, JS::Value *vp)
 {
     JS::Value v;
     if (argc < 1 || !((v = JS_ARGV(cx, vp)[0]).isObject())) {
@@ -5141,16 +5144,17 @@ Shell(JSContext *cx, OptionParser *op, c
     if (op->getBoolOption("fuzzing-safe"))
         fuzzingSafe = true;
 
     RootedObject glob(cx);
     glob = NewGlobalObject(cx, NULL);
     if (!glob)
         return 1;
 
+    JSAutoCompartment ac(cx, glob);
     JS_SetGlobalObject(cx, glob);
 
     JSObject *envobj = JS_DefineObject(cx, glob, "environment", &env_class, NULL, 0);
     if (!envobj)
         return 1;
     JS_SetPrivate(envobj, envp);
 
     int result = ProcessArgs(cx, glob, op);
--- a/netwerk/base/src/ProxyAutoConfig.cpp
+++ b/netwerk/base/src/ProxyAutoConfig.cpp
@@ -537,16 +537,17 @@ private:
     JSAutoRequest ar(mContext);
 
     JS::CompartmentOptions options;
     options.setZone(JS::SystemZone)
            .setVersion(JSVERSION_LATEST);
     mGlobal = JS_NewGlobalObject(mContext, &sGlobalClass, nullptr, options);
     NS_ENSURE_TRUE(mGlobal, NS_ERROR_OUT_OF_MEMORY);
 
+    JSAutoCompartment ac(mContext, mGlobal);
     JS_SetGlobalObject(mContext, mGlobal);
     JS_InitStandardClasses(mContext, mGlobal);
 
     JS_SetErrorReporter(mContext, PACErrorReporter);
 
     if (!JS_DefineFunctions(mContext, mGlobal, PACGlobalFunctions))
       return NS_ERROR_FAILURE;
 
@@ -588,16 +589,17 @@ ProxyAutoConfig::SetupJS()
   if (mPACScript.IsEmpty())
     return NS_ERROR_FAILURE;
 
   mJSRuntime = JSRuntimeWrapper::Create();
   if (!mJSRuntime)
     return NS_ERROR_FAILURE;
 
   JSAutoRequest ar(mJSRuntime->Context());
+  JSAutoCompartment ac(mJSRuntime->Context(), mJSRuntime->Global());
 
   sRunning = this;
   JSScript *script = JS_CompileScript(mJSRuntime->Context(),
                                       mJSRuntime->Global(),
                                       mPACScript.get(), mPACScript.Length(),
                                       mPACURI.get(), 1);
   if (!script ||
       !JS_ExecuteScript(mJSRuntime->Context(), mJSRuntime->Global(), script, nullptr)) {
@@ -629,16 +631,17 @@ ProxyAutoConfig::GetProxyForURI(const ns
   if (mJSNeedsSetup)
     SetupJS();
 
   if (!mJSRuntime || !mJSRuntime->IsOK())
     return NS_ERROR_NOT_AVAILABLE;
 
   JSContext *cx = mJSRuntime->Context();
   JSAutoRequest ar(cx);
+  JSAutoCompartment ac(cx, mJSRuntime->Global());
 
   // the sRunning flag keeps a new PAC file from being installed
   // while the event loop is spinning on a DNS function. Don't early return.
   sRunning = this;
   mRunningHost = aTestHost;
 
   nsresult rv = NS_ERROR_FAILURE;
   JS::RootedString uriString(cx, JS_NewStringCopyZ(cx, aTestURI.get()));
@@ -668,16 +671,17 @@ ProxyAutoConfig::GetProxyForURI(const ns
 }
 
 void
 ProxyAutoConfig::GC()
 {
   if (!mJSRuntime || !mJSRuntime->IsOK())
     return;
 
+  JSAutoCompartment ac(mJSRuntime->Context(), mJSRuntime->Global());
   JS_MaybeGC(mJSRuntime->Context());
 }
 
 ProxyAutoConfig::~ProxyAutoConfig()
 {
   MOZ_COUNT_DTOR(ProxyAutoConfig);
   NS_ASSERTION(!mJSRuntime,
                "~ProxyAutoConfig leaking JS runtime that "