зеркало из https://github.com/mozilla/gecko-dev.git
Bug 839088 part 2. Add way to indicate to a CallSetup that it should propagate any exceptions thrown during the call out to the ErrorResult for the call. r=peterv
This commit is contained in:
Родитель
ea45d30665
Коммит
624e0560d5
|
@ -33,8 +33,12 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(CallbackObject)
|
|||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mCallback)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
|
||||
CallbackObject::CallSetup::CallSetup(JSObject* const aCallback)
|
||||
CallbackObject::CallSetup::CallSetup(JSObject* const aCallback,
|
||||
ErrorResult& aRv,
|
||||
ExceptionHandling aExceptionHandling)
|
||||
: mCx(nullptr)
|
||||
, mErrorResult(aRv)
|
||||
, mExceptionHandling(aExceptionHandling)
|
||||
{
|
||||
xpc_UnmarkGrayObject(aCallback);
|
||||
|
||||
|
@ -123,14 +127,40 @@ CallbackObject::CallSetup::CallSetup(JSObject* const aCallback)
|
|||
|
||||
// And now we're ready to go.
|
||||
mCx = cx;
|
||||
|
||||
// Make sure the JS engine doesn't report exceptions we want to re-throw
|
||||
if (mExceptionHandling == eRethrowExceptions) {
|
||||
mSavedJSContextOptions = JS_GetOptions(cx);
|
||||
JS_SetOptions(cx, mSavedJSContextOptions | JSOPTION_DONT_REPORT_UNCAUGHT);
|
||||
}
|
||||
}
|
||||
|
||||
CallbackObject::CallSetup::~CallSetup()
|
||||
{
|
||||
// First things first: if we have a JSContext, report any pending
|
||||
// errors on it.
|
||||
// errors on it, unless we were told to re-throw them.
|
||||
if (mCx) {
|
||||
nsJSUtils::ReportPendingException(mCx);
|
||||
bool dealtWithPendingException = false;
|
||||
if (mExceptionHandling == eRethrowExceptions) {
|
||||
// Restore the old context options
|
||||
JS_SetOptions(mCx, mSavedJSContextOptions);
|
||||
mErrorResult.MightThrowJSException();
|
||||
if (JS_IsExceptionPending(mCx)) {
|
||||
JS::Value exn;
|
||||
if (JS_GetPendingException(mCx, &exn)) {
|
||||
mErrorResult.ThrowJSException(mCx, exn);
|
||||
JS_ClearPendingException(mCx);
|
||||
dealtWithPendingException = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!dealtWithPendingException) {
|
||||
// Either we're supposed to report our exceptions, or we're supposed to
|
||||
// re-throw them but we failed to JS_GetPendingException. Either way,
|
||||
// just report the pending exception, if any.
|
||||
nsJSUtils::ReportPendingException(mCx);
|
||||
}
|
||||
}
|
||||
|
||||
// If we have an mCtx, we need to call ScriptEvaluated() on it. But we have
|
||||
|
|
|
@ -81,6 +81,11 @@ public:
|
|||
return mCallback;
|
||||
}
|
||||
|
||||
enum ExceptionHandling {
|
||||
eReportExceptions,
|
||||
eRethrowExceptions
|
||||
};
|
||||
|
||||
protected:
|
||||
explicit CallbackObject(CallbackObject* aCallbackFunction)
|
||||
: mCallback(aCallbackFunction->mCallback)
|
||||
|
@ -112,7 +117,8 @@ protected:
|
|||
* non-null.
|
||||
*/
|
||||
public:
|
||||
CallSetup(JSObject* const aCallable);
|
||||
CallSetup(JSObject* const aCallable, ErrorResult& aRv,
|
||||
ExceptionHandling aExceptionHandling);
|
||||
~CallSetup();
|
||||
|
||||
JSContext* GetContext() const
|
||||
|
@ -149,6 +155,12 @@ protected:
|
|||
// JSContext. Though in practice we'll often manually order those two
|
||||
// things.
|
||||
Maybe<JSAutoCompartment> mAc;
|
||||
|
||||
// An ErrorResult to possibly re-throw exceptions on and whether
|
||||
// we should re-throw them.
|
||||
ErrorResult& mErrorResult;
|
||||
const ExceptionHandling mExceptionHandling;
|
||||
uint32_t mSavedJSContextOptions;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -7707,7 +7707,7 @@ class CGCallback(CGClass):
|
|||
argsWithoutThis = list(args)
|
||||
args.insert(0, Argument("const T&", "thisObj"))
|
||||
|
||||
setupCall = ("CallSetup s(mCallback);\n"
|
||||
setupCall = ("CallSetup s(mCallback, aRv, eReportExceptions);\n"
|
||||
"if (!s.GetContext()) {\n"
|
||||
" aRv.Throw(NS_ERROR_UNEXPECTED);\n"
|
||||
" return${errorReturn};\n"
|
||||
|
@ -7970,7 +7970,7 @@ class CallbackMember(CGNativeMember):
|
|||
# It's been done for us already
|
||||
return ""
|
||||
return string.Template(
|
||||
"CallSetup s(mCallback);\n"
|
||||
"CallSetup s(mCallback, aRv, eReportExceptions);\n"
|
||||
"JSContext* cx = s.GetContext();\n"
|
||||
"if (!cx) {\n"
|
||||
" aRv.Throw(NS_ERROR_UNEXPECTED);\n"
|
||||
|
|
Загрузка…
Ссылка в новой задаче