Bug 398114. JS_Assert: (cx)->requestDepth || (cx)->thread == (cx)->runtime->gcThread from nsJSSh::Init. r=mrbkap, sr=shaver
authorsayrer@gmail.com
Fri, 05 Oct 2007 13:10:46 -0700
changeset 6672 85c81187992bf953a5c2e09daef93d0c6af1d245
parent 6671 82cfa8db2920293503fddd0c9964f6c590e60936
child 6673 ae6680abc2627c7ecf12ad36083b9f0bd1579922
push idunknown
push userunknown
push dateunknown
reviewersmrbkap, shaver
bugs398114
milestone1.9a9pre
Bug 398114. JS_Assert: (cx)->requestDepth || (cx)->thread == (cx)->runtime->gcThread from nsJSSh::Init. r=mrbkap, sr=shaver
extensions/jssh/nsJSSh.cpp
--- a/extensions/jssh/nsJSSh.cpp
+++ b/extensions/jssh/nsJSSh.cpp
@@ -60,16 +60,18 @@ PRLogModuleInfo *gJSShLog = PR_NewLogMod
 
 const char *gWelcome = "Welcome to the Mozilla JavaScript Shell!\n";
 const char *gGoodbye = "Goodbye!\n";
 
 // GetJSShGlobal: helper for native js functions to obtain the global
 // JSSh object
 PRBool GetJSShGlobal(JSContext *cx, JSObject *obj, nsJSSh** shell)
 {
+  JSAutoRequest ar(cx);
+
 #ifdef DEBUG
 //  printf("GetJSShGlobal(cx=%p, obj=%p)\n", cx, obj);
 #endif
   JSObject *parent, *global = obj;
   if (!global) {
     NS_ERROR("need a non-null obj to find script global");
     return PR_FALSE;
   }
@@ -131,16 +133,18 @@ my_ErrorReporter(JSContext *cx, const ch
 }
 
 JS_STATIC_DLL_CALLBACK(JSBool)
 Print(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
 {
   nsJSSh* shell;
   if (!GetJSShGlobal(cx, obj, &shell)) return JS_FALSE;
 
+  JSAutoRequest ar(cx);
+
   PRUint32 bytesWritten;
 
 #ifdef DEBUG
 //     nsCOMPtr<nsIThread> thread;
 //     nsIThread::GetCurrent(getter_AddRefs(thread));
 //     printf("printing on thread %p, shell %p, output %p, cx=%p, obj=%p\n", thread.get(), shell, shell->mOutput, cx, obj);
 #endif
 
@@ -178,16 +182,19 @@ Quit(JSContext *cx, JSObject *obj, uintN
   
   return JS_TRUE;
 }
 
 JS_STATIC_DLL_CALLBACK(JSBool)
 Load(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
 {
   nsJSSh* shell;
+
+  JSAutoRequest ar(cx);
+
   if (!GetJSShGlobal(cx, obj, &shell)) return JS_FALSE;
 
   for (unsigned int i=0; i<argc; ++i) {
     JSString *str = JS_ValueToString(cx, argv[i]);
     if (!str) return JS_FALSE;
     //argv[i] = STRING_TO_JSVAL(str);
     const char *url = JS_GetStringBytes(str);
     if (!shell->LoadURL(url, rval))
@@ -236,16 +243,18 @@ Resume(JSContext *cx, JSObject *obj, uin
   return JS_TRUE;
 }
 
 JS_STATIC_DLL_CALLBACK(JSBool)
 AddressOf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
 {
   if (argc!=1) return JS_FALSE;
 
+  JSAutoRequest ar(cx);
+
   // xxx If argv[0] is not an obj already, we'll get a transient
   // address from JS_ValueToObject. Maybe we should throw an exception
   // instead.
   
   JSObject *arg_obj;
   if (!JS_ValueToObject(cx, argv[0], &arg_obj)) {
     return JS_FALSE;
   }
@@ -259,16 +268,18 @@ AddressOf(JSContext *cx, JSObject *obj, 
 
 JS_STATIC_DLL_CALLBACK(JSBool)
 SetProtocol(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
 {
   if (argc!=1) return JS_FALSE;
   nsJSSh* shell;
   if (!GetJSShGlobal(cx, obj, &shell)) return JS_FALSE;
 
+  JSAutoRequest ar(cx);
+
   JSString *str = JS_ValueToString(cx, argv[0]);
   if (!str) return JS_FALSE;
   char *protocol = JS_GetStringBytes(str);
   
   if (!strcmp(protocol, "interactive")) {
     shell->mEmitHeader = PR_FALSE;
     shell->mPrompt = NS_LITERAL_CSTRING("\n> ");
     shell->mProtocol = protocol;
@@ -289,27 +300,31 @@ SetProtocol(JSContext *cx, JSObject *obj
 }
 
 JS_STATIC_DLL_CALLBACK(JSBool)
 GetProtocol(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
 {
   nsJSSh* shell;
   if (!GetJSShGlobal(cx, obj, &shell)) return JS_FALSE;
 
+  JSAutoRequest ar(cx);
+
   JSString *str = JS_NewStringCopyZ(cx, shell->mProtocol.get());
   *rval = STRING_TO_JSVAL(str);
   return JS_TRUE;
 }
 
 JS_STATIC_DLL_CALLBACK(JSBool)
 SetContextObj(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
 {
   nsJSSh* shell;
   if (!GetJSShGlobal(cx, obj, &shell)) return JS_FALSE;
 
+  JSAutoRequest ar(cx);
+
   if (argc!=1) return JS_FALSE;
 
   JSObject *arg_obj;
   if (!JS_ValueToObject(cx, argv[0], &arg_obj)) {
     return JS_FALSE;
   }
 
   if (shell->mContextObj != shell->mGlobal)
@@ -335,16 +350,18 @@ DebugBreak(JSContext *cx, JSObject *obj,
 }
 
 JS_STATIC_DLL_CALLBACK(JSBool)
 GetInputStream(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
 {
   nsJSSh* shell;
   if (!GetJSShGlobal(cx, obj, &shell)) return JS_FALSE;
 
+  JSAutoRequest ar(cx);
+
   nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID());
   if (!xpc) {
     NS_ERROR("failed to get xpconnect service");
     return JS_FALSE;
   }
   
   nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
   xpc->WrapNative(cx, shell->mGlobal, shell->mInput,
@@ -365,16 +382,18 @@ GetInputStream(JSContext *cx, JSObject *
 }
 
 JS_STATIC_DLL_CALLBACK(JSBool)
 GetOutputStream(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
 {
   nsJSSh* shell;
   if (!GetJSShGlobal(cx, obj, &shell)) return JS_FALSE;
 
+  JSAutoRequest ar(cx);
+
   nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID());
   if (!xpc) {
     NS_ERROR("failed to get xpconnect service");
     return JS_FALSE;
   }
   
   nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
   xpc->WrapNative(cx, shell->mGlobal, shell->mOutput,
@@ -580,16 +599,18 @@ NS_IMETHODIMP nsJSSh::Init()
   }
   
   mJSContext = JS_NewContext(rt, 8192);
   if (!mJSContext) {
     NS_ERROR("JS_NewContext failed");
     return NS_ERROR_FAILURE;
   }
 
+  JSAutoRequest ar(mJSContext);
+
   // Enable e4x:
   JS_SetOptions(mJSContext, JS_GetOptions(mJSContext) | JSOPTION_XML);
   
   // Always use the latest js version
   JS_SetVersion(mJSContext, JSVERSION_LATEST);
   
   mContextStack = do_GetService("@mozilla.org/js/xpc/ContextStack;1");
   if (!mContextStack) {
@@ -630,34 +651,39 @@ NS_IMETHODIMP nsJSSh::Init()
 NS_IMETHODIMP nsJSSh::Cleanup()
 {
   nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID());
   if (!xpc) {
     NS_ERROR("failed to get xpconnect service");
     return NS_ERROR_FAILURE;
   }
 
-  if (mContextObj != mGlobal)
-    JS_RemoveRoot(mJSContext, &(mContextObj));
+  {
+    JSAutoRequest ar(mJSContext);
 
-  JS_ClearScope(mJSContext, mGlobal);
-  JS_GC(mJSContext);
+    if (mContextObj != mGlobal)
+      JS_RemoveRoot(mJSContext, &(mContextObj));
+
+    JS_ClearScope(mJSContext, mGlobal);
+    JS_GC(mJSContext);
+  }
 
   JS_DestroyContext(mJSContext);
   xpc->SyncJSContexts();
   return NS_OK;
 }
 
 NS_IMETHODIMP nsJSSh::ExecuteBuffer()
 {
 #ifdef DEBUG
 //     nsCOMPtr<nsIThread> thread;
 //     nsIThread::GetCurrent(getter_AddRefs(thread));
 //     printf("executing on thread %p\n", thread.get());
 #endif
+
   JS_BeginRequest(mJSContext);
   JS_ClearPendingException(mJSContext);
   JSPrincipals *jsprincipals;
   mPrincipal->GetJSPrincipals(mJSContext, &jsprincipals);
 
   if(NS_FAILED(mContextStack->Push(mJSContext))) {
     NS_ERROR("failed to push the current JSContext on the nsThreadJSContextStack");
     return NS_ERROR_FAILURE;
@@ -691,16 +717,17 @@ NS_IMETHODIMP nsJSSh::ExecuteBuffer()
   
   JS_EndRequest(mJSContext);
   
   return NS_OK;
 }
 
 NS_IMETHODIMP nsJSSh::IsBufferCompilable(PRBool *_retval)
 {
+  JSAutoRequest ar(mJSContext);
   *_retval = JS_BufferIsCompilableUnit(mJSContext, mContextObj, mBuffer, mBufferPtr);
   return NS_OK;
 }
 
 //----------------------------------------------------------------------
 // nsIScriptObjectPrincipal methods:
 
 nsIPrincipal *
@@ -728,16 +755,18 @@ nsJSSh::GetPrincipal()
 NS_IMETHODIMP
 nsJSSh::NewResolve(nsIXPConnectWrappedNative *wrapper,
                    JSContext * cx, JSObject * obj,
                    jsval id, PRUint32 flags, 
                    JSObject * *objp, PRBool *_retval)
 {
   JSBool resolved;
   
+  JSAutoRequest ar(cx);
+
   *_retval = JS_ResolveStandardClass(cx, obj, id, &resolved);
   if (*_retval && resolved)
     *objp = obj;
   return NS_OK;
 }
 
 //----------------------------------------------------------------------
 // Implementation helpers: