From 38b602931b1ce6f89a6e0571bf27df95c9ab14ac Mon Sep 17 00:00:00 2001 From: Jon Coppeard Date: Thu, 19 Sep 2013 08:54:01 +0100 Subject: [PATCH] Bug 917798 - Handlify JS exception APIs r=terrence r=bz --- dom/base/nsDOMClassInfo.cpp | 2 +- dom/base/nsJSUtils.cpp | 6 +++++- dom/bindings/BindingUtils.cpp | 3 ++- dom/bindings/CallbackObject.cpp | 2 +- dom/bindings/Exceptions.cpp | 3 ++- dom/plugins/base/nsJSNPRuntime.cpp | 3 ++- js/ipc/JavaScriptChild.cpp | 2 +- js/jsd/jsd_hook.cpp | 11 +++++++---- js/jsd/jsd_stak.cpp | 18 ++++++++++-------- js/jsd/jsd_val.cpp | 2 +- js/jsd/jsd_xpc.cpp | 10 +++++----- js/src/ctypes/CTypes.cpp | 2 +- js/src/jsapi-tests/tests.h | 2 +- js/src/jsapi.cpp | 17 ++++++++--------- js/src/jsapi.h | 6 +++--- js/src/jsexn.cpp | 5 +++-- js/src/shell/js.cpp | 2 +- js/xpconnect/loader/mozJSComponentLoader.cpp | 4 ++-- js/xpconnect/loader/mozJSSubScriptLoader.cpp | 3 ++- js/xpconnect/src/Sandbox.cpp | 2 +- js/xpconnect/src/XPCWrappedJSClass.cpp | 4 ++-- 21 files changed, 61 insertions(+), 48 deletions(-) diff --git a/dom/base/nsDOMClassInfo.cpp b/dom/base/nsDOMClassInfo.cpp index 777abc9030b..59859940534 100644 --- a/dom/base/nsDOMClassInfo.cpp +++ b/dom/base/nsDOMClassInfo.cpp @@ -3530,7 +3530,7 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx, // 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; } diff --git a/dom/base/nsJSUtils.cpp b/dom/base/nsJSUtils.cpp index a4928fee22b..8aebacb86df 100644 --- a/dom/base/nsJSUtils.cpp +++ b/dom/base/nsJSUtils.cpp @@ -296,7 +296,11 @@ nsJSUtils::EvaluateString(JSContext* aCx, } 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); } } diff --git a/dom/bindings/BindingUtils.cpp b/dom/bindings/BindingUtils.cpp index d241edef033..d2edabddc93 100644 --- a/dom/bindings/BindingUtils.cpp +++ b/dom/bindings/BindingUtils.cpp @@ -181,7 +181,8 @@ 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. diff --git a/dom/bindings/CallbackObject.cpp b/dom/bindings/CallbackObject.cpp index 16b31d5d01e..e4421b4afc0 100644 --- a/dom/bindings/CallbackObject.cpp +++ b/dom/bindings/CallbackObject.cpp @@ -186,7 +186,7 @@ CallbackObject::CallSetup::~CallSetup() mErrorResult.MightThrowJSException(); if (JS_IsExceptionPending(mCx)) { JS::Rooted exn(mCx); - if (JS_GetPendingException(mCx, exn.address()) && + if (JS_GetPendingException(mCx, &exn) && ShouldRethrowException(exn)) { mErrorResult.ThrowJSException(mCx, exn); JS_ClearPendingException(mCx); diff --git a/dom/bindings/Exceptions.cpp b/dom/bindings/Exceptions.cpp index 4db1c63fe3a..368d0cddcfc 100644 --- a/dom/bindings/Exceptions.cpp +++ b/dom/bindings/Exceptions.cpp @@ -71,7 +71,8 @@ ThrowExceptionObject(JSContext* aCx, nsIException* aException) return false; } - JS_SetPendingException(aCx, OBJECT_TO_JSVAL(obj)); + JS::RootedValue exn(aCx, JS::ObjectOrNullValue(obj)); + JS_SetPendingException(aCx, exn); return true; } diff --git a/dom/plugins/base/nsJSNPRuntime.cpp b/dom/plugins/base/nsJSNPRuntime.cpp index a214655b44a..9f16519c3a2 100644 --- a/dom/plugins/base/nsJSNPRuntime.cpp +++ b/dom/plugins/base/nsJSNPRuntime.cpp @@ -457,7 +457,8 @@ ThrowJSException(JSContext *cx, const char *message) ucex.Length()); if (str) { - ::JS_SetPendingException(cx, STRING_TO_JSVAL(str)); + JS::RootedValue exn(cx, JS::StringValue(str)); + ::JS_SetPendingException(cx, exn); } PopException(); diff --git a/js/ipc/JavaScriptChild.cpp b/js/ipc/JavaScriptChild.cpp index 7a87e15fb6a..8343e8b1f1f 100644 --- a/js/ipc/JavaScriptChild.cpp +++ b/js/ipc/JavaScriptChild.cpp @@ -118,7 +118,7 @@ JavaScriptChild::fail(JSContext *cx, ReturnStatus *rs) // 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; diff --git a/js/jsd/jsd_hook.cpp b/js/jsd/jsd_hook.cpp index 63bd0adfbbf..33986aeb215 100644 --- a/js/jsd/jsd_hook.cpp +++ b/js/jsd/jsd_hook.cpp @@ -80,7 +80,7 @@ jsd_DebuggerHandler(JSContext *cx, JSScript *script, jsbytecode *pc, JSTrapStatus jsd_ThrowHandler(JSContext *cx, JSScript *script, jsbytecode *pc, - jsval *rval, void *closure) + jsval *rvalArg, void *closure) { JSDScript* jsdscript; JSDContext* jsdc = (JSDContext*) closure; @@ -107,10 +107,13 @@ jsd_ThrowHandler(JSContext *cx, JSScript *script, jsbytecode *pc, 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 diff --git a/js/jsd/jsd_stak.cpp b/js/jsd/jsd_stak.cpp index 0b562d31606..f73dc323449 100644 --- a/js/jsd/jsd_stak.cpp +++ b/js/jsd/jsd_stak.cpp @@ -524,7 +524,7 @@ jsd_IsValidFrameInThreadState(JSDContext* jsdc, JSD_ASSERT_VALID_THREAD_STATE(jsdthreadstate); JSD_ASSERT_VALID_STACK_FRAME(jsdframe); - + return true; } @@ -538,13 +538,13 @@ _getContextForThreadState(JSDContext* jsdc, JSDThreadState* jsdthreadstate) 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; @@ -552,10 +552,10 @@ jsd_GetException(JSDContext* jsdc, JSDThreadState* jsdthreadstate) 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; @@ -563,10 +563,12 @@ jsd_SetException(JSDContext* jsdc, JSDThreadState* jsdthreadstate, 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; } diff --git a/js/jsd/jsd_val.cpp b/js/jsd/jsd_val.cpp index 007327cb153..fcac01c4469 100644 --- a/js/jsd/jsd_val.cpp +++ b/js/jsd/jsd_val.cpp @@ -526,7 +526,7 @@ jsd_GetValueProperty(JSDContext* jsdc, JSDValue* jsdval, JSString* nameStr) { if (JS_IsExceptionPending(cx)) { - if (!JS_GetPendingException(cx, propValue.address())) + if (!JS_GetPendingException(cx, &propValue)) { return NULL; } diff --git a/js/jsd/jsd_xpc.cpp b/js/jsd/jsd_xpc.cpp index 8cf561b6111..eb4f8be5fd3 100644 --- a/js/jsd/jsd_xpc.cpp +++ b/js/jsd/jsd_xpc.cpp @@ -495,17 +495,17 @@ jsds_ErrorHookProc (JSDContext *jsdc, JSContext *cx, const char *message, if (running) return JSD_ERROR_REPORTER_PASS_ALONG; - + running = true; - + nsCOMPtr 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; @@ -1999,7 +1999,7 @@ jsdStackFrame::Eval (const nsAString &bytes, const nsACString &fileName, line, &jv); if (!*_rval) { if (JS_IsExceptionPending(cx)) - JS_GetPendingException (cx, jv.address()); + JS_GetPendingException (cx, &jv); else jv = JSVAL_NULL; } diff --git a/js/src/ctypes/CTypes.cpp b/js/src/ctypes/CTypes.cpp index 2472709d471..e7c5ffd3bd2 100644 --- a/js/src/ctypes/CTypes.cpp +++ b/js/src/ctypes/CTypes.cpp @@ -2590,7 +2590,7 @@ ExplicitConvert(JSContext* cx, HandleValue val, HandleObject targetType, void* b // 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 diff --git a/js/src/jsapi-tests/tests.h b/js/src/jsapi-tests/tests.h index f253cc89c19..df9676af1a9 100644 --- a/js/src/jsapi-tests/tests.h +++ b/js/src/jsapi-tests/tests.h @@ -209,7 +209,7 @@ class JSAPITest 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) { diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index d298f8c433c..81a1abbb197 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -5924,21 +5924,20 @@ JS_IsExceptionPending(JSContext *cx) } 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) +JS_SetPendingException(JSContext *cx, HandleValue value) { - RootedValue value(cx, valueArg); AssertHeapIsIdle(cx); CHECK_REQUEST(cx); assertSameCompartment(cx, value); @@ -5975,7 +5974,8 @@ JS_SaveExceptionState(JSContext *cx) CHECK_REQUEST(cx); state = cx->pod_malloc(); 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"); } @@ -5989,7 +5989,7 @@ JS_RestoreExceptionState(JSContext *cx, JSExceptionState *state) 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); @@ -6011,9 +6011,8 @@ JS_DropExceptionState(JSContext *cx, JSExceptionState *state) } JS_PUBLIC_API(JSErrorReport *) -JS_ErrorFromException(JSContext *cx, jsval valueArg) +JS_ErrorFromException(JSContext *cx, HandleValue value) { - RootedValue value(cx, valueArg); AssertHeapIsIdle(cx); CHECK_REQUEST(cx); assertSameCompartment(cx, value); diff --git a/js/src/jsapi.h b/js/src/jsapi.h index 1c123e2401b..739b353ccd3 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -4128,10 +4128,10 @@ 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); @@ -4167,7 +4167,7 @@ JS_DropExceptionState(JSContext *cx, JSExceptionState *state); * 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 diff --git a/js/src/jsexn.cpp b/js/src/jsexn.cpp index 0d01eb18c46..9cd64eb437a 100644 --- a/js/src/jsexn.cpp +++ b/js/src/jsexn.cpp @@ -981,7 +981,8 @@ js_ErrorToException(JSContext *cx, const char *message, JSErrorReport *reportp, 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; @@ -1019,7 +1020,7 @@ js_ReportUncaughtException(JSContext *cx) return true; RootedValue exn(cx); - if (!JS_GetPendingException(cx, exn.address())) + if (!JS_GetPendingException(cx, &exn)) return false; AutoValueVector roots(cx); diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index 3910b1fba15..97026dd3061 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -850,7 +850,7 @@ class AutoNewContext 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) diff --git a/js/xpconnect/loader/mozJSComponentLoader.cpp b/js/xpconnect/loader/mozJSComponentLoader.cpp index c2b2cf36c0a..07641adbe00 100644 --- a/js/xpconnect/loader/mozJSComponentLoader.cpp +++ b/js/xpconnect/loader/mozJSComponentLoader.cpp @@ -967,7 +967,7 @@ mozJSComponentLoader::ObjectForLocation(nsIFile *aComponentFile, // exception on this context. JS_SetOptions(cx, oldopts); if (!script && !function && aPropagateExceptions) { - JS_GetPendingException(cx, aException.address()); + JS_GetPendingException(cx, aException); JS_ClearPendingException(cx); } } @@ -1020,7 +1020,7 @@ mozJSComponentLoader::ObjectForLocation(nsIFile *aComponentFile, if (!ok) { if (aPropagateExceptions) { - JS_GetPendingException(cx, aException.address()); + JS_GetPendingException(cx, aException); JS_ClearPendingException(cx); } *aObject = nullptr; diff --git a/js/xpconnect/loader/mozJSSubScriptLoader.cpp b/js/xpconnect/loader/mozJSSubScriptLoader.cpp index 3b91e2c6bac..62497d97c53 100644 --- a/js/xpconnect/loader/mozJSSubScriptLoader.cpp +++ b/js/xpconnect/loader/mozJSSubScriptLoader.cpp @@ -62,7 +62,8 @@ 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; } diff --git a/js/xpconnect/src/Sandbox.cpp b/js/xpconnect/src/Sandbox.cpp index 00d81ad0a43..e82abce73b2 100644 --- a/js/xpconnect/src/Sandbox.cpp +++ b/js/xpconnect/src/Sandbox.cpp @@ -1552,7 +1552,7 @@ xpc::EvalInSandbox(JSContext *cx, HandleObject sandboxArg, const nsAString& sour } // 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) { diff --git a/js/xpconnect/src/XPCWrappedJSClass.cpp b/js/xpconnect/src/XPCWrappedJSClass.cpp index ac123f4f25e..6a2b3aa4209 100644 --- a/js/xpconnect/src/XPCWrappedJSClass.cpp +++ b/js/xpconnect/src/XPCWrappedJSClass.cpp @@ -255,7 +255,7 @@ nsXPCWrappedJSClass::CallQueryInterfaceOnJSObject(JSContext* cx, 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 @@ -941,7 +941,7 @@ nsXPCWrappedJSClass::CheckForException(XPCCallContext & ccx, 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) {