Bug 889714 - Use the SafeJSContext in XPCShellEnvironment. r=mrbkap
authorBobby Holley <bobbyholley@gmail.com>
Wed, 31 Jul 2013 10:59:26 -0700
changeset 148171 b932a3fb643167afa64601690583a527972cbddc
parent 148170 90ad8d976c7cc91a7551d2510fb9b48f3d94ce09
child 148172 589c2607f15e1595b935aa02c6840bec53261f1f
push id2697
push userbbajaj@mozilla.com
push dateMon, 05 Aug 2013 18:49:53 +0000
treeherdermozilla-beta@dfec938c7b63 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmrbkap
bugs889714
milestone24.0a2
Bug 889714 - Use the SafeJSContext in XPCShellEnvironment. r=mrbkap
ipc/testshell/XPCShellEnvironment.cpp
ipc/testshell/XPCShellEnvironment.h
--- a/ipc/testshell/XPCShellEnvironment.cpp
+++ b/ipc/testshell/XPCShellEnvironment.cpp
@@ -412,18 +412,16 @@ typedef enum JSShellErrNum
 void
 XPCShellEnvironment::ProcessFile(JSContext *cx,
                                  JS::Handle<JSObject*> obj,
                                  const char *filename,
                                  FILE *file,
                                  JSBool forceTTY)
 {
     XPCShellEnvironment* env = this;
-    nsCxPusher pusher;
-    pusher.Push(env->GetContext());
 
     JSScript *script;
     JS::Rooted<JS::Value> result(cx);
     int lineno, startline;
     JSBool ok, hitEOF;
     char *bufp, buffer[4096];
     JSString *str;
 
@@ -564,38 +562,35 @@ XPCShellEnvironment::CreateEnvironment()
     if (env && !env->Init()) {
         delete env;
         env = nullptr;
     }
     return env;
 }
 
 XPCShellEnvironment::XPCShellEnvironment()
-:   mCx(NULL),
-    mQuitting(JS_FALSE)
+:   mQuitting(JS_FALSE)
 {
 }
 
 XPCShellEnvironment::~XPCShellEnvironment()
 {
-    if (mCx) {
-        JS_BeginRequest(mCx);
 
-        JSObject* global = GetGlobalObject();
-        if (global) {
-            JS_SetAllNonReservedSlotsToUndefined(mCx, global);
+    AutoSafeJSContext cx;
+    JSObject* global = GetGlobalObject();
+    if (global) {
+        {
+            JSAutoCompartment ac(cx, global);
+            JS_SetAllNonReservedSlotsToUndefined(cx, global);
         }
         mGlobalHolder.Release();
 
-        JSRuntime *rt = JS_GetRuntime(mCx);
+        JSRuntime *rt = JS_GetRuntime(cx);
         JS_GC(rt);
 
-        JS_EndRequest(mCx);
-        JS_DestroyContext(mCx);
-
         if (gOldContextCallback) {
             NS_ASSERTION(rt, "Should never be null!");
             JS_SetContextCallback(rt, gOldContextCallback);
             gOldContextCallback = NULL;
         }
     }
 }
 
@@ -624,27 +619,17 @@ XPCShellEnvironment::Init()
     }
 
     if (!mGlobalHolder.Hold(rt)) {
         NS_ERROR("Can't protect global object!");
         return false;
     }
 
     gOldContextCallback = JS_SetContextCallback(rt, ContextCallback);
-
-    JSContext *cx = JS_NewContext(rt, 8192);
-    if (!cx) {
-        NS_ERROR("JS_NewContext failed!");
-
-        JS_SetContextCallback(rt, gOldContextCallback);
-        gOldContextCallback = NULL;
-
-        return false;
-    }
-    mCx = cx;
+    AutoSafeJSContext cx;
 
     JS_SetContextPrivate(cx, this);
 
     nsCOMPtr<nsIXPConnect> xpc =
       do_GetService(nsIXPConnect::GetCID());
     if (!xpc) {
         NS_ERROR("failed to get nsXPConnect service!");
         return false;
@@ -657,19 +642,16 @@ XPCShellEnvironment::Init()
         rv = securityManager->GetSystemPrincipal(getter_AddRefs(principal));
         if (NS_FAILED(rv)) {
             fprintf(stderr, "+++ Failed to obtain SystemPrincipal from ScriptSecurityManager service.\n");
         }
     } else {
         fprintf(stderr, "+++ Failed to get ScriptSecurityManager service, running without principals");
     }
 
-    nsCxPusher pusher;
-    pusher.Push(mCx);
-
     nsRefPtr<BackstagePass> backstagePass;
     rv = NS_NewBackstagePass(getter_AddRefs(backstagePass));
     if (NS_FAILED(rv)) {
         NS_ERROR("Failed to create backstage pass!");
         return false;
     }
 
     JS::CompartmentOptions options;
@@ -686,32 +668,29 @@ XPCShellEnvironment::Init()
         return false;
     }
 
     JS::Rooted<JSObject*> globalObj(cx, holder->GetJSObject());
     if (!globalObj) {
         NS_ERROR("Failed to get global JSObject!");
         return false;
     }
