Bug 998863: Asynchronous Plugin Initialization, Part 1: nsJSNPRuntime changes; r=josh

This commit is contained in:
Aaron Klotz 2014-12-24 17:55:48 -07:00
Родитель 27902ec6b5
Коммит 3f61ccb984
2 изменённых файлов: 65 добавлений и 7 удалений

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

@ -28,7 +28,10 @@
#include "js/HashTable.h" #include "js/HashTable.h"
#include "mozilla/HashFunctions.h" #include "mozilla/HashFunctions.h"
#include "mozilla/dom/ScriptSettings.h" #include "mozilla/dom/ScriptSettings.h"
#include "mozilla/plugins/PluginAsyncSurrogate.h"
using mozilla::plugins::AsyncNPObject;
using mozilla::plugins::PluginAsyncSurrogate;
#define NPRUNTIME_JSCLASS_NAME "NPObject JS wrapper class" #define NPRUNTIME_JSCLASS_NAME "NPObject JS wrapper class"
@ -94,10 +97,24 @@ static nsTArray<NPObject*>* sDelayedReleases;
namespace { namespace {
inline void
CastNPObject(NPObject *aObj, PluginScriptableObjectParent*& aActor,
PluginAsyncSurrogate*& aSurrogate)
{
aActor = nullptr;
aSurrogate = nullptr;
if (aObj->_class == PluginScriptableObjectParent::GetClass()) {
aActor = static_cast<ParentNPObject*>(aObj)->parent;
} else if (aObj->_class == PluginAsyncSurrogate::GetClass()) {
aSurrogate = static_cast<AsyncNPObject*>(aObj)->mSurrogate;
}
}
inline bool inline bool
NPObjectIsOutOfProcessProxy(NPObject *obj) NPObjectIsOutOfProcessProxy(NPObject *obj)
{ {
return obj->_class == PluginScriptableObjectParent::GetClass(); return obj->_class == PluginScriptableObjectParent::GetClass() ||
obj->_class == PluginAsyncSurrogate::GetClass();
} }
} // anonymous namespace } // anonymous namespace
@ -1389,15 +1406,23 @@ NPObjWrapper_GetProperty(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<js
NPIdentifier identifier = JSIdToNPIdentifier(id); NPIdentifier identifier = JSIdToNPIdentifier(id);
if (NPObjectIsOutOfProcessProxy(npobj)) { if (NPObjectIsOutOfProcessProxy(npobj)) {
PluginScriptableObjectParent* actor = PluginScriptableObjectParent* actor = nullptr;
static_cast<ParentNPObject*>(npobj)->parent; PluginAsyncSurrogate* surrogate = nullptr;
CastNPObject(npobj, actor, surrogate);
// actor may be null if the plugin crashed. // actor and surrogate may be null if the plugin crashed.
if (!actor) if (!actor && !surrogate)
return false; return false;
bool success = actor->GetPropertyHelper(identifier, &hasProperty, bool success = false;
if (surrogate) {
success = surrogate->GetPropertyHelper(npobj, identifier, &hasProperty,
&hasMethod, &npv); &hasMethod, &npv);
} else if (actor) {
success = actor->GetPropertyHelper(identifier, &hasProperty, &hasMethod,
&npv);
}
if (!ReportExceptionIfPending(cx)) { if (!ReportExceptionIfPending(cx)) {
if (success) if (success)
_releasevariantvalue(&npv); _releasevariantvalue(&npv);
@ -2253,3 +2278,35 @@ NPObjectMember_Trace(JSTracer *trc, JSObject *obj)
"NPObject Member => npobjWrapper"); "NPObject Member => npobjWrapper");
} }
} }
// static
bool
nsJSObjWrapper::HasOwnProperty(NPObject *npobj, NPIdentifier npid)
{
NPP npp = NPPStack::Peek();
dom::AutoJSAPI jsapi;
if (NS_WARN_IF(!jsapi.InitWithLegacyErrorReporting(GetGlobalObject(npp)))) {
return false;
}
JSContext *cx = jsapi.cx();
if (!npobj) {
ThrowJSException(cx,
"Null npobj in nsJSObjWrapper::NP_HasOwnProperty!");
return false;
}
nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj;
bool found, ok = false;
AutoJSExceptionReporter reporter(cx);
JS::Rooted<JSObject*> jsobj(cx, npjsobj->mJSObj);
JSAutoCompartment ac(cx, jsobj);
NS_ASSERTION(NPIdentifierIsInt(npid) || NPIdentifierIsString(npid),
"id must be either string or int!\n");
JS::Rooted<jsid> id(cx, NPIdentifierToJSId(npid));
ok = ::JS_AlreadyHasOwnPropertyById(cx, jsobj, id, &found);
return ok && found;
}

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

@ -44,6 +44,7 @@ public:
static NPObject *GetNewOrUsed(NPP npp, JSContext *cx, static NPObject *GetNewOrUsed(NPP npp, JSContext *cx,
JS::Handle<JSObject*> obj); JS::Handle<JSObject*> obj);
static bool HasOwnProperty(NPObject* npobj, NPIdentifier npid);
protected: protected:
explicit nsJSObjWrapper(NPP npp); explicit nsJSObjWrapper(NPP npp);