From 6f3990c46892ca31d55af46247690fa9e583a56c Mon Sep 17 00:00:00 2001 From: Aaron Klotz Date: Mon, 29 Dec 2014 16:12:25 -0700 Subject: [PATCH] Bug 998863: Asynchronous Plugin Initialization, Part 1: nsJSNPRuntime changes; r=josh --- dom/plugins/base/nsJSNPRuntime.cpp | 71 +++++++++++++++++++++++++++--- dom/plugins/base/nsJSNPRuntime.h | 1 + 2 files changed, 65 insertions(+), 7 deletions(-) diff --git a/dom/plugins/base/nsJSNPRuntime.cpp b/dom/plugins/base/nsJSNPRuntime.cpp index 9d63f0415af..a50f21bd578 100644 --- a/dom/plugins/base/nsJSNPRuntime.cpp +++ b/dom/plugins/base/nsJSNPRuntime.cpp @@ -28,7 +28,10 @@ #include "js/HashTable.h" #include "mozilla/HashFunctions.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" @@ -94,10 +97,24 @@ static nsTArray* sDelayedReleases; namespace { +inline void +CastNPObject(NPObject *aObj, PluginScriptableObjectParent*& aActor, + PluginAsyncSurrogate*& aSurrogate) +{ + aActor = nullptr; + aSurrogate = nullptr; + if (aObj->_class == PluginScriptableObjectParent::GetClass()) { + aActor = static_cast(aObj)->parent; + } else if (aObj->_class == PluginAsyncSurrogate::GetClass()) { + aSurrogate = static_cast(aObj)->mSurrogate; + } +} + inline bool NPObjectIsOutOfProcessProxy(NPObject *obj) { - return obj->_class == PluginScriptableObjectParent::GetClass(); + return obj->_class == PluginScriptableObjectParent::GetClass() || + obj->_class == PluginAsyncSurrogate::GetClass(); } } // anonymous namespace @@ -1389,15 +1406,23 @@ NPObjWrapper_GetProperty(JSContext *cx, JS::Handle obj, JS::Handle(npobj)->parent; + PluginScriptableObjectParent* actor = nullptr; + PluginAsyncSurrogate* surrogate = nullptr; + CastNPObject(npobj, actor, surrogate); - // actor may be null if the plugin crashed. - if (!actor) + // actor and surrogate may be null if the plugin crashed. + if (!actor && !surrogate) return false; - bool success = actor->GetPropertyHelper(identifier, &hasProperty, - &hasMethod, &npv); + bool success = false; + if (surrogate) { + success = surrogate->GetPropertyHelper(npobj, identifier, &hasProperty, + &hasMethod, &npv); + } else if (actor) { + success = actor->GetPropertyHelper(identifier, &hasProperty, &hasMethod, + &npv); + } + if (!ReportExceptionIfPending(cx)) { if (success) _releasevariantvalue(&npv); @@ -2253,3 +2278,35 @@ NPObjectMember_Trace(JSTracer *trc, JSObject *obj) "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 jsobj(cx, npjsobj->mJSObj); + JSAutoCompartment ac(cx, jsobj); + + NS_ASSERTION(NPIdentifierIsInt(npid) || NPIdentifierIsString(npid), + "id must be either string or int!\n"); + JS::Rooted id(cx, NPIdentifierToJSId(npid)); + ok = ::JS_AlreadyHasOwnPropertyById(cx, jsobj, id, &found); + return ok && found; +} diff --git a/dom/plugins/base/nsJSNPRuntime.h b/dom/plugins/base/nsJSNPRuntime.h index 7d1a5f5c197..e361b94e187 100644 --- a/dom/plugins/base/nsJSNPRuntime.h +++ b/dom/plugins/base/nsJSNPRuntime.h @@ -44,6 +44,7 @@ public: static NPObject *GetNewOrUsed(NPP npp, JSContext *cx, JS::Handle obj); + static bool HasOwnProperty(NPObject* npobj, NPIdentifier npid); protected: explicit nsJSObjWrapper(NPP npp);