Bug 1254847 part 2. Change nsJSNPRuntime to always use AutoEntryScript and always take ownership of error reporting. r=bholley

The main change is that we move AutoJSExceptionReporter up to before the first
place where we might throw an exception, so we report those exceptions before
returning.  The change to use AutoEntryScript consistently is because all of
these callsites can run JS in practice, and it seems reasonable to allow them
to.
This commit is contained in:
Boris Zbarsky 2016-03-09 19:02:03 -05:00
Родитель 0f63c48348
Коммит 6b80989ddf
1 изменённых файлов: 53 добавлений и 32 удалений

Просмотреть файл

@ -131,28 +131,31 @@ NPObjectIsOutOfProcessProxy(NPObject *obj)
} // namespace
// Helper class that reports any JS exceptions that were thrown while
// the plugin executed JS.
// Helper class that suppresses any JS exceptions that were thrown while
// the plugin executed JS, if the nsJSObjWrapper has a destroy pending.
// Note that this class is the product (vestige?) of a long evolution in how
// error reporting worked, and hence the mIsDestroyPending check, and hence this
// class in general, may or may not actually be necessary.
class MOZ_STACK_CLASS AutoJSExceptionReporter
class MOZ_STACK_CLASS AutoJSExceptionSuppressor
{
public:
AutoJSExceptionReporter(dom::AutoJSAPI& jsapi, nsJSObjWrapper* aWrapper)
: mJsapi(jsapi)
AutoJSExceptionSuppressor(dom::AutoEntryScript& aes, nsJSObjWrapper* aWrapper)
: mAes(aes)
, mIsDestroyPending(aWrapper->mDestroyPending)
{
jsapi.TakeOwnershipOfErrorReporting();
MOZ_ASSERT(aes.OwnsErrorReporting());
}
~AutoJSExceptionReporter()
~AutoJSExceptionSuppressor()
{
if (mIsDestroyPending) {
mJsapi.ClearException();
mAes.ClearException();
}
}
protected:
dom::AutoJSAPI& mJsapi;
dom::AutoEntryScript& mAes;
bool mIsDestroyPending;
};
@ -728,11 +731,14 @@ bool
nsJSObjWrapper::NP_HasMethod(NPObject *npobj, NPIdentifier id)
{
NPP npp = NPPStack::Peek();
dom::AutoJSAPI jsapi;
if (NS_WARN_IF(!jsapi.InitWithLegacyErrorReporting(GetGlobalObject(npp)))) {
nsIGlobalObject* globalObject = GetGlobalObject(npp);
if (NS_WARN_IF(!globalObject)) {
return false;
}
JSContext *cx = jsapi.cx();
dom::AutoEntryScript aes(globalObject, "NPAPI HasMethod");
aes.TakeOwnershipOfErrorReporting();
JSContext *cx = aes.cx();
if (!npobj) {
ThrowJSException(cx,
@ -745,7 +751,7 @@ nsJSObjWrapper::NP_HasMethod(NPObject *npobj, NPIdentifier id)
JSAutoCompartment ac(cx, npjsobj->mJSObj);
AutoJSExceptionReporter reporter(jsapi, npjsobj);
AutoJSExceptionSuppressor suppressor(aes, npjsobj);
JS::Rooted<JS::Value> v(cx);
bool ok = GetProperty(cx, npjsobj->mJSObj, id, &v);
@ -768,6 +774,7 @@ doInvoke(NPObject *npobj, NPIdentifier method, const NPVariant *args,
// We're about to run script via JS_CallFunctionValue, so we need an
// AutoEntryScript. NPAPI plugins are Gecko-specific and not in any spec.
dom::AutoEntryScript aes(globalObject, "NPAPI doInvoke");
aes.TakeOwnershipOfErrorReporting();
JSContext *cx = aes.cx();
if (!npobj || !result) {
@ -785,7 +792,7 @@ doInvoke(NPObject *npobj, NPIdentifier method, const NPVariant *args,
JSAutoCompartment ac(cx, jsobj);
JS::Rooted<JS::Value> fv(cx);
AutoJSExceptionReporter reporter(aes, npjsobj);
AutoJSExceptionSuppressor suppressor(aes, npjsobj);
if (method != NPIdentifier_VOID) {
if (!GetProperty(cx, jsobj, method, &fv) ||
@ -854,11 +861,14 @@ bool
nsJSObjWrapper::NP_HasProperty(NPObject *npobj, NPIdentifier npid)
{
NPP npp = NPPStack::Peek();
dom::AutoJSAPI jsapi;
if (NS_WARN_IF(!jsapi.InitWithLegacyErrorReporting(GetGlobalObject(npp)))) {
nsIGlobalObject* globalObject = GetGlobalObject(npp);
if (NS_WARN_IF(!globalObject)) {
return false;
}
JSContext *cx = jsapi.cx();
dom::AutoEntryScript aes(globalObject, "NPAPI HasProperty");
aes.TakeOwnershipOfErrorReporting();
JSContext *cx = aes.cx();
if (!npobj) {
ThrowJSException(cx,
@ -870,7 +880,7 @@ nsJSObjWrapper::NP_HasProperty(NPObject *npobj, NPIdentifier npid)
nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj;
bool found, ok = false;
AutoJSExceptionReporter reporter(jsapi, npjsobj);
AutoJSExceptionSuppressor suppressor(aes, npjsobj);
JS::Rooted<JSObject*> jsobj(cx, npjsobj->mJSObj);
JSAutoCompartment ac(cx, jsobj);
@ -896,6 +906,7 @@ nsJSObjWrapper::NP_GetProperty(NPObject *npobj, NPIdentifier id,
// We're about to run script via JS_CallFunctionValue, so we need an
// AutoEntryScript. NPAPI plugins are Gecko-specific and not in any spec.
dom::AutoEntryScript aes(globalObject, "NPAPI get");
aes.TakeOwnershipOfErrorReporting();
JSContext *cx = aes.cx();
if (!npobj) {
@ -907,7 +918,7 @@ nsJSObjWrapper::NP_GetProperty(NPObject *npobj, NPIdentifier id,
nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj;
AutoJSExceptionReporter reporter(aes, npjsobj);
AutoJSExceptionSuppressor suppressor(aes, npjsobj);
JSAutoCompartment ac(cx, npjsobj->mJSObj);
JS::Rooted<JS::Value> v(cx);
@ -930,6 +941,7 @@ nsJSObjWrapper::NP_SetProperty(NPObject *npobj, NPIdentifier npid,
// We're about to run script via JS_CallFunctionValue, so we need an
// AutoEntryScript. NPAPI plugins are Gecko-specific and not in any spec.
dom::AutoEntryScript aes(globalObject, "NPAPI set");
aes.TakeOwnershipOfErrorReporting();
JSContext *cx = aes.cx();
if (!npobj) {
@ -942,7 +954,7 @@ nsJSObjWrapper::NP_SetProperty(NPObject *npobj, NPIdentifier npid,
nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj;
bool ok = false;
AutoJSExceptionReporter reporter(aes, npjsobj);
AutoJSExceptionSuppressor suppressor(aes, npjsobj);
JS::Rooted<JSObject*> jsObj(cx, npjsobj->mJSObj);
JSAutoCompartment ac(cx, jsObj);
@ -961,11 +973,14 @@ bool
nsJSObjWrapper::NP_RemoveProperty(NPObject *npobj, NPIdentifier npid)
{
NPP npp = NPPStack::Peek();
dom::AutoJSAPI jsapi;
if (NS_WARN_IF(!jsapi.InitWithLegacyErrorReporting(GetGlobalObject(npp)))) {
nsIGlobalObject* globalObject = GetGlobalObject(npp);
if (NS_WARN_IF(!globalObject)) {
return false;
}
JSContext *cx = jsapi.cx();
dom::AutoEntryScript aes(globalObject, "NPAPI RemoveProperty");
aes.TakeOwnershipOfErrorReporting();
JSContext *cx = aes.cx();
if (!npobj) {
ThrowJSException(cx,
@ -976,7 +991,7 @@ nsJSObjWrapper::NP_RemoveProperty(NPObject *npobj, NPIdentifier npid)
nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj;
AutoJSExceptionReporter reporter(jsapi, npjsobj);
AutoJSExceptionSuppressor suppressor(aes, npjsobj);
JS::ObjectOpResult result;
JS::Rooted<JSObject*> obj(cx, npjsobj->mJSObj);
JSAutoCompartment ac(cx, obj);
@ -1010,11 +1025,14 @@ nsJSObjWrapper::NP_Enumerate(NPObject *npobj, NPIdentifier **idarray,
uint32_t *count)
{
NPP npp = NPPStack::Peek();
dom::AutoJSAPI jsapi;
if (NS_WARN_IF(!jsapi.InitWithLegacyErrorReporting(GetGlobalObject(npp)))) {
nsIGlobalObject* globalObject = GetGlobalObject(npp);
if (NS_WARN_IF(!globalObject)) {
return false;
}
JSContext *cx = jsapi.cx();
dom::AutoEntryScript aes(globalObject, "NPAPI Enumerate");
aes.TakeOwnershipOfErrorReporting();
JSContext *cx = aes.cx();
*idarray = 0;
*count = 0;
@ -1028,7 +1046,7 @@ nsJSObjWrapper::NP_Enumerate(NPObject *npobj, NPIdentifier **idarray,
nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj;
AutoJSExceptionReporter reporter(jsapi, npjsobj);
AutoJSExceptionSuppressor suppressor(aes, npjsobj);
JS::Rooted<JSObject*> jsobj(cx, npjsobj->mJSObj);
JSAutoCompartment ac(cx, jsobj);
@ -2280,11 +2298,14 @@ bool
nsJSObjWrapper::HasOwnProperty(NPObject *npobj, NPIdentifier npid)
{
NPP npp = NPPStack::Peek();
dom::AutoJSAPI jsapi;
if (NS_WARN_IF(!jsapi.InitWithLegacyErrorReporting(GetGlobalObject(npp)))) {
nsIGlobalObject* globalObject = GetGlobalObject(npp);
if (NS_WARN_IF(!globalObject)) {
return false;
}
JSContext *cx = jsapi.cx();
dom::AutoEntryScript aes(globalObject, "NPAPI HasOwnProperty");
aes.TakeOwnershipOfErrorReporting();
JSContext *cx = aes.cx();
if (!npobj) {
ThrowJSException(cx,
@ -2296,7 +2317,7 @@ nsJSObjWrapper::HasOwnProperty(NPObject *npobj, NPIdentifier npid)
nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj;
bool found, ok = false;
AutoJSExceptionReporter reporter(jsapi, npjsobj);
AutoJSExceptionSuppressor suppressor(aes, npjsobj);
JS::Rooted<JSObject*> jsobj(cx, npjsobj->mJSObj);
JSAutoCompartment ac(cx, jsobj);