Bug 981198 - Make JS_{Get,Set}ErrorReporter take a JSRuntime. r=terrence,r=bz
authorBobby Holley <bobbyholley@gmail.com>
Tue, 09 Sep 2014 16:02:10 -0700
changeset 204438 0eaa239b3bfd05c88aca67b2421e0770cffeb4e6
parent 204437 3d78fa27054f81bb21f7c212940ba0dc987551e7
child 204439 c09f2ddb7bacd254d416d3838c525a2ed95cc766
push id27458
push usercbook@mozilla.com
push dateWed, 10 Sep 2014 12:59:53 +0000
treeherdermozilla-central@3402f4fbf7b2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersterrence, bz
bugs981198
milestone35.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 981198 - Make JS_{Get,Set}ErrorReporter take a JSRuntime. r=terrence,r=bz
dom/base/nsJSEnvironment.cpp
dom/workers/RuntimeService.cpp
ipc/testshell/XPCShellEnvironment.cpp
js/src/gdb/gdb-tests.cpp
js/src/jsapi-tests/testErrorCopying.cpp
js/src/jsapi-tests/testGCOutOfMemory.cpp
js/src/jsapi-tests/testOriginPrincipals.cpp
js/src/jsapi-tests/testParseJSON.cpp
js/src/jsapi-tests/testUncaughtError.cpp
js/src/jsapi-tests/tests.h
js/src/jsapi.cpp
js/src/jsapi.h
js/src/jsexn.cpp
js/src/shell/js.cpp
js/src/vm/SelfHosting.cpp
js/xpconnect/src/XPCJSContextStack.cpp
js/xpconnect/src/XPCJSRuntime.cpp
js/xpconnect/src/XPCShellImpl.cpp
netwerk/base/src/ProxyAutoConfig.cpp
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -755,18 +755,16 @@ nsJSContext::InitContext()
 {
   // Make sure callers of this use
   // WillInitializeContext/DidInitializeContext around this call.
   NS_ENSURE_TRUE(!mIsInitialized, NS_ERROR_ALREADY_INITIALIZED);
 
   if (!mContext)
     return NS_ERROR_OUT_OF_MEMORY;
 
-  JS_SetErrorReporter(mContext, xpc::SystemErrorReporter);
-
   JSOptionChangedCallback(js_options_dot_str, this);
 
   return NS_OK;
 }
 
 nsresult
 nsJSContext::SetProperty(JS::Handle<JSObject*> aTarget, const char* aPropName, nsISupports* aArgs)
 {
--- a/dom/workers/RuntimeService.cpp
+++ b/dom/workers/RuntimeService.cpp
@@ -821,17 +821,17 @@ CreateJSContextForWorker(WorkerPrivate* 
     return nullptr;
   }
 
   auto rtPrivate = new WorkerThreadRuntimePrivate();
   memset(rtPrivate, 0, sizeof(WorkerThreadRuntimePrivate));
   rtPrivate->mWorkerPrivate = aWorkerPrivate;
   JS_SetRuntimePrivate(aRuntime, rtPrivate);
 
-  JS_SetErrorReporter(workerCx, ErrorReporter);
+  JS_SetErrorReporter(aRuntime, ErrorReporter);
 
   JS_SetInterruptCallback(aRuntime, InterruptCallback);
 
   js::SetCTypesActivityCallback(aRuntime, CTypesActivityCallback);
 
   JS::ContextOptionsRef(workerCx) = kRequiredContextOptions;
 
 #ifdef JS_GC_ZEAL
--- a/ipc/testshell/XPCShellEnvironment.cpp
+++ b/ipc/testshell/XPCShellEnvironment.cpp
@@ -373,22 +373,22 @@ XPCShellEnvironment::ProcessFile(JSConte
         options.setFileAndLine("typein", startline);
         JS::Rooted<JSScript*> script(cx);
         if (JS_CompileScript(cx, obj, buffer, strlen(buffer), options, &script)) {
             JSErrorReporter older;
 
             ok = JS_ExecuteScript(cx, obj, script, &result);
             if (ok && result != JSVAL_VOID) {
                 /* Suppress error reports from JS::ToString(). */
-                older = JS_SetErrorReporter(cx, nullptr);
+                older = JS_SetErrorReporter(JS_GetRuntime(cx), nullptr);
                 str = JS::ToString(cx, result);
                 JSAutoByteString bytes;
                 if (str)
                     bytes.encodeLatin1(cx, str);
-                JS_SetErrorReporter(cx, older);
+                JS_SetErrorReporter(JS_GetRuntime(cx), older);
 
                 if (!!bytes)
                     fprintf(stdout, "%s\n", bytes.ptr());
                 else
                     ok = false;
             }
         }
     } while (!hitEOF && !env->IsQuitting());
@@ -588,22 +588,22 @@ XPCShellEnvironment::EvaluateString(cons
 
   if (aResult) {
       aResult->Truncate();
   }
 
   JS::Rooted<JS::Value> result(cx);
   bool ok = JS_ExecuteScript(cx, global, script, &result);
   if (ok && result != JSVAL_VOID) {
-      JSErrorReporter old = JS_SetErrorReporter(cx, nullptr);
+      JSErrorReporter old = JS_SetErrorReporter(JS_GetRuntime(cx), nullptr);
       JSString* str = JS::ToString(cx, result);
       nsAutoJSString autoStr;
       if (str)
           autoStr.init(cx, str);
-      JS_SetErrorReporter(cx, old);
+      JS_SetErrorReporter(JS_GetRuntime(cx), old);
 
       if (!autoStr.IsEmpty() && aResult) {
           aResult->Assign(autoStr);
       }
   }
 
   return true;
 }
--- a/js/src/gdb/gdb-tests.cpp
+++ b/js/src/gdb/gdb-tests.cpp
@@ -62,17 +62,17 @@ int
 main (int argc, const char **argv)
 {
     if (!JS_Init()) return 1;
     JSRuntime *runtime = checkPtr(JS_NewRuntime(1024 * 1024));
     JS_SetGCParameter(runtime, JSGC_MAX_BYTES, 0xffffffff);
     JS_SetNativeStackQuota(runtime, 5000000);
 
     JSContext *cx = checkPtr(JS_NewContext(runtime, 8192));
-    JS_SetErrorReporter(cx, reportError);
+    JS_SetErrorReporter(runtime, reportError);
 
     JSAutoRequest ar(cx);
 
     /* Create the global object. */
     JS::CompartmentOptions options;
     options.setVersion(JSVERSION_LATEST);
     RootedObject global(cx, checkPtr(JS_NewGlobalObject(cx, &global_class,
                         nullptr, JS::FireOnNewGlobalHook, options)));
--- a/js/src/jsapi-tests/testErrorCopying.cpp
+++ b/js/src/jsapi-tests/testErrorCopying.cpp
@@ -14,17 +14,17 @@ static uint32_t column = 0;
 
 BEGIN_TEST(testErrorCopying_columnCopied)
 {
         //0         1         2
         //0123456789012345678901234567
     EXEC("function check() { Object; foo; }");
 
     JS::RootedValue rval(cx);
-    JS_SetErrorReporter(cx, my_ErrorReporter);
+    JS_SetErrorReporter(rt, my_ErrorReporter);
     CHECK(!JS_CallFunctionName(cx, global, "check", JS::HandleValueArray::empty(),
                                &rval));
     CHECK(column == 27);
     return true;
 }
 
 static void
 my_ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
--- a/js/src/jsapi-tests/testGCOutOfMemory.cpp
+++ b/js/src/jsapi-tests/testGCOutOfMemory.cpp
@@ -13,17 +13,17 @@ static unsigned errorCount = 0;
 static void
 ErrorCounter(JSContext *cx, const char *message, JSErrorReport *report)
 {
     ++errorCount;
 }
 
 BEGIN_TEST(testGCOutOfMemory)
 {
-    JS_SetErrorReporter(cx, ErrorCounter);
+    JS_SetErrorReporter(rt, ErrorCounter);
 
     JS::RootedValue root(cx);
 
     static const char source[] =
         "var max = 0; (function() {"
         "    var array = [];"
         "    for (; ; ++max)"
         "        array.push({});"
--- a/js/src/jsapi-tests/testOriginPrincipals.cpp
+++ b/js/src/jsapi-tests/testOriginPrincipals.cpp
@@ -25,17 +25,17 @@ BEGIN_TEST(testOriginPrincipals)
     CHECK(testOuter("(function (){ return eval('(function() { return eval(\"(function(){return 5})\") })()'); })()"));
     CHECK(testOuter("new Function('return 6')"));
     CHECK(testOuter("function f() { return new Function('return 7') }; f();"));
     CHECK(testOuter("eval('new Function(\"return 8\")')"));
     CHECK(testOuter("(new Function('return eval(\"(function(){return 9})\")'))()"));
     CHECK(testOuter("(function(){return function(){return 10}}).bind()()"));
     CHECK(testOuter("var e = eval; (function() { return e('(function(){return 11})') })()"));
 
-    JS_SetErrorReporter(cx, ErrorReporter);
+    JS_SetErrorReporter(rt, ErrorReporter);
     CHECK(testError("eval(-)"));
     CHECK(testError("-"));
     CHECK(testError("new Function('x', '-')"));
     CHECK(testError("eval('new Function(\"x\", \"-\")')"));
 
     /*
      * NB: uncaught exceptions, when reported, have nothing on the stack so
      * both the filename and originPrincipals are null. E.g., this would fail:
--- a/js/src/jsapi-tests/testParseJSON.cpp
+++ b/js/src/jsapi-tests/testParseJSON.cpp
@@ -278,19 +278,19 @@ Error(JSContext *cx, const char (&input)
 {
     AutoInflatedString str(cx), line(cx), column(cx);
     RootedValue dummy(cx);
     str = input;
 
     ContextPrivate p = {0, 0};
     CHECK(!JS_GetContextPrivate(cx));
     JS_SetContextPrivate(cx, &p);
-    JSErrorReporter old = JS_SetErrorReporter(cx, ReportJSONError);
+    JSErrorReporter old = JS_SetErrorReporter(rt, ReportJSONError);
     bool ok = JS_ParseJSON(cx, str.chars(), str.length(), &dummy);
-    JS_SetErrorReporter(cx, old);
+    JS_SetErrorReporter(rt, old);
     JS_SetContextPrivate(cx, nullptr);
 
     CHECK(!ok);
     CHECK(!p.unexpectedErrorCount);
     CHECK(p.expectedErrorCount == 1);
     column = expectedColumn;
     CHECK(js_strcmp(column.chars(), p.column) == 0);
     line = expectedLine;
--- a/js/src/jsapi-tests/testUncaughtError.cpp
+++ b/js/src/jsapi-tests/testUncaughtError.cpp
@@ -8,17 +8,17 @@ using JS::CreateError;
 using JS::Rooted;
 using JS::ObjectValue;
 using JS::Value;
 
 static size_t uncaughtCount = 0;
 
 BEGIN_TEST(testUncaughtError)
 {
-    JSErrorReporter old = JS_SetErrorReporter(cx, UncaughtErrorReporter);
+    JSErrorReporter old = JS_SetErrorReporter(rt, UncaughtErrorReporter);
 
     CHECK(uncaughtCount == 0);
 
     Rooted<JSString*> empty(cx, JS_GetEmptyString(JS_GetRuntime(cx)));
     if (!empty)
         return false;
 
     Rooted<Value> err(cx);
@@ -37,17 +37,17 @@ BEGIN_TEST(testUncaughtError)
     if (!JS_SetProperty(cx, errObj, "message", err))
         return false;
 
     JS_SetPendingException(cx, err);
     JS_ReportPendingException(cx);
 
     CHECK(uncaughtCount == 1);
 
-    JS_SetErrorReporter(cx, old);
+    JS_SetErrorReporter(rt, old);
 
     return true;
 }
 
 static void
 UncaughtErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
 {
     uncaughtCount++;
--- a/js/src/jsapi-tests/tests.h
+++ b/js/src/jsapi-tests/tests.h
@@ -278,16 +278,17 @@ class JSAPITest
 
         JS_SetNativeStackQuota(rt, MAX_STACK_SIZE);
     }
 
     virtual JSRuntime * createRuntime() {
         JSRuntime *rt = JS_NewRuntime(8L * 1024 * 1024);
         if (!rt)
             return nullptr;
+        JS_SetErrorReporter(rt, &reportError);
         setNativeStackQuota(rt);
         JS::RuntimeOptionsRef(rt).setVarObjFix(true);
         return rt;
     }
 
     virtual void destroyRuntime() {
         JS_ASSERT(!cx);
         JS_ASSERT(rt);
@@ -297,21 +298,17 @@ class JSAPITest
     static void reportError(JSContext *cx, const char *message, JSErrorReport *report) {
         fprintf(stderr, "%s:%u:%s\n",
                 report->filename ? report->filename : "<no filename>",
                 (unsigned int) report->lineno,
                 message);
     }
 
     virtual JSContext * createContext() {
-        JSContext *cx = JS_NewContext(rt, 8192);
-        if (!cx)
-            return nullptr;
-        JS_SetErrorReporter(cx, &reportError);
-        return cx;
+        return JS_NewContext(rt, 8192);
     }
 
     virtual const JSClass * getGlobalClass() {
         return basicGlobalClass();
     }
 
     virtual JSObject * createGlobal(JSPrincipals *principals = nullptr);
 };
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -4564,27 +4564,27 @@ JS_BufferIsCompilableUnit(JSContext *cx,
     // caller doesn't try to collect more buffered source.
     bool result = true;
 
     CompileOptions options(cx);
     options.setCompileAndGo(false);
     Parser<frontend::FullParseHandler> parser(cx, &cx->tempLifoAlloc(),
                                               options, chars, length,
                                               /* foldConstants = */ true, nullptr, nullptr);
-    JSErrorReporter older = JS_SetErrorReporter(cx, nullptr);
+    JSErrorReporter older = JS_SetErrorReporter(cx->runtime(), nullptr);
     if (!parser.parse(obj)) {
         // We ran into an error. If it was because we ran out of source, we
         // return false so our caller knows to try to collect more buffered
         // source.
         if (parser.isUnexpectedEOF())
             result = false;
 
         cx->clearPendingException();
     }
-    JS_SetErrorReporter(cx, older);
+    JS_SetErrorReporter(cx->runtime(), older);
 
     js_free(chars);
     return result;
 }
 
 JS_PUBLIC_API(JSObject *)
 JS_GetGlobalFromScript(JSScript *script)
 {
@@ -5762,28 +5762,28 @@ JS_ReportOutOfMemory(JSContext *cx)
 
 JS_PUBLIC_API(void)
 JS_ReportAllocationOverflow(JSContext *cx)
 {
     js_ReportAllocationOverflow(cx);
 }
 
 JS_PUBLIC_API(JSErrorReporter)
-JS_GetErrorReporter(JSContext *cx)
-{
-    return cx->runtime()->errorReporter;
+JS_GetErrorReporter(JSRuntime *rt)
+{
+    return rt->errorReporter;
 }
 
 JS_PUBLIC_API(JSErrorReporter)
-JS_SetErrorReporter(JSContext *cx, JSErrorReporter er)
+JS_SetErrorReporter(JSRuntime *rt, JSErrorReporter er)
 {
     JSErrorReporter older;
 
-    older = cx->runtime()->errorReporter;
-    cx->runtime()->errorReporter = er;
+    older = rt->errorReporter;
+    rt->errorReporter = er;
     return older;
 }
 
 /************************************************************************/
 
 /*
  * Dates.
  */
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -4633,20 +4633,20 @@ struct JSErrorReport {
  * appropriate.
  */
 #define JSREPORT_IS_WARNING(flags)      (((flags) & JSREPORT_WARNING) != 0)
 #define JSREPORT_IS_EXCEPTION(flags)    (((flags) & JSREPORT_EXCEPTION) != 0)
 #define JSREPORT_IS_STRICT(flags)       (((flags) & JSREPORT_STRICT) != 0)
 #define JSREPORT_IS_STRICT_MODE_ERROR(flags) (((flags) &                      \
                                               JSREPORT_STRICT_MODE_ERROR) != 0)
 extern JS_PUBLIC_API(JSErrorReporter)
-JS_GetErrorReporter(JSContext *cx);
+JS_GetErrorReporter(JSRuntime *rt);
 
 extern JS_PUBLIC_API(JSErrorReporter)
-JS_SetErrorReporter(JSContext *cx, JSErrorReporter er);
+JS_SetErrorReporter(JSRuntime *rt, JSErrorReporter er);
 
 namespace JS {
 
 extern JS_PUBLIC_API(bool)
 CreateError(JSContext *cx, JSExnType type, HandleString stack,
             HandleString fileName, uint32_t lineNumber, uint32_t columnNumber,
             JSErrorReport *report, HandleString message, MutableHandleValue rval);
 
--- a/js/src/jsexn.cpp
+++ b/js/src/jsexn.cpp
@@ -211,23 +211,23 @@ js::CopyErrorReport(JSContext *cx, JSErr
 struct SuppressErrorsGuard
 {
     JSContext *cx;
     JSErrorReporter prevReporter;
     JS::AutoSaveExceptionState prevState;
 
     explicit SuppressErrorsGuard(JSContext *cx)
       : cx(cx),
-        prevReporter(JS_SetErrorReporter(cx, nullptr)),
+        prevReporter(JS_SetErrorReporter(cx->runtime(), nullptr)),
         prevState(cx)
     {}
 
     ~SuppressErrorsGuard()
     {
-        JS_SetErrorReporter(cx, prevReporter);
+        JS_SetErrorReporter(cx->runtime(), prevReporter);
     }
 };
 
 JSString *
 js::ComputeStackString(JSContext *cx)
 {
     StringBuffer sb(cx);
 
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -190,16 +190,18 @@ DestroyContext(JSContext *cx, bool withG
 
 static JSObject *
 NewGlobalObject(JSContext *cx, JS::CompartmentOptions &options,
                 JSPrincipals *principals);
 
 static const JSErrorFormatString *
 my_GetErrorMessage(void *userRef, const unsigned errorNumber);
 
+static void
+my_ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report);
 
 /*
  * A toy principals type for the shell.
  *
  * In the shell, a principal is simply a 32-bit mask: P subsumes Q if the
  * set bits in P are a superset of those in Q. Thus, the principal 0 is
  * subsumed by everything, and the principal ~0 subsumes everything.
  *
@@ -2694,16 +2696,17 @@ WorkerMain(void *arg)
 {
     WorkerInput *input = (WorkerInput *) arg;
 
     JSRuntime *rt = JS_NewRuntime(8L * 1024L * 1024L, 2L * 1024L * 1024L, input->runtime);
     if (!rt) {
         js_delete(input);
         return;
     }
+    JS_SetErrorReporter(rt, my_ErrorReporter);
 
     JSContext *cx = NewContext(rt);
     if (!cx) {
         JS_DestroyRuntime(rt);
         js_delete(input);
         return;
     }
 
@@ -5540,17 +5543,16 @@ NewContext(JSRuntime *rt)
 
     JSShellContextData *data = NewContextData();
     if (!data) {
         DestroyContext(cx, false);
         return nullptr;
     }
 
     JS_SetContextPrivate(cx, data);
-    JS_SetErrorReporter(cx, my_ErrorReporter);
     return cx;
 }
 
 static void
 DestroyContext(JSContext *cx, bool withGC)
 {
     // Don't use GetContextData as |data| could be a nullptr in the case of
     // destroying a context precisely because we couldn't create its private
@@ -6177,16 +6179,17 @@ main(int argc, char **argv, char **envp)
     nurseryBytes = op.getIntOption("nursery-size") * 1024L * 1024L;
 #endif
 
     /* Use the same parameters as the browser in xpcjsruntime.cpp. */
     rt = JS_NewRuntime(JS::DefaultHeapMaxBytes, nurseryBytes);
     if (!rt)
         return 1;
 
+    JS_SetErrorReporter(rt, my_ErrorReporter);
     JS::SetOutOfMemoryCallback(rt, my_OOMCallback, nullptr);
     if (!SetRuntimeOptions(rt, op))
         return 1;
 
     gInterruptFunc.emplace(rt, NullValue());
 
     JS_SetGCParameter(rt, JSGC_MAX_BYTES, 0xffffffff);
 #ifdef JSGC_GENERATIONAL
--- a/js/src/vm/SelfHosting.cpp
+++ b/js/src/vm/SelfHosting.cpp
@@ -1025,17 +1025,17 @@ JSRuntime::initSelfHosting(JSContext *cx
     CompileOptions options(cx);
     FillSelfHostingCompileOptions(options);
 
     /*
      * Set a temporary error reporter printing to stderr because it is too
      * early in the startup process for any other reporter to be registered
      * and we don't want errors in self-hosted code to be silently swallowed.
      */
-    JSErrorReporter oldReporter = JS_SetErrorReporter(cx, selfHosting_ErrorReporter);
+    JSErrorReporter oldReporter = JS_SetErrorReporter(cx->runtime(), selfHosting_ErrorReporter);
     RootedValue rv(cx);
     bool ok = false;
 
     char *filename = getenv("MOZ_SELFHOSTEDJS");
     if (filename) {
         RootedScript script(cx);
         if (Compile(cx, shg, options, filename, &script))
             ok = Execute(cx, script, *shg.get(), rv.address());
@@ -1048,17 +1048,17 @@ JSRuntime::initSelfHosting(JSContext *cx
         if (!src || !DecompressString(compressed, compressedLen,
                                       reinterpret_cast<unsigned char *>(src.get()), srcLen))
         {
             return false;
         }
 
         ok = Evaluate(cx, shg, options, src, srcLen, &rv);
     }
-    JS_SetErrorReporter(cx, oldReporter);
+    JS_SetErrorReporter(cx->runtime(), oldReporter);
     return ok;
 }
 
 void
 JSRuntime::finishSelfHosting()
 {
     selfHostingGlobal_ = nullptr;
 }
--- a/js/xpconnect/src/XPCJSContextStack.cpp
+++ b/js/xpconnect/src/XPCJSContextStack.cpp
@@ -117,11 +117,10 @@ XPCJSContextStack::GetSafeJSContext()
 
 JSContext*
 XPCJSContextStack::InitSafeJSContext()
 {
     MOZ_ASSERT(!mSafeJSContext);
     mSafeJSContext = JS_NewContext(XPCJSRuntime::Get()->Runtime(), 8192);
     if (!mSafeJSContext)
         MOZ_CRASH();
-    JS_SetErrorReporter(mSafeJSContext, xpc::SystemErrorReporter);
     return mSafeJSContext;
 }
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -3197,16 +3197,17 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* 
     // default.
     (void) kDefaultStackQuota;
 
     JS_SetNativeStackQuota(runtime,
                            kStackQuota,
                            kStackQuota - kSystemCodeBuffer,
                            kStackQuota - kSystemCodeBuffer - kTrustedScriptBuffer);
 
+    JS_SetErrorReporter(runtime, xpc::SystemErrorReporter);
     JS_SetDestroyCompartmentCallback(runtime, CompartmentDestroyedCallback);
     JS_SetCompartmentNameCallback(runtime, CompartmentNameCallback);
     mPrevGCSliceCallback = JS::SetGCSliceCallback(runtime, GCSliceCallback);
     JS_AddFinalizeCallback(runtime, FinalizeCallback, nullptr);
     JS_SetWrapObjectCallbacks(runtime, &WrapObjectCallbacks);
     js::SetPreserveWrapperCallback(runtime, PreserveWrapper);
 #ifdef MOZ_CRASHREPORTER
     JS_EnumerateDiagnosticMemoryRegions(DiagnosticMemoryCallback);
--- a/js/xpconnect/src/XPCShellImpl.cpp
+++ b/js/xpconnect/src/XPCShellImpl.cpp
@@ -955,19 +955,19 @@ ProcessFile(JSContext *cx, JS::Handle<JS
                .setCompileAndGo(true);
         if (JS_CompileScript(cx, obj, buffer, strlen(buffer), options, &script)) {
             JSErrorReporter older;
 
             if (!compileOnly) {
                 ok = JS_ExecuteScript(cx, obj, script, &result);
                 if (ok && result != JSVAL_VOID) {
                     /* Suppress error reports from JS::ToString(). */
-                    older = JS_SetErrorReporter(cx, nullptr);
+                    older = JS_SetErrorReporter(JS_GetRuntime(cx), nullptr);
                     str = ToString(cx, result);
-                    JS_SetErrorReporter(cx, older);
+                    JS_SetErrorReporter(JS_GetRuntime(cx), older);
                     JSAutoByteString bytes;
                     if (str && bytes.encodeLatin1(cx, str))
                         fprintf(gOutFile, "%s\n", bytes.ptr());
                     else
                         ok = false;
                 }
             }
         }
@@ -1261,24 +1261,16 @@ XPCShellErrorReporter(JSContext *cx, con
     if (!JSREPORT_IS_WARNING(rep->flags))
         gExitCode = EXITCODE_RUNTIME_ERROR;
 
     // Delegate to the system error reporter for heavy lifting.
     xpc::SystemErrorReporter(cx, message, rep);
 }
 
 static bool
-ContextCallback(JSContext *cx, unsigned contextOp)
-{
-    if (contextOp == JSCONTEXT_NEW)
-        JS_SetErrorReporter(cx, XPCShellErrorReporter);
-    return true;
-}
-
-static bool
 GetCurrentWorkingDirectory(nsAString& workingDirectory)
 {
 #if !defined(XP_WIN) && !defined(XP_UNIX)
     //XXX: your platform should really implement this
     return false;
 #elif XP_WIN
     DWORD requiredLength = GetCurrentDirectoryW(0, nullptr);
     workingDirectory.SetLength(requiredLength);
@@ -1449,24 +1441,24 @@ XRE_XPCShellMain(int argc, char **argv, 
             return 1;
         }
 
         if (NS_FAILED(rtsvc->GetRuntime(&rt)) || !rt) {
             printf("failed to get JSRuntime from nsJSRuntimeService!\n");
             return 1;
         }
 
-        rtsvc->RegisterContextCallback(ContextCallback);
-
         // Override the default XPConnect interrupt callback. We could store the
         // old one and restore it before shutting down, but there's not really a
         // reason to bother.
         sScriptedInterruptCallback.emplace(rt, UndefinedValue());
         JS_SetInterruptCallback(rt, XPCShellInterruptCallback);
 
+        JS_SetErrorReporter(rt, XPCShellErrorReporter);
+
         dom::AutoJSAPI jsapi;
         jsapi.Init();
         cx = jsapi.cx();
 
         argc--;
         argv++;
         ProcessArgsForCompartment(cx, argv, argc);
 
--- a/netwerk/base/src/ProxyAutoConfig.cpp
+++ b/netwerk/base/src/ProxyAutoConfig.cpp
@@ -562,34 +562,34 @@ private:
     NS_ENSURE_TRUE(mRuntime, NS_ERROR_OUT_OF_MEMORY);
 
     /*
      * Not setting this will cause JS_CHECK_RECURSION to report false
      * positives
      */
     JS_SetNativeStackQuota(mRuntime, 128 * sizeof(size_t) * 1024); 
 
+    JS_SetErrorReporter(mRuntime, PACErrorReporter);
+
     mContext = JS_NewContext(mRuntime, 0);
     NS_ENSURE_TRUE(mContext, NS_ERROR_OUT_OF_MEMORY);
 
     JSAutoRequest ar(mContext);
 
     JS::CompartmentOptions options;
     options.setZone(JS::SystemZone)
            .setVersion(JSVERSION_LATEST);
     mGlobal = JS_NewGlobalObject(mContext, &sGlobalClass, nullptr,
                                  JS::DontFireOnNewGlobalHook, options);
     NS_ENSURE_TRUE(mGlobal, NS_ERROR_OUT_OF_MEMORY);
     JS::Rooted<JSObject*> global(mContext, mGlobal);
 
     JSAutoCompartment ac(mContext, global);
     JS_InitStandardClasses(mContext, global);
 
-    JS_SetErrorReporter(mContext, PACErrorReporter);
-
     if (!JS_DefineFunctions(mContext, global, PACGlobalFunctions))
       return NS_ERROR_FAILURE;
 
     JS_FireOnNewGlobalObject(mContext, global);
 
     return NS_OK;
   }
 };