mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-13 05:15:45 +00:00
Bug 1135491: Part 2 - Changes to nsJSNPRuntime to ensure that JS exceptions aren't thrown when plugin destruction is pending; r=josh,bholley
--HG-- extra : rebase_source : 450766689e0c0bf1cfa8c52f4e4051e2214715f2
This commit is contained in:
parent
30dc911b8c
commit
623be0b606
@ -122,21 +122,26 @@ NPObjectIsOutOfProcessProxy(NPObject *obj)
|
||||
// Helper class that reports any JS exceptions that were thrown while
|
||||
// the plugin executed JS.
|
||||
|
||||
class AutoJSExceptionReporter
|
||||
class MOZ_STACK_CLASS AutoJSExceptionReporter
|
||||
{
|
||||
public:
|
||||
explicit AutoJSExceptionReporter(JSContext* aCx)
|
||||
: mCx(aCx)
|
||||
AutoJSExceptionReporter(dom::AutoJSAPI& jsapi, nsJSObjWrapper* aWrapper)
|
||||
: mJsapi(jsapi)
|
||||
, mIsDestroyPending(aWrapper->mDestroyPending)
|
||||
{
|
||||
jsapi.TakeOwnershipOfErrorReporting();
|
||||
}
|
||||
|
||||
~AutoJSExceptionReporter()
|
||||
{
|
||||
JS_ReportPendingException(mCx);
|
||||
if (mIsDestroyPending) {
|
||||
mJsapi.ClearException();
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
JSContext *mCx;
|
||||
dom::AutoJSAPI& mJsapi;
|
||||
bool mIsDestroyPending;
|
||||
};
|
||||
|
||||
|
||||
@ -746,7 +751,7 @@ nsJSObjWrapper::NP_HasMethod(NPObject *npobj, NPIdentifier id)
|
||||
|
||||
JSAutoCompartment ac(cx, npjsobj->mJSObj);
|
||||
|
||||
AutoJSExceptionReporter reporter(cx);
|
||||
AutoJSExceptionReporter reporter(jsapi, npjsobj);
|
||||
|
||||
JS::Rooted<JS::Value> v(cx);
|
||||
bool ok = GetProperty(cx, npjsobj->mJSObj, id, &v);
|
||||
@ -786,7 +791,7 @@ doInvoke(NPObject *npobj, NPIdentifier method, const NPVariant *args,
|
||||
JSAutoCompartment ac(cx, jsobj);
|
||||
JS::Rooted<JS::Value> fv(cx);
|
||||
|
||||
AutoJSExceptionReporter reporter(cx);
|
||||
AutoJSExceptionReporter reporter(aes, npjsobj);
|
||||
|
||||
if (method != NPIdentifier_VOID) {
|
||||
if (!GetProperty(cx, jsobj, method, &fv) ||
|
||||
@ -871,7 +876,7 @@ nsJSObjWrapper::NP_HasProperty(NPObject *npobj, NPIdentifier npid)
|
||||
nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj;
|
||||
bool found, ok = false;
|
||||
|
||||
AutoJSExceptionReporter reporter(cx);
|
||||
AutoJSExceptionReporter reporter(jsapi, npjsobj);
|
||||
JS::Rooted<JSObject*> jsobj(cx, npjsobj->mJSObj);
|
||||
JSAutoCompartment ac(cx, jsobj);
|
||||
|
||||
@ -908,7 +913,7 @@ nsJSObjWrapper::NP_GetProperty(NPObject *npobj, NPIdentifier id,
|
||||
|
||||
nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj;
|
||||
|
||||
AutoJSExceptionReporter reporter(cx);
|
||||
AutoJSExceptionReporter reporter(aes, npjsobj);
|
||||
JSAutoCompartment ac(cx, npjsobj->mJSObj);
|
||||
|
||||
JS::Rooted<JS::Value> v(cx);
|
||||
@ -943,7 +948,7 @@ nsJSObjWrapper::NP_SetProperty(NPObject *npobj, NPIdentifier npid,
|
||||
nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj;
|
||||
bool ok = false;
|
||||
|
||||
AutoJSExceptionReporter reporter(cx);
|
||||
AutoJSExceptionReporter reporter(aes, npjsobj);
|
||||
JS::Rooted<JSObject*> jsObj(cx, npjsobj->mJSObj);
|
||||
JSAutoCompartment ac(cx, jsObj);
|
||||
|
||||
@ -977,7 +982,7 @@ nsJSObjWrapper::NP_RemoveProperty(NPObject *npobj, NPIdentifier npid)
|
||||
|
||||
nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj;
|
||||
|
||||
AutoJSExceptionReporter reporter(cx);
|
||||
AutoJSExceptionReporter reporter(jsapi, npjsobj);
|
||||
JS::ObjectOpResult result;
|
||||
JS::Rooted<JSObject*> obj(cx, npjsobj->mJSObj);
|
||||
JSAutoCompartment ac(cx, obj);
|
||||
@ -1029,7 +1034,7 @@ nsJSObjWrapper::NP_Enumerate(NPObject *npobj, NPIdentifier **idarray,
|
||||
|
||||
nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj;
|
||||
|
||||
AutoJSExceptionReporter reporter(cx);
|
||||
AutoJSExceptionReporter reporter(jsapi, npjsobj);
|
||||
JS::Rooted<JSObject*> jsobj(cx, npjsobj->mJSObj);
|
||||
JSAutoCompartment ac(cx, jsobj);
|
||||
|
||||
@ -1120,6 +1125,17 @@ nsJSObjWrapper::GetNewOrUsed(NPP npp, JSContext *cx, JS::Handle<JSObject*> obj)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// If we're running out-of-process and initializing asynchronously, and if
|
||||
// the plugin has been asked to destroy itself during initialization,
|
||||
// don't return any new NPObjects.
|
||||
nsNPAPIPluginInstance* inst = static_cast<nsNPAPIPluginInstance*>(npp->ndata);
|
||||
if (inst->GetPlugin()->GetLibrary()->IsOOP()) {
|
||||
PluginAsyncSurrogate* surrogate = PluginAsyncSurrogate::Cast(npp);
|
||||
if (surrogate && surrogate->IsDestroyPending()) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (!cx) {
|
||||
cx = GetJSContext(npp);
|
||||
|
||||
@ -2029,6 +2045,23 @@ nsJSNPRuntime::OnPluginDestroy(NPP npp)
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
nsJSNPRuntime::OnPluginDestroyPending(NPP npp)
|
||||
{
|
||||
if (sJSObjWrappersAccessible) {
|
||||
// Prevent modification of sJSObjWrappers table if we go reentrant.
|
||||
sJSObjWrappersAccessible = false;
|
||||
for (JSObjWrapperTable::Enum e(sJSObjWrappers); !e.empty(); e.popFront()) {
|
||||
nsJSObjWrapper *npobj = e.front().value();
|
||||
MOZ_ASSERT(npobj->_class == &nsJSObjWrapper::sJSObjWrapperNPClass);
|
||||
if (npobj->mNpp == npp) {
|
||||
npobj->mDestroyPending = true;
|
||||
}
|
||||
}
|
||||
sJSObjWrappersAccessible = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Find the NPP for a NPObject.
|
||||
static NPP
|
||||
@ -2291,7 +2324,7 @@ nsJSObjWrapper::HasOwnProperty(NPObject *npobj, NPIdentifier npid)
|
||||
nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj;
|
||||
bool found, ok = false;
|
||||
|
||||
AutoJSExceptionReporter reporter(cx);
|
||||
AutoJSExceptionReporter reporter(jsapi, npjsobj);
|
||||
JS::Rooted<JSObject*> jsobj(cx, npjsobj->mJSObj);
|
||||
JSAutoCompartment ac(cx, jsobj);
|
||||
|
||||
|
@ -15,6 +15,7 @@ class nsJSNPRuntime
|
||||
{
|
||||
public:
|
||||
static void OnPluginDestroy(NPP npp);
|
||||
static void OnPluginDestroyPending(NPP npp);
|
||||
};
|
||||
|
||||
class nsJSObjWrapperKey
|
||||
@ -41,6 +42,7 @@ class nsJSObjWrapper : public NPObject
|
||||
public:
|
||||
JS::Heap<JSObject *> mJSObj;
|
||||
const NPP mNpp;
|
||||
bool mDestroyPending;
|
||||
|
||||
static NPObject *GetNewOrUsed(NPP npp, JSContext *cx,
|
||||
JS::Handle<JSObject*> obj);
|
||||
|
Loading…
Reference in New Issue
Block a user