Bug 1360961 - Add a barrier to the plugin object wrapper table to handle incrementally finalized JSObjects r=bz

This commit is contained in:
Jon Coppeard 2017-05-04 08:17:39 +01:00
Родитель 494416733e
Коммит cecd5ba76a
1 изменённых файлов: 23 добавлений и 7 удалений

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

@ -1728,7 +1728,13 @@ NPObjWrapper_Finalize(js::FreeOp *fop, JSObject *obj)
NPObject *npobj = (NPObject *)::JS_GetPrivate(obj);
if (npobj) {
if (sNPObjWrappers) {
sNPObjWrappers->Remove(npobj);
// If the sNPObjWrappers map contains an entry that refers to this
// wrapper, remove it.
auto entry =
static_cast<NPObjWrapperHashEntry*>(sNPObjWrappers->Search(npobj));
if (entry && entry->mJSObj == obj) {
sNPObjWrappers->Remove(npobj);
}
}
}
@ -1907,13 +1913,23 @@ nsNPObjWrapper::GetNewOrUsed(NPP npp, JSContext *cx, NPObject *npobj)
}
if (entry->mJSObj) {
// Found a live NPObject wrapper. It may not be in the same compartment
// as cx, so we need to wrap it before returning it.
JS::Rooted<JSObject*> obj(cx, entry->mJSObj);
if (!JS_WrapObject(cx, &obj)) {
return nullptr;
// Found a NPObject wrapper. First check it is still alive.
JSObject* obj = entry->mJSObj;
if (js::gc::EdgeNeedsSweepUnbarriered(&obj)) {
// The object is dead (finalization will happen at a later time). By the
// time we leave this function, this entry will either be updated with a
// new wrapper or removed if that fails. Clear it anyway to make sure
// nothing touches the dead object.
entry->mJSObj = nullptr;
} else {
// It may not be in the same compartment as cx, so we need to wrap it
// before returning it.
JS::Rooted<JSObject*> obj(cx, entry->mJSObj);
if (!JS_WrapObject(cx, &obj)) {
return nullptr;
}
return obj;
}
return obj;
}
entry->mNPObj = npobj;