+    JSAutoCompartment ac(cx, globalObj);
 
     backstagePass->SetGlobalObject(globalObj);
 
+    if (!JS_DefineProperty(cx, globalObj, "__XPCShellEnvironment",
+                           PRIVATE_TO_JSVAL(this), JS_PropertyStub,
+                           JS_StrictPropertyStub,
+                           JSPROP_READONLY | JSPROP_PERMANENT) ||
+        !JS_DefineFunctions(cx, globalObj, gGlobalFunctions) ||
+        !JS_DefineProfilingFunctions(cx, globalObj))
     {
-        JSAutoRequest ar(cx);
-        JSAutoCompartment ac(cx, globalObj);
-
-        if (!JS_DefineProperty(cx, globalObj, "__XPCShellEnvironment",
-                               PRIVATE_TO_JSVAL(this), JS_PropertyStub,
-                               JS_StrictPropertyStub,
-                               JSPROP_READONLY | JSPROP_PERMANENT) ||
-            !JS_DefineFunctions(cx, globalObj, gGlobalFunctions) ||
-            !JS_DefineProfilingFunctions(cx, globalObj)) {
-            NS_ERROR("JS_DefineFunctions failed!");
-            return false;
-        }
+        NS_ERROR("JS_DefineFunctions failed!");
+        return false;
     }
 
     mGlobalHolder = globalObj;
 
     FILE* runtimeScriptFile = fopen(kDefaultRuntimeScriptFilename, "r");
     if (runtimeScriptFile) {
         fprintf(stdout, "[loading '%s'...]\n", kDefaultRuntimeScriptFilename);
         ProcessFile(cx, globalObj, kDefaultRuntimeScriptFilename,
@@ -721,48 +700,41 @@ XPCShellEnvironment::Init()
 
     return true;
 }
 
 bool
 XPCShellEnvironment::EvaluateString(const nsString& aString,
                                     nsString* aResult)
 {
-  XPCShellEnvironment* env = this;
-  nsCxPusher pusher;
-  pusher.Push(env->GetContext());
-
-  JSAutoRequest ar(mCx);
-
-  JS_ClearPendingException(mCx);
-
-  JS::Rooted<JSObject*> global(mCx, GetGlobalObject());
-  JSAutoCompartment ac(mCx, global);
+  AutoSafeJSContext cx;
+  JS::Rooted<JSObject*> global(cx, GetGlobalObject());
+  JSAutoCompartment ac(cx, global);
 
   JSScript* script =
-      JS_CompileUCScriptForPrincipals(mCx, global, GetPrincipal(),
+      JS_CompileUCScriptForPrincipals(cx, global, GetPrincipal(),
                                       aString.get(), aString.Length(),
                                       "typein", 0);
   if (!script) {
      return false;
   }
 
   if (aResult) {
       aResult->Truncate();
   }
 
-  JS::Rooted<JS::Value> result(mCx);
-  JSBool ok = JS_ExecuteScript(mCx, global, script, result.address());
+  JS::Rooted<JS::Value> result(cx);
+  JSBool ok = JS_ExecuteScript(cx, global, script, result.address());
   if (ok && result != JSVAL_VOID) {
-      JSErrorReporter old = JS_SetErrorReporter(mCx, NULL);
-      JSString* str = JS_ValueToString(mCx, result);
+      JSErrorReporter old = JS_SetErrorReporter(cx, NULL);
+      JSString* str = JS_ValueToString(cx, result);
       nsDependentJSString depStr;
       if (str)
-          depStr.init(mCx, str);
-      JS_SetErrorReporter(mCx, old);
+          depStr.init(cx, str);
+      JS_SetErrorReporter(cx, old);
 
       if (!depStr.IsEmpty() && aResult) {
           aResult->Assign(depStr);
       }
   }
 
   return true;
 }
--- a/ipc/testshell/XPCShellEnvironment.h
+++ b/ipc/testshell/XPCShellEnvironment.h
@@ -38,33 +38,28 @@ public:
     JSPrincipals* GetPrincipal() {
         return nsJSPrincipals::get(nsContentUtils::GetSystemPrincipal());
     }
 
     JSObject* GetGlobalObject() {
         return mGlobalHolder.ToJSObject();
     }
 
-    JSContext* GetContext() {
-        return mCx;
-    }
-
     void SetIsQuitting() {
         mQuitting = JS_TRUE;
     }
     JSBool IsQuitting() {
         return mQuitting;
     }
 
 protected:
     XPCShellEnvironment();
     bool Init();
 
 private:
-    JSContext* mCx;
     nsAutoJSValHolder mGlobalHolder;
 
     JSBool mQuitting;
 };
 
 } /* namespace ipc */
 } /* namespace mozilla */