Bug 917798 - Handlify JS exception APIs r=terrence r=bz
authorJon Coppeard <jcoppeard@mozilla.com>
Thu, 19 Sep 2013 08:54:01 +0100
changeset 148217 0874c0c422b1ba2fc1fa82e15da81f24ffd9b5ec
parent 148216 f1434323209c058ee75ca60670fec1daa0b902a7
child 148218 020f08616536c164e0bd6712702ea8c9e6d974b4
push id270
push userpvanderbeken@mozilla.com
push dateThu, 06 Mar 2014 09:24:21 +0000
reviewersterrence, bz
bugs917798
milestone27.0a1
Bug 917798 - Handlify JS exception APIs r=terrence r=bz
dom/base/nsDOMClassInfo.cpp
dom/base/nsJSUtils.cpp
dom/bindings/BindingUtils.cpp
dom/bindings/CallbackObject.cpp
dom/bindings/Exceptions.cpp
dom/plugins/base/nsJSNPRuntime.cpp
js/ipc/JavaScriptChild.cpp
js/jsd/jsd_hook.cpp
js/jsd/jsd_stak.cpp
js/jsd/jsd_val.cpp
js/jsd/jsd_xpc.cpp
js/src/ctypes/CTypes.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/xpconnect/loader/mozJSComponentLoader.cpp
js/xpconnect/loader/mozJSSubScriptLoader.cpp
js/xpconnect/src/Sandbox.cpp
js/xpconnect/src/XPCWrappedJSClass.cpp
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -3525,17 +3525,17 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
       JSAutoCompartment ac(my_cx, obj);
 
       ok = JS_ResolveStandardClass(my_cx, obj, id, &did_resolve);
 
       if (!ok) {
         // Trust the JS engine (or the script security manager) to set
         // the exception in the JS engine.
 
-        if (!JS_GetPendingException(my_cx, exn.address())) {
+        if (!JS_GetPendingException(my_cx, &exn)) {
           return NS_ERROR_UNEXPECTED;
         }
 
         // Return NS_OK to avoid stomping over the exception that was passed
         // down from the ResolveStandardClass call.
         // Note that the order of the JS_ClearPendingException and
         // JS_SetPendingException is important in the case that my_cx == cx.
 
--- a/dom/base/nsJSUtils.cpp
+++ b/dom/base/nsJSUtils.cpp
@@ -291,17 +291,21 @@ nsJSUtils::EvaluateString(JSContext* aCx
     if (aEvaluateOptions.reportUncaught) {
       ReportPendingException(aCx);
       if (aRetValue) {
         *aRetValue = JS::UndefinedValue();
       }
     } else {
       rv = JS_IsExceptionPending(aCx) ? NS_ERROR_FAILURE
                                       : NS_ERROR_OUT_OF_MEMORY;
-      JS_GetPendingException(aCx, aRetValue);
+      JS::RootedValue exn(aCx);
+      JS_GetPendingException(aCx, &exn);
+      if (aRetValue) {
+        *aRetValue = exn;
+      }
       JS_ClearPendingException(aCx);
     }
   }
 
   // Wrap the return value into whatever compartment aCx was in.
   if (aRetValue && !JS_WrapValue(aCx, aRetValue))
     return NS_ERROR_OUT_OF_MEMORY;
   return rv;
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -176,17 +176,18 @@ ErrorResult::ThrowJSException(JSContext*
 }
 
 void
 ErrorResult::ReportJSException(JSContext* cx)
 {
   MOZ_ASSERT(!mMightHaveUnreportedJSException,
              "Why didn't you tell us you planned to handle JS exceptions?");
   if (JS_WrapValue(cx, &mJSException)) {
-    JS_SetPendingException(cx, mJSException);
+    JS::RootedValue exception(cx, mJSException);
+    JS_SetPendingException(cx, exception);
   }
   // If JS_WrapValue failed, not much we can do about it...  No matter
   // what, go ahead and unroot mJSException.
   JS_RemoveValueRoot(cx, &mJSException);
 }
 
 void
 ErrorResult::ReportJSExceptionFromJSImplementation(JSContext* aCx)
--- a/dom/bindings/CallbackObject.cpp
+++ b/dom/bindings/CallbackObject.cpp
@@ -181,17 +181,17 @@ CallbackObject::CallSetup::~CallSetup()
     bool dealtWithPendingException = false;
     if (mExceptionHandling == eRethrowContentExceptions ||
         mExceptionHandling == eRethrowExceptions) {
       // Restore the old context options
       JS_SetOptions(mCx, mSavedJSContextOptions);
       mErrorResult.MightThrowJSException();
       if (JS_IsExceptionPending(mCx)) {
         JS::Rooted<JS::Value> exn(mCx);
-        if (JS_GetPendingException(mCx, exn.address()) &&
+        if (JS_GetPendingException(mCx, &exn) &&
             ShouldRethrowException(exn)) {
           mErrorResult.ThrowJSException(mCx, exn);
           JS_ClearPendingException(mCx);
           dealtWithPendingException = true;
         }
       }
     }
 
--- a/dom/bindings/Exceptions.cpp
+++ b/dom/bindings/Exceptions.cpp
@@ -66,17 +66,18 @@ ThrowExceptionObject(JSContext* aCx, nsI
     return false;
   }
 
   JS::RootedObject obj(aCx, holder->GetJSObject());
   if (!obj) {
     return false;
   }
 
-  JS_SetPendingException(aCx, OBJECT_TO_JSVAL(obj));
+  JS::RootedValue exn(aCx, JS::ObjectOrNullValue(obj));
+  JS_SetPendingException(aCx, exn);
 
   return true;
 }
 
 bool
 ThrowExceptionObject(JSContext* aCx, Exception* aException)
 {
   JS::Rooted<JS::Value> thrown(aCx);
--- a/dom/plugins/base/nsJSNPRuntime.cpp
+++ b/dom/plugins/base/nsJSNPRuntime.cpp
@@ -452,17 +452,18 @@ ThrowJSException(JSContext *cx, const ch
     if (message) {
       AppendASCIItoUTF16("].", ucex);
     }
 
     JSString *str = ::JS_NewUCStringCopyN(cx, (jschar *)ucex.get(),
                                           ucex.Length());
 
     if (str) {
-      ::JS_SetPendingException(cx, STRING_TO_JSVAL(str));
+      JS::RootedValue exn(cx, JS::StringValue(str));
+      ::JS_SetPendingException(cx, exn);
     }
 
     PopException();
   } else {
     ::JS_ReportError(cx, message);
   }
 }
 
--- a/js/ipc/JavaScriptChild.cpp
+++ b/js/ipc/JavaScriptChild.cpp
@@ -113,17 +113,17 @@ JavaScriptChild::fail(JSContext *cx, Ret
     // By default, we set |undefined| unless we can get a more meaningful
     // exception.
     *rs = ReturnStatus(false, JSVariant(void_t()));
 
     // Note we always return true from this function, since this propagates
     // to the IPC code, and we don't want a JS failure to cause the death
     // of the child process.
 
-    jsval exn;
+    RootedValue exn(cx);
     if (!JS_GetPendingException(cx, &exn))
         return true;
 
     // If we don't clear the pending exception, JS will try to wrap it as it
     // leaves the current compartment. Since there is no previous compartment,
     // that would crash.
     JS_ClearPendingException(cx);
 
--- a/js/jsd/jsd_hook.cpp
+++ b/js/jsd/jsd_hook.cpp
@@ -75,17 +75,17 @@ jsd_DebuggerHandler(JSContext *cx, JSScr
 
     return jsd_CallExecutionHook(jsdc, cx, JSD_HOOK_DEBUGGER_KEYWORD,
                                  hook, hookData, rval);
 }
 
 
 JSTrapStatus
 jsd_ThrowHandler(JSContext *cx, JSScript *script, jsbytecode *pc,
-                 jsval *rval, void *closure)
+                 jsval *rvalArg, void *closure)
 {
     JSDScript*      jsdscript;
     JSDContext*     jsdc = (JSDContext*) closure;
     JSD_ExecutionHookProc hook;
     void*                 hookData;
 
     if( ! jsdc || ! jsdc->inited )
         return JSTRAP_CONTINUE;
@@ -102,20 +102,23 @@ jsd_ThrowHandler(JSContext *cx, JSScript
         return JSTRAP_CONTINUE;
 
     JSD_LOCK_SCRIPTS(jsdc);
     jsdscript = jsd_FindOrCreateJSDScript(jsdc, cx, script, JSNullFramePtr());
     JSD_UNLOCK_SCRIPTS(jsdc);
     if( ! jsdscript )
         return JSTRAP_CONTINUE;
 
-    JS_GetPendingException(cx, rval);
+    JS::RootedValue rval(cx);
+    JS_GetPendingException(cx, &rval);
 
-    return jsd_CallExecutionHook(jsdc, cx, JSD_HOOK_THROW,
-                                 hook, hookData, rval);
+    JSTrapStatus result = jsd_CallExecutionHook(jsdc, cx, JSD_HOOK_THROW,
+                                                hook, hookData, rval.address());
+    *rvalArg = rval;
+    return result;
 }
 
 JSTrapStatus
 jsd_CallExecutionHook(JSDContext* jsdc,
                       JSContext *cx,
                       unsigned type,
                       JSD_ExecutionHookProc hook,
                       void* hookData,
--- a/js/jsd/jsd_stak.cpp
+++ b/js/jsd/jsd_stak.cpp
@@ -519,54 +519,56 @@ jsd_IsValidFrameInThreadState(JSDContext
 
     if( ! jsd_IsValidThreadState(jsdc, jsdthreadstate) )
         return false;
     if( jsdframe->jsdthreadstate != jsdthreadstate )
         return false;
 
     JSD_ASSERT_VALID_THREAD_STATE(jsdthreadstate);
     JSD_ASSERT_VALID_STACK_FRAME(jsdframe);
-    
+
     return true;
 }
 
 static JSContext*
 _getContextForThreadState(JSDContext* jsdc, JSDThreadState* jsdthreadstate)
 {
     bool valid;
     JSD_LOCK_THREADSTATES(jsdc);
     valid = jsd_IsValidThreadState(jsdc, jsdthreadstate);
     JSD_UNLOCK_THREADSTATES(jsdc);
     if( valid )
         return jsdthreadstate->context;
     return NULL;
-}        
+}
 
 JSDValue*
 jsd_GetException(JSDContext* jsdc, JSDThreadState* jsdthreadstate)
 {
     JSContext* cx;
-    jsval val;
+    JS::RootedValue val(cx);
 
     if(!(cx = _getContextForThreadState(jsdc, jsdthreadstate)))
         return NULL;
 
     if(JS_GetPendingException(cx, &val))
         return jsd_NewValue(jsdc, val);
     return NULL;
-}        
+}
 
 bool
-jsd_SetException(JSDContext* jsdc, JSDThreadState* jsdthreadstate, 
+jsd_SetException(JSDContext* jsdc, JSDThreadState* jsdthreadstate,
                  JSDValue* jsdval)
 {
     JSContext* cx;
 
     if(!(cx = _getContextForThreadState(jsdc, jsdthreadstate)))
         return false;
 
-    if(jsdval)
-        JS_SetPendingException(cx, JSD_GetValueWrappedJSVal(jsdc, jsdval));
-    else
+    if(jsdval) {
+        JS::RootedValue exn(cx, JSD_GetValueWrappedJSVal(jsdc, jsdval));
+        JS_SetPendingException(cx, exn);
+    } else {
         JS_ClearPendingException(cx);
+    }
     return true;
 }
 
--- a/js/jsd/jsd_val.cpp
+++ b/js/jsd/jsd_val.cpp
@@ -521,17 +521,17 @@ jsd_GetValueProperty(JSDContext* jsdc, J
             return NULL;
 
         JS_ClearPendingException(cx);
 
         if(!JS_GetPropertyById(cx, obj, id, &val))
         {
             if (JS_IsExceptionPending(cx))
             {
-                if (!JS_GetPendingException(cx, propValue.address()))
+                if (!JS_GetPendingException(cx, &propValue))
                 {
                     return NULL;
                 }
                 propFlags = JSPD_EXCEPTION;
             }
             else
             {
                 propFlags = JSPD_ERROR;
--- a/js/jsd/jsd_xpc.cpp
+++ b/js/jsd/jsd_xpc.cpp
@@ -490,27 +490,27 @@ jsds_ErrorHookProc (JSDContext *jsdc, JS
 
     nsCOMPtr<jsdIErrorHook> hook;
     gJsds->GetErrorHook(getter_AddRefs(hook));
     if (!hook)
         return JSD_ERROR_REPORTER_PASS_ALONG;
 
     if (running)
         return JSD_ERROR_REPORTER_PASS_ALONG;
-    
+
     running = true;
-    
+
     nsCOMPtr<jsdIValue> val;
     if (JS_IsExceptionPending(cx)) {
-        jsval jv;
+        JS::RootedValue jv(cx);
         JS_GetPendingException(cx, &jv);
         JSDValue *jsdv = JSD_NewValue (jsdc, jv);
         val = dont_AddRef(jsdValue::FromPtr(jsdc, jsdv));
     }
-    
+
     nsAutoCString fileName;
     uint32_t    line;
     uint32_t    pos;
     uint32_t    flags;
     uint32_t    errnum;
     bool        rval;
     if (report) {
         fileName.Assign(report->filename);
@@ -1994,17 +1994,17 @@ jsdStackFrame::Eval (const nsAString &by
 
     *_rval = JSD_AttemptUCScriptInStackFrame (mCx, mThreadState,
                                               mStackFrameInfo,
                                               char_bytes, bytes.Length(),
                                               PromiseFlatCString(fileName).get(),
                                               line, &jv);
     if (!*_rval) {
         if (JS_IsExceptionPending(cx))
-            JS_GetPendingException (cx, jv.address());
+            JS_GetPendingException (cx, &jv);
         else
             jv = JSVAL_NULL;
     }
 
     JS_RestoreExceptionState (cx, estate);
 
     JSDValue *jsdv = JSD_NewValue (mCx, jv);
     if (!jsdv)
--- a/js/src/ctypes/CTypes.cpp
+++ b/js/src/ctypes/CTypes.cpp
@@ -2585,17 +2585,17 @@ ExplicitConvert(JSContext* cx, HandleVal
   // If ImplicitConvert succeeds, use that result.
   if (ImplicitConvert(cx, val, targetType, buffer, false, NULL))
     return true;
 
   // If ImplicitConvert failed, and there is no pending exception, then assume
   // hard failure (out of memory, or some other similarly serious condition).
   // We store any pending exception in case we need to re-throw it.
   RootedValue ex(cx);
-  if (!JS_GetPendingException(cx, ex.address()))
+  if (!JS_GetPendingException(cx, &ex))
     return false;
 
   // Otherwise, assume soft failure. Clear the pending exception so that we
   // can throw a different one as required.
   JS_ClearPendingException(cx);
 
   TypeCode type = CType::GetTypeCode(targetType);
 
--- a/js/src/jsapi-tests/tests.h
+++ b/js/src/jsapi-tests/tests.h
@@ -204,17 +204,17 @@ class JSAPITest
         if (!(expr)) \
             return fail("CHECK failed: " #expr, __FILE__, __LINE__); \
     } while (false)
 
     bool fail(JSAPITestString msg = JSAPITestString(), const char *filename = "-", int lineno = 0) {
         if (JS_IsExceptionPending(cx)) {
             js::gc::AutoSuppressGC gcoff(cx);
             JS::RootedValue v(cx);
-            JS_GetPendingException(cx, v.address());
+            JS_GetPendingException(cx, &v);
             JS_ClearPendingException(cx);
             JSString *s = JS_ValueToString(cx, v);
             if (s) {
                 JSAutoByteString bytes(cx, s);
                 if (!!bytes)
                     msg += bytes.ptr();
             }
         }
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -5919,31 +5919,30 @@ JS_GetLocaleCallbacks(JSRuntime *rt)
 JS_PUBLIC_API(bool)
 JS_IsExceptionPending(JSContext *cx)
 {
     /* This function can be called by a finalizer. */
     return (bool) cx->isExceptionPending();
 }
 
 JS_PUBLIC_API(bool)
-JS_GetPendingException(JSContext *cx, jsval *vp)
+JS_GetPendingException(JSContext *cx, MutableHandleValue vp)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     if (!cx->isExceptionPending())
         return false;
-    *vp = cx->getPendingException();
-    assertSameCompartment(cx, *vp);
+    vp.set(cx->getPendingException());
+    assertSameCompartment(cx, vp);
     return true;
 }
 
 JS_PUBLIC_API(void)
-JS_SetPendingException(JSContext *cx, jsval valueArg)
-{
-    RootedValue value(cx, valueArg);
+JS_SetPendingException(JSContext *cx, HandleValue value)
+{
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, value);
     cx->setPendingException(value);
 }
 
 JS_PUBLIC_API(void)
 JS_ClearPendingException(JSContext *cx)
@@ -5970,31 +5969,32 @@ JS_PUBLIC_API(JSExceptionState *)
 JS_SaveExceptionState(JSContext *cx)
 {
     JSExceptionState *state;
 
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     state = cx->pod_malloc<JSExceptionState>();
     if (state) {
-        state->throwing = JS_GetPendingException(cx, &state->exception);
+        state->throwing =
+            JS_GetPendingException(cx, MutableHandleValue::fromMarkedLocation(&state->exception));
         if (state->throwing && JSVAL_IS_GCTHING(state->exception))
             AddValueRoot(cx, &state->exception, "JSExceptionState.exception");
     }
     return state;
 }
 
 JS_PUBLIC_API(void)
 JS_RestoreExceptionState(JSContext *cx, JSExceptionState *state)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     if (state) {
         if (state->throwing)
-            JS_SetPendingException(cx, state->exception);
+            JS_SetPendingException(cx, HandleValue::fromMarkedLocation(&state->exception));
         else
             JS_ClearPendingException(cx);
         JS_DropExceptionState(cx, state);
     }
 }
 
 JS_PUBLIC_API(void)
 JS_DropExceptionState(JSContext *cx, JSExceptionState *state)
@@ -6006,19 +6006,18 @@ JS_DropExceptionState(JSContext *cx, JSE
             assertSameCompartment(cx, state->exception);
             JS_RemoveValueRoot(cx, &state->exception);
         }
         js_free(state);
     }
 }
 
 JS_PUBLIC_API(JSErrorReport *)
-JS_ErrorFromException(JSContext *cx, jsval valueArg)
-{
-    RootedValue value(cx, valueArg);
+JS_ErrorFromException(JSContext *cx, HandleValue value)
+{
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, value);
     return js_ErrorFromException(value);
 }
 
 JS_PUBLIC_API(bool)
 JS_ThrowReportedError(JSContext *cx, const char *message,
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -4123,20 +4123,20 @@ extern JS_PUBLIC_API(JSString *)
 JS_GetRegExpSource(JSContext *cx, JS::HandleObject obj);
 
 /************************************************************************/
 
 extern JS_PUBLIC_API(bool)
 JS_IsExceptionPending(JSContext *cx);
 
 extern JS_PUBLIC_API(bool)
-JS_GetPendingException(JSContext *cx, jsval *vp);
+JS_GetPendingException(JSContext *cx, JS::MutableHandleValue vp);
 
 extern JS_PUBLIC_API(void)
-JS_SetPendingException(JSContext *cx, jsval v);
+JS_SetPendingException(JSContext *cx, JS::HandleValue v);
 
 extern JS_PUBLIC_API(void)
 JS_ClearPendingException(JSContext *cx);
 
 extern JS_PUBLIC_API(bool)
 JS_ReportPendingException(JSContext *cx);
 
 /*
@@ -4162,17 +4162,17 @@ JS_DropExceptionState(JSContext *cx, JSE
 /*
  * If the given value is an exception object that originated from an error,
  * the exception will contain an error report struct, and this API will return
  * the address of that struct.  Otherwise, it returns NULL.  The lifetime of
  * the error report struct that might be returned is the same as the lifetime
  * of the exception object.
  */
 extern JS_PUBLIC_API(JSErrorReport *)
-JS_ErrorFromException(JSContext *cx, jsval v);
+JS_ErrorFromException(JSContext *cx, JS::HandleValue v);
 
 /*
  * Given a reported error's message and JSErrorReport struct pointer, throw
  * the corresponding exception on cx.
  */
 extern JS_PUBLIC_API(bool)
 JS_ThrowReportedError(JSContext *cx, const char *message,
                       JSErrorReport *reportp);
--- a/js/src/jsexn.cpp
+++ b/js/src/jsexn.cpp
@@ -976,17 +976,18 @@ js_ErrorToException(JSContext *cx, const
         return false;
     tv[3] = STRING_TO_JSVAL(filenameStr);
 
     if (!InitExnPrivate(cx, errObject, messageStr, filenameStr,
                         reportp->lineno, reportp->column, reportp, exn)) {
         return false;
     }
 
-    JS_SetPendingException(cx, OBJECT_TO_JSVAL(errObject));
+    RootedValue errValue(cx, OBJECT_TO_JSVAL(errObject));
+    JS_SetPendingException(cx, errValue);
 
     /* Flag the error report passed in to indicate an exception was raised. */
     reportp->flags |= JSREPORT_EXCEPTION;
     return true;
 }
 
 static bool
 IsDuckTypedErrorObject(JSContext *cx, HandleObject exnObject, const char **filename_strp)
@@ -1014,17 +1015,17 @@ bool
 js_ReportUncaughtException(JSContext *cx)
 {
     JSErrorReport *reportp, report;
 
     if (!JS_IsExceptionPending(cx))
         return true;
 
     RootedValue exn(cx);
-    if (!JS_GetPendingException(cx, exn.address()))
+    if (!JS_GetPendingException(cx, &exn))
         return false;
 
     AutoValueVector roots(cx);
     roots.resize(6);
 
     /*
      * Because ToString below could error and an exception object could become
      * unrooted, we must root exnObject.  Later, if exnObject is non-null, we
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -845,17 +845,17 @@ class AutoNewContext
 
     JSContext *get() { return newcx; }
 
     ~AutoNewContext() {
         if (newcx) {
             RootedValue exc(oldcx);
             bool throwing = JS_IsExceptionPending(newcx);
             if (throwing)
-                JS_GetPendingException(newcx, exc.address());
+                JS_GetPendingException(newcx, &exc);
             newCompartment.destroy();
             newRequest.destroy();
             if (throwing)
                 JS_SetPendingException(oldcx, exc);
             DestroyContext(newcx, false);
         }
     }
 };
--- a/js/xpconnect/loader/mozJSComponentLoader.cpp
+++ b/js/xpconnect/loader/mozJSComponentLoader.cpp
@@ -962,17 +962,17 @@ mozJSComponentLoader::ObjectForLocation(
                                                nullptr, 0, nullptr,
                                                buf, bytesRead);
             }
         }
         // Propagate the exception, if one exists. Also, don't leave the stale
         // exception on this context.
         JS_SetOptions(cx, oldopts);
         if (!script && !function && aPropagateExceptions) {
-            JS_GetPendingException(cx, aException.address());
+            JS_GetPendingException(cx, aException);
             JS_ClearPendingException(cx);
         }
     }
 
     if (!script && !function) {
         return NS_ERROR_FAILURE;
     }
 
@@ -1015,17 +1015,17 @@ mozJSComponentLoader::ObjectForLocation(
     } else {
         jsval rval;
         ok = JS_CallFunction(cx, obj, function, 0, nullptr, &rval);
     }
     JS_SetOptions(cx, oldopts);
 
     if (!ok) {
         if (aPropagateExceptions) {
-            JS_GetPendingException(cx, aException.address());
+            JS_GetPendingException(cx, aException);
             JS_ClearPendingException(cx);
         }
         *aObject = nullptr;
         return NS_ERROR_FAILURE;
     }
 
     /* Freed when we remove from the table. */
     *aLocation = ToNewCString(nativePath);
--- a/js/xpconnect/loader/mozJSSubScriptLoader.cpp
+++ b/js/xpconnect/loader/mozJSSubScriptLoader.cpp
@@ -57,17 +57,18 @@ mozJSSubScriptLoader::~mozJSSubScriptLoa
     /* empty */
 }
 
 NS_IMPL_ISUPPORTS1(mozJSSubScriptLoader, mozIJSSubScriptLoader)
 
 static nsresult
 ReportError(JSContext *cx, const char *msg)
 {
-    JS_SetPendingException(cx, STRING_TO_JSVAL(JS_NewStringCopyZ(cx, msg)));
+    RootedValue exn(cx, JS::StringValue(JS_NewStringCopyZ(cx, msg)));
+    JS_SetPendingException(cx, exn);
     return NS_OK;
 }
 
 nsresult
 mozJSSubScriptLoader::ReadScript(nsIURI *uri, JSContext *cx, JSObject *targetObjArg,
                                  const nsAString& charset, const char *uriStr,
                                  nsIIOService *serv, nsIPrincipal *principal,
                                  bool reuseGlobal, JSScript **scriptp,
--- a/js/xpconnect/src/Sandbox.cpp
+++ b/js/xpconnect/src/Sandbox.cpp
@@ -1547,17 +1547,17 @@ xpc::EvalInSandbox(JSContext *cx, Handle
                           v.address());
         if (ok && returnStringOnly && !v.isUndefined()) {
             JSString *str = JS_ValueToString(sandcx, v);
             ok = !!str;
             v = ok ? JS::StringValue(str) : JS::UndefinedValue();
         }
 
         // If the sandbox threw an exception, grab it off the context.
-        if (JS_GetPendingException(sandcx, exn.address())) {
+        if (JS_GetPendingException(sandcx, &exn)) {
             MOZ_ASSERT(!ok);
             JS_ClearPendingException(sandcx);
             if (returnStringOnly) {
                 // The caller asked for strings only, convert the
                 // exception into a string.
                 JSString *str = JS_ValueToString(sandcx, exn);
                 exn = str ? JS::StringValue(str) : JS::UndefinedValue();
             }
--- a/js/xpconnect/src/XPCWrappedJSClass.cpp
+++ b/js/xpconnect/src/XPCWrappedJSClass.cpp
@@ -250,17 +250,17 @@ nsXPCWrappedJSClass::CallQueryInterfaceO
         jsval args[1] = {OBJECT_TO_JSVAL(id)};
         success = JS_CallFunctionValue(cx, jsobj, fun, 1, args, retval.address());
 
         JS_SetOptions(cx, oldOpts);
 
         if (!success && JS_IsExceptionPending(cx)) {
             RootedValue jsexception(cx, NullValue());
 
-            if (JS_GetPendingException(cx, jsexception.address())) {
+            if (JS_GetPendingException(cx, &jsexception)) {
                 nsresult rv;
                 if (jsexception.isObject()) {
                     // XPConnect may have constructed an object to represent a
                     // C++ QI failure. See if that is the case.
                     using namespace mozilla::dom;
                     Exception *e = nullptr;
                     UNWRAP_OBJECT(Exception, cx, &jsexception.toObject(), e);
 
@@ -936,17 +936,17 @@ nsXPCWrappedJSClass::CheckForException(X
     if (xpc_exception)
         xpcc->SetException(nullptr);
 
     // get this right away in case we do something below to cause JS code
     // to run on this JSContext
     nsresult pending_result = xpcc->GetPendingResult();
 
     RootedValue js_exception(cx);
-    bool is_js_exception = JS_GetPendingException(cx, js_exception.address());
+    bool is_js_exception = JS_GetPendingException(cx, &js_exception);
 
     /* JS might throw an expection whether the reporter was called or not */
     if (is_js_exception) {
         if (!xpc_exception)
             XPCConvert::JSValToXPCException(&js_exception, anInterfaceName,
                                             aPropertyName,
                                             getter_AddRefs(xpc_exception));