mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-16 22:04:36 +00:00
Bug 521377 - 'NPRuntime: Segfault when NPP_GetValue_NPPVpluginScriptableNPObject returns a null actor'. r=bsmedberg+valgrind.
This commit is contained in:
parent
b75d2c2802
commit
1b93c5d97b
@ -69,6 +69,7 @@ EXPORTS_mozilla/plugins = \
|
||||
PluginProcessParent.h \
|
||||
PluginScriptableObjectChild.h \
|
||||
PluginScriptableObjectParent.h \
|
||||
PluginScriptableObjectUtils.h \
|
||||
PluginInstanceChild.h \
|
||||
PluginInstanceParent.h \
|
||||
AStream.h \
|
||||
@ -99,6 +100,7 @@ CPPSRCS = \
|
||||
PluginProcessParent.cpp \
|
||||
PluginScriptableObjectChild.cpp \
|
||||
PluginScriptableObjectParent.cpp \
|
||||
PluginScriptableObjectUtils.cpp \
|
||||
BrowserStreamChild.cpp \
|
||||
BrowserStreamParent.cpp \
|
||||
PluginStreamChild.cpp \
|
||||
|
@ -63,8 +63,7 @@ rpc protocol PPluginInstance
|
||||
manages PStreamNotify;
|
||||
|
||||
child:
|
||||
rpc __delete__()
|
||||
returns (NPError rv);
|
||||
rpc __delete__();
|
||||
|
||||
rpc NPP_SetWindow(NPRemoteWindow window)
|
||||
returns (NPError rv);
|
||||
@ -82,6 +81,9 @@ child:
|
||||
rpc NPP_HandleEvent(NPRemoteEvent event)
|
||||
returns (int16_t handled);
|
||||
|
||||
rpc NPP_Destroy()
|
||||
returns (NPError rv);
|
||||
|
||||
parent:
|
||||
rpc NPN_GetValue_NPNVjavascriptEnabledBool()
|
||||
returns (bool value, NPError result);
|
||||
|
@ -72,10 +72,11 @@ parent:
|
||||
returns (Variant aResult,
|
||||
bool aSuccess);
|
||||
|
||||
both:
|
||||
// NPClass methods
|
||||
child:
|
||||
rpc Invalidate();
|
||||
|
||||
both:
|
||||
// NPClass methods
|
||||
rpc HasMethod(NPRemoteIdentifier aId)
|
||||
returns (bool aHasMethod);
|
||||
|
||||
@ -109,6 +110,16 @@ both:
|
||||
rpc Construct(Variant[] aArgs)
|
||||
returns (Variant aResult,
|
||||
bool aSuccess);
|
||||
|
||||
// Objects are initially unprotected, and the Protect and Unprotect functions
|
||||
// only affect protocol objects that represent NPObjects created in the same
|
||||
// process (rather than protocol objects that are a proxy for an NPObject
|
||||
// created in another process). Protocol objects representing local NPObjects
|
||||
// are protected after an NPObject has been associated with the protocol
|
||||
// object. Sending the protocol object as an argument to the other process
|
||||
// temporarily protects the protocol object again for the duration of the call.
|
||||
rpc Protect();
|
||||
rpc Unprotect();
|
||||
};
|
||||
|
||||
} // namespace plugins
|
||||
|
@ -63,27 +63,27 @@ using mozilla::gfx::SharedDIB;
|
||||
#endif
|
||||
|
||||
PluginInstanceChild::PluginInstanceChild(const NPPluginFuncs* aPluginIface) :
|
||||
mPluginIface(aPluginIface)
|
||||
mPluginIface(aPluginIface)
|
||||
#if defined(OS_WIN)
|
||||
, mPluginWindowHWND(0)
|
||||
, mPluginWndProc(0)
|
||||
, mPluginParentHWND(0)
|
||||
#endif
|
||||
{
|
||||
memset(&mWindow, 0, sizeof(mWindow));
|
||||
mData.ndata = (void*) this;
|
||||
, mPluginWindowHWND(0)
|
||||
, mPluginWndProc(0)
|
||||
, mPluginParentHWND(0)
|
||||
#endif // OS_WIN
|
||||
{
|
||||
memset(&mWindow, 0, sizeof(mWindow));
|
||||
mData.ndata = (void*) this;
|
||||
#if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
mWindow.ws_info = &mWsInfo;
|
||||
memset(&mWsInfo, 0, sizeof(mWsInfo));
|
||||
# ifdef MOZ_WIDGET_GTK2
|
||||
mWsInfo.display = GDK_DISPLAY();
|
||||
# endif
|
||||
#endif
|
||||
mWindow.ws_info = &mWsInfo;
|
||||
memset(&mWsInfo, 0, sizeof(mWsInfo));
|
||||
#ifdef MOZ_WIDGET_GTK2
|
||||
mWsInfo.display = GDK_DISPLAY();
|
||||
#endif // MOZ_WIDGET_GTK2
|
||||
#endif // MOZ_X11 && XP_UNIX && !XP_MACOSX
|
||||
#if defined(OS_WIN)
|
||||
memset(&mAlphaExtract, 0, sizeof(mAlphaExtract));
|
||||
mAlphaExtract.doublePassEvent = ::RegisterWindowMessage(NS_OOPP_DOUBLEPASS_MSGID);
|
||||
#endif
|
||||
}
|
||||
#endif // OS_WIN
|
||||
}
|
||||
|
||||
PluginInstanceChild::~PluginInstanceChild()
|
||||
{
|
||||
@ -92,13 +92,6 @@ PluginInstanceChild::~PluginInstanceChild()
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
PluginInstanceChild::Answer__delete__(NPError* rv)
|
||||
{
|
||||
return static_cast<PluginModuleChild*>(Manager())->
|
||||
PluginInstanceDestroyed(this, rv);
|
||||
}
|
||||
|
||||
NPError
|
||||
PluginInstanceChild::NPN_GetValue(NPNVariable aVar,
|
||||
void* aValue)
|
||||
@ -174,7 +167,7 @@ PluginInstanceChild::NPN_GetValue(NPNVariable aVar,
|
||||
NS_ASSERTION(actor, "Null actor!");
|
||||
|
||||
NPObject* object =
|
||||
static_cast<PluginScriptableObjectChild*>(actor)->GetObject();
|
||||
static_cast<PluginScriptableObjectChild*>(actor)->GetObject(true);
|
||||
NS_ASSERTION(object, "Null object?!");
|
||||
|
||||
PluginModuleChild::sBrowserFuncs.retainobject(object);
|
||||
@ -197,7 +190,7 @@ PluginInstanceChild::NPN_GetValue(NPNVariable aVar,
|
||||
NS_ASSERTION(actor, "Null actor!");
|
||||
|
||||
NPObject* object =
|
||||
static_cast<PluginScriptableObjectChild*>(actor)->GetObject();
|
||||
static_cast<PluginScriptableObjectChild*>(actor)->GetObject(true);
|
||||
NS_ASSERTION(object, "Null object?!");
|
||||
|
||||
PluginModuleChild::sBrowserFuncs.retainobject(object);
|
||||
@ -525,30 +518,6 @@ PluginInstanceChild::Initialize()
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
PluginInstanceChild::Destroy()
|
||||
{
|
||||
// Copy the actors here so we don't enumerate a mutating array.
|
||||
nsAutoTArray<PluginScriptableObjectChild*, 10> objects;
|
||||
PRUint32 count = mScriptableObjects.Length();
|
||||
for (PRUint32 index = 0; index < count; index++) {
|
||||
objects.AppendElement(mScriptableObjects[index]);
|
||||
}
|
||||
|
||||
count = objects.Length();
|
||||
for (PRUint32 index = 0; index < count; index++) {
|
||||
PluginScriptableObjectChild*& actor = objects[index];
|
||||
NPObject* object = actor->GetObject();
|
||||
if (object->_class == PluginScriptableObjectChild::GetClass()) {
|
||||
PluginScriptableObjectChild::ScriptableInvalidate(object);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
SharedSurfaceRelease();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
|
||||
static const TCHAR kWindowClassName[] = TEXT("GeckoPluginWindow");
|
||||
@ -881,15 +850,7 @@ PPluginScriptableObjectChild*
|
||||
PluginInstanceChild::AllocPPluginScriptableObject()
|
||||
{
|
||||
AssertPluginThread();
|
||||
|
||||
nsAutoPtr<PluginScriptableObjectChild>* object =
|
||||
mScriptableObjects.AppendElement();
|
||||
NS_ENSURE_TRUE(object, nsnull);
|
||||
|
||||
*object = new PluginScriptableObjectChild();
|
||||
NS_ENSURE_TRUE(*object, nsnull);
|
||||
|
||||
return object->get();
|
||||
return new PluginScriptableObjectChild(Proxy);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -898,24 +859,16 @@ PluginInstanceChild::DeallocPPluginScriptableObject(
|
||||
{
|
||||
AssertPluginThread();
|
||||
|
||||
PluginScriptableObjectChild* object =
|
||||
PluginScriptableObjectChild* actor =
|
||||
reinterpret_cast<PluginScriptableObjectChild*>(aObject);
|
||||
|
||||
NPObject* npobject = object->GetObject();
|
||||
if (npobject &&
|
||||
npobject->_class != PluginScriptableObjectChild::GetClass()) {
|
||||
PluginModuleChild::current()->UnregisterNPObject(npobject);
|
||||
NPObject* object = actor->GetObject(false);
|
||||
if (object) {
|
||||
PluginModuleChild::current()->UnregisterNPObject(object);
|
||||
}
|
||||
|
||||
PRUint32 count = mScriptableObjects.Length();
|
||||
for (PRUint32 index = 0; index < count; index++) {
|
||||
if (mScriptableObjects[index] == object) {
|
||||
mScriptableObjects.RemoveElementAt(index);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
NS_NOTREACHED("An actor we don't know about?!");
|
||||
return false;
|
||||
delete actor;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -927,19 +880,12 @@ PluginInstanceChild::AnswerPPluginScriptableObjectConstructor(
|
||||
// This is only called in response to the parent process requesting the
|
||||
// creation of an actor. This actor will represent an NPObject that is
|
||||
// created by the browser and returned to the plugin.
|
||||
NPClass* npclass =
|
||||
const_cast<NPClass*>(PluginScriptableObjectChild::GetClass());
|
||||
|
||||
ChildNPObject* object = reinterpret_cast<ChildNPObject*>(
|
||||
PluginModuleChild::sBrowserFuncs.createobject(GetNPP(), npclass));
|
||||
if (!object) {
|
||||
NS_WARNING("Failed to create NPObject!");
|
||||
return false;
|
||||
}
|
||||
|
||||
PluginScriptableObjectChild* actor =
|
||||
static_cast<PluginScriptableObjectChild*>(aActor);
|
||||
actor->Initialize(const_cast<PluginInstanceChild*>(this), object);
|
||||
NS_ASSERTION(!actor->GetObject(false), "Actor already has an object?!");
|
||||
|
||||
actor->InitializeProxy();
|
||||
NS_ASSERTION(actor->GetObject(false), "Actor should have an object!");
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -1049,35 +995,30 @@ PluginScriptableObjectChild*
|
||||
PluginInstanceChild::GetActorForNPObject(NPObject* aObject)
|
||||
{
|
||||
AssertPluginThread();
|
||||
NS_ASSERTION(aObject, "Null pointer!");
|
||||
NS_ASSERTION(aObject, "Null pointer!");
|
||||
|
||||
if (aObject->_class == PluginScriptableObjectChild::GetClass()) {
|
||||
// One of ours! It's a browser-provided object.
|
||||
ChildNPObject* object = static_cast<ChildNPObject*>(aObject);
|
||||
NS_ASSERTION(object->parent, "Null actor!");
|
||||
return object->parent;
|
||||
}
|
||||
if (aObject->_class == PluginScriptableObjectChild::GetClass()) {
|
||||
// One of ours! It's a browser-provided object.
|
||||
ChildNPObject* object = static_cast<ChildNPObject*>(aObject);
|
||||
NS_ASSERTION(object->parent, "Null actor!");
|
||||
return object->parent;
|
||||
}
|
||||
|
||||
PluginScriptableObjectChild* actor =
|
||||
PluginModuleChild::current()->GetActorForNPObject(aObject);
|
||||
if (actor) {
|
||||
// Plugin-provided object that we've previously wrapped.
|
||||
return actor;
|
||||
}
|
||||
PluginScriptableObjectChild* actor =
|
||||
PluginModuleChild::current()->GetActorForNPObject(aObject);
|
||||
if (actor) {
|
||||
// Plugin-provided object that we've previously wrapped.
|
||||
return actor;
|
||||
}
|
||||
|
||||
actor = reinterpret_cast<PluginScriptableObjectChild*>(
|
||||
CallPPluginScriptableObjectConstructor());
|
||||
NS_ENSURE_TRUE(actor, nsnull);
|
||||
actor = new PluginScriptableObjectChild(LocalObject);
|
||||
if (!CallPPluginScriptableObjectConstructor(actor)) {
|
||||
NS_ERROR("Failed to send constructor message!");
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
actor->Initialize(this, aObject);
|
||||
|
||||
#ifdef DEBUG
|
||||
bool ok =
|
||||
#endif
|
||||
PluginModuleChild::current()->RegisterNPObject(aObject, actor);
|
||||
NS_ASSERTION(ok, "Out of memory?");
|
||||
|
||||
return actor;
|
||||
actor->InitializeLocal(aObject);
|
||||
return actor;
|
||||
}
|
||||
|
||||
NPError
|
||||
@ -1119,3 +1060,16 @@ PluginInstanceChild::InvalidateRect(NPRect* aInvalidRect)
|
||||
|
||||
SendNPN_InvalidateRect(*aInvalidRect);
|
||||
}
|
||||
|
||||
bool
|
||||
PluginInstanceChild::AnswerNPP_Destroy(NPError* aResult)
|
||||
{
|
||||
PluginModuleChild* module = PluginModuleChild::current();
|
||||
bool retval = module->PluginInstanceDestroyed(this, aResult);
|
||||
|
||||
#if defined(OS_WIN)
|
||||
SharedSurfaceRelease();
|
||||
#endif
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
@ -71,9 +71,6 @@ class PluginInstanceChild : public PPluginInstanceChild
|
||||
protected:
|
||||
virtual bool AnswerNPP_SetWindow(const NPRemoteWindow& window, NPError* rv);
|
||||
|
||||
virtual bool Answer__delete__(NPError* rv);
|
||||
|
||||
|
||||
virtual bool
|
||||
AnswerNPP_GetValue_NPPVpluginWindow(bool* windowed, NPError* rv);
|
||||
virtual bool
|
||||
@ -87,6 +84,9 @@ protected:
|
||||
virtual bool
|
||||
AnswerNPP_HandleEvent(const NPRemoteEvent& event, int16_t* handled);
|
||||
|
||||
virtual bool
|
||||
AnswerNPP_Destroy(NPError* result);
|
||||
|
||||
virtual PPluginScriptableObjectChild*
|
||||
AllocPPluginScriptableObject();
|
||||
|
||||
@ -146,7 +146,6 @@ public:
|
||||
virtual ~PluginInstanceChild();
|
||||
|
||||
bool Initialize();
|
||||
void Destroy();
|
||||
|
||||
NPP GetNPP()
|
||||
{
|
||||
@ -191,6 +190,7 @@ private:
|
||||
const NPPluginFuncs* mPluginIface;
|
||||
NPP_t mData;
|
||||
NPWindow mWindow;
|
||||
|
||||
#if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
NPSetWindowCallbackStruct mWsInfo;
|
||||
#elif defined(OS_WIN)
|
||||
@ -199,8 +199,6 @@ private:
|
||||
HWND mPluginParentHWND;
|
||||
#endif
|
||||
|
||||
nsTArray<nsAutoPtr<PluginScriptableObjectChild> > mScriptableObjects;
|
||||
|
||||
#if defined(OS_WIN)
|
||||
private:
|
||||
// Shared dib rendering management for windowless plugins.
|
||||
|
@ -43,7 +43,6 @@
|
||||
#include "PluginModuleParent.h"
|
||||
#include "PluginStreamParent.h"
|
||||
#include "StreamNotifyParent.h"
|
||||
|
||||
#include "npfunctions.h"
|
||||
#include "nsAutoPtr.h"
|
||||
|
||||
@ -69,27 +68,40 @@ PluginInstanceParent::~PluginInstanceParent()
|
||||
mNPP->pdata = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
PluginInstanceParent::Init()
|
||||
{
|
||||
return !!mScriptableObjects.Init();
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
PLDHashOperator
|
||||
ActorCollect(const void* aKey,
|
||||
PluginScriptableObjectParent* aData,
|
||||
void* aUserData)
|
||||
{
|
||||
nsTArray<PluginScriptableObjectParent*>* objects =
|
||||
reinterpret_cast<nsTArray<PluginScriptableObjectParent*>*>(aUserData);
|
||||
return objects->AppendElement(aData) ? PL_DHASH_NEXT : PL_DHASH_STOP;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
NPError
|
||||
PluginInstanceParent::Destroy()
|
||||
{
|
||||
// Copy the actors here so we don't enumerate a mutating array.
|
||||
nsAutoTArray<PluginScriptableObjectParent*, 10> objects;
|
||||
PRUint32 count = mScriptableObjects.Length();
|
||||
for (PRUint32 index = 0; index < count; index++) {
|
||||
objects.AppendElement(mScriptableObjects[index]);
|
||||
}
|
||||
|
||||
count = objects.Length();
|
||||
for (PRUint32 index = 0; index < count; index++) {
|
||||
NPObject* object = objects[index]->GetObject();
|
||||
if (object->_class == PluginScriptableObjectParent::GetClass()) {
|
||||
PluginScriptableObjectParent::ScriptableInvalidate(object);
|
||||
}
|
||||
NPError retval;
|
||||
if (!CallNPP_Destroy(&retval)) {
|
||||
NS_WARNING("Failed to send message!");
|
||||
return NPERR_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
SharedSurfaceRelease();
|
||||
#endif
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
PBrowserStreamParent*
|
||||
@ -453,7 +465,7 @@ PluginInstanceParent::NPP_GetValue(NPPVariable aVariable,
|
||||
}
|
||||
|
||||
NPObject* object =
|
||||
static_cast<PluginScriptableObjectParent*>(actor)->GetObject();
|
||||
static_cast<PluginScriptableObjectParent*>(actor)->GetObject(true);
|
||||
NS_ASSERTION(object, "This shouldn't ever be null!");
|
||||
|
||||
(*(NPObject**)_retval) = npn->retainobject(object);
|
||||
@ -582,32 +594,57 @@ PluginInstanceParent::NPP_DestroyStream(NPStream* stream, NPReason reason)
|
||||
PPluginScriptableObjectParent*
|
||||
PluginInstanceParent::AllocPPluginScriptableObject()
|
||||
{
|
||||
nsAutoPtr<PluginScriptableObjectParent>* object =
|
||||
mScriptableObjects.AppendElement();
|
||||
NS_ENSURE_TRUE(object, nsnull);
|
||||
|
||||
*object = new PluginScriptableObjectParent();
|
||||
NS_ENSURE_TRUE(*object, nsnull);
|
||||
|
||||
return object->get();
|
||||
return new PluginScriptableObjectParent(Proxy);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
namespace {
|
||||
|
||||
struct ActorSearchData
|
||||
{
|
||||
PluginScriptableObjectParent* actor;
|
||||
bool found;
|
||||
};
|
||||
|
||||
PLDHashOperator
|
||||
ActorSearch(const void* aKey,
|
||||
PluginScriptableObjectParent* aData,
|
||||
void* aUserData)
|
||||
{
|
||||
ActorSearchData* asd = reinterpret_cast<ActorSearchData*>(aUserData);
|
||||
if (asd->actor == aData) {
|
||||
asd->found = true;
|
||||
return PL_DHASH_STOP;
|
||||
}
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
#endif // DEBUG
|
||||
|
||||
bool
|
||||
PluginInstanceParent::DeallocPPluginScriptableObject(
|
||||
PPluginScriptableObjectParent* aObject)
|
||||
{
|
||||
PluginScriptableObjectParent* object =
|
||||
reinterpret_cast<PluginScriptableObjectParent*>(aObject);
|
||||
PluginScriptableObjectParent* actor =
|
||||
static_cast<PluginScriptableObjectParent*>(aObject);
|
||||
|
||||
PRUint32 count = mScriptableObjects.Length();
|
||||
for (PRUint32 index = 0; index < count; index++) {
|
||||
if (mScriptableObjects[index] == object) {
|
||||
mScriptableObjects.RemoveElementAt(index);
|
||||
return true;
|
||||
}
|
||||
NPObject* object = actor->GetObject(false);
|
||||
if (object) {
|
||||
NS_ASSERTION(mScriptableObjects.Get(object, nsnull),
|
||||
"NPObject not in the hash!");
|
||||
mScriptableObjects.Remove(object);
|
||||
}
|
||||
NS_NOTREACHED("An actor we don't know about?!");
|
||||
return false;
|
||||
#ifdef DEBUG
|
||||
else {
|
||||
ActorSearchData asd = { actor, false };
|
||||
mScriptableObjects.EnumerateRead(ActorSearch, &asd);
|
||||
NS_ASSERTION(!asd.found, "Actor in the hash with a null NPObject!");
|
||||
}
|
||||
#endif
|
||||
|
||||
delete actor;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -617,24 +654,13 @@ PluginInstanceParent::AnswerPPluginScriptableObjectConstructor(
|
||||
// This is only called in response to the child process requesting the
|
||||
// creation of an actor. This actor will represent an NPObject that is
|
||||
// created by the plugin and returned to the browser.
|
||||
const NPNetscapeFuncs* npn = mParent->GetNetscapeFuncs();
|
||||
if (!npn) {
|
||||
NS_WARNING("No netscape function pointers?!");
|
||||
return false;
|
||||
}
|
||||
PluginScriptableObjectParent* actor =
|
||||
static_cast<PluginScriptableObjectParent*>(aActor);
|
||||
NS_ASSERTION(!actor->GetObject(false), "Actor already has an object?!");
|
||||
|
||||
NPClass* npclass =
|
||||
const_cast<NPClass*>(PluginScriptableObjectParent::GetClass());
|
||||
actor->InitializeProxy();
|
||||
NS_ASSERTION(actor->GetObject(false), "Actor should have an object!");
|
||||
|
||||
ParentNPObject* object = reinterpret_cast<ParentNPObject*>(
|
||||
npn->createobject(mNPP, npclass));
|
||||
if (!object) {
|
||||
NS_WARNING("Failed to create NPObject!");
|
||||
return false;
|
||||
}
|
||||
|
||||
static_cast<PluginScriptableObjectParent*>(aActor)->Initialize(
|
||||
const_cast<PluginInstanceParent*>(this), object);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -650,6 +676,26 @@ PluginInstanceParent::NPP_URLNotify(const char* url, NPReason reason,
|
||||
PStreamNotifyParent::Call__delete__(streamNotify, reason);
|
||||
}
|
||||
|
||||
bool
|
||||
PluginInstanceParent::RegisterNPObjectForActor(
|
||||
NPObject* aObject,
|
||||
PluginScriptableObjectParent* aActor)
|
||||
{
|
||||
NS_ASSERTION(aObject && aActor, "Null pointers!");
|
||||
NS_ASSERTION(mScriptableObjects.IsInitialized(), "Hash not initialized!");
|
||||
NS_ASSERTION(!mScriptableObjects.Get(aObject, nsnull), "Duplicate entry!");
|
||||
return !!mScriptableObjects.Put(aObject, aActor);
|
||||
}
|
||||
|
||||
void
|
||||
PluginInstanceParent::UnregisterNPObject(NPObject* aObject)
|
||||
{
|
||||
NS_ASSERTION(aObject, "Null pointer!");
|
||||
NS_ASSERTION(mScriptableObjects.IsInitialized(), "Hash not initialized!");
|
||||
NS_ASSERTION(mScriptableObjects.Get(aObject, nsnull), "Unknown entry!");
|
||||
mScriptableObjects.Remove(aObject);
|
||||
}
|
||||
|
||||
PluginScriptableObjectParent*
|
||||
PluginInstanceParent::GetActorForNPObject(NPObject* aObject)
|
||||
{
|
||||
@ -662,21 +708,23 @@ PluginInstanceParent::GetActorForNPObject(NPObject* aObject)
|
||||
return object->parent;
|
||||
}
|
||||
|
||||
PRUint32 count = mScriptableObjects.Length();
|
||||
for (PRUint32 index = 0; index < count; index++) {
|
||||
nsAutoPtr<PluginScriptableObjectParent>& actor =
|
||||
mScriptableObjects[index];
|
||||
if (actor->GetObject() == aObject) {
|
||||
return actor;
|
||||
}
|
||||
PluginScriptableObjectParent* actor;
|
||||
if (mScriptableObjects.Get(aObject, &actor)) {
|
||||
return actor;
|
||||
}
|
||||
|
||||
PluginScriptableObjectParent* actor =
|
||||
static_cast<PluginScriptableObjectParent*>(
|
||||
CallPPluginScriptableObjectConstructor());
|
||||
NS_ENSURE_TRUE(actor, nsnull);
|
||||
actor = new PluginScriptableObjectParent(LocalObject);
|
||||
if (!actor) {
|
||||
NS_ERROR("Out of memory!");
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
actor->Initialize(const_cast<PluginInstanceParent*>(this), aObject);
|
||||
if (!CallPPluginScriptableObjectConstructor(actor)) {
|
||||
NS_WARNING("Failed to send constructor message!");
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
actor->InitializeLocal(aObject);
|
||||
return actor;
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,8 @@
|
||||
|
||||
#include "npfunctions.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsDataHashtable.h"
|
||||
#include "nsHashKeys.h"
|
||||
#include "nsRect.h"
|
||||
|
||||
namespace mozilla {
|
||||
@ -69,7 +70,8 @@ public:
|
||||
|
||||
virtual ~PluginInstanceParent();
|
||||
|
||||
void Destroy();
|
||||
bool Init();
|
||||
NPError Destroy();
|
||||
|
||||
virtual PPluginScriptableObjectParent*
|
||||
AllocPPluginScriptableObject();
|
||||
@ -190,6 +192,13 @@ public:
|
||||
return mNPNIface;
|
||||
}
|
||||
|
||||
bool
|
||||
RegisterNPObjectForActor(NPObject* aObject,
|
||||
PluginScriptableObjectParent* aActor);
|
||||
|
||||
void
|
||||
UnregisterNPObject(NPObject* aObject);
|
||||
|
||||
PluginScriptableObjectParent*
|
||||
GetActorForNPObject(NPObject* aObject);
|
||||
|
||||
@ -210,7 +219,7 @@ private:
|
||||
const NPNetscapeFuncs* mNPNIface;
|
||||
NPWindowType mWindowType;
|
||||
|
||||
nsTArray<nsAutoPtr<PluginScriptableObjectParent> > mScriptableObjects;
|
||||
nsDataHashtable<nsVoidPtrHashKey, PluginScriptableObjectParent*> mScriptableObjects;
|
||||
|
||||
#if defined(OS_WIN)
|
||||
private:
|
||||
|
@ -1,101 +1,106 @@
|
||||
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8; -*- */
|
||||
/* vim: set sw=2 ts=8 et tw=80 : */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Content App.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* The Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "PluginMessageUtils.h"
|
||||
#include "nsIRunnable.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
namespace {
|
||||
|
||||
class DeferNPObjectReleaseRunnable : public nsRunnable
|
||||
{
|
||||
public:
|
||||
DeferNPObjectReleaseRunnable(const NPNetscapeFuncs* f, NPObject* o)
|
||||
: mFuncs(f)
|
||||
, mObject(o)
|
||||
{
|
||||
NS_ASSERTION(o, "no release null objects");
|
||||
}
|
||||
|
||||
NS_IMETHOD Run();
|
||||
|
||||
private:
|
||||
const NPNetscapeFuncs* mFuncs;
|
||||
NPObject* mObject;
|
||||
};
|
||||
|
||||
NS_IMETHODIMP
|
||||
DeferNPObjectReleaseRunnable::Run()
|
||||
{
|
||||
mFuncs->releaseobject(mObject);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace mozilla {
|
||||
namespace plugins {
|
||||
|
||||
PRLogModuleInfo* gPluginLog = PR_NewLogModule("IPCPlugins");
|
||||
|
||||
void
|
||||
DeferNPObjectLastRelease(const NPNetscapeFuncs* f, NPObject* o)
|
||||
{
|
||||
if (!o)
|
||||
return;
|
||||
|
||||
if (o->referenceCount > 1) {
|
||||
f->releaseobject(o);
|
||||
return;
|
||||
}
|
||||
|
||||
NS_DispatchToCurrentThread(new DeferNPObjectReleaseRunnable(f, o));
|
||||
}
|
||||
|
||||
void DeferNPVariantLastRelease(const NPNetscapeFuncs* f, NPVariant* v)
|
||||
{
|
||||
if (!NPVARIANT_IS_OBJECT(*v)) {
|
||||
f->releasevariantvalue(v);
|
||||
return;
|
||||
}
|
||||
DeferNPObjectLastRelease(f, v->value.objectValue);
|
||||
VOID_TO_NPVARIANT(*v);
|
||||
}
|
||||
|
||||
} // namespace plugins
|
||||
} // namespace mozilla
|
||||
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8; -*- */
|
||||
/* vim: set sw=2 ts=8 et tw=80 : */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Content App.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* The Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "PluginMessageUtils.h"
|
||||
#include "nsIRunnable.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
#include "PluginInstanceParent.h"
|
||||
#include "PluginInstanceChild.h"
|
||||
#include "PluginScriptableObjectParent.h"
|
||||
#include "PluginScriptableObjectChild.h"
|
||||
|
||||
namespace {
|
||||
|
||||
class DeferNPObjectReleaseRunnable : public nsRunnable
|
||||
{
|
||||
public:
|
||||
DeferNPObjectReleaseRunnable(const NPNetscapeFuncs* f, NPObject* o)
|
||||
: mFuncs(f)
|
||||
, mObject(o)
|
||||
{
|
||||
NS_ASSERTION(o, "no release null objects");
|
||||
}
|
||||
|
||||
NS_IMETHOD Run();
|
||||
|
||||
private:
|
||||
const NPNetscapeFuncs* mFuncs;
|
||||
NPObject* mObject;
|
||||
};
|
||||
|
||||
NS_IMETHODIMP
|
||||
DeferNPObjectReleaseRunnable::Run()
|
||||
{
|
||||
mFuncs->releaseobject(mObject);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace mozilla {
|
||||
namespace plugins {
|
||||
|
||||
PRLogModuleInfo* gPluginLog = PR_NewLogModule("IPCPlugins");
|
||||
|
||||
void
|
||||
DeferNPObjectLastRelease(const NPNetscapeFuncs* f, NPObject* o)
|
||||
{
|
||||
if (!o)
|
||||
return;
|
||||
|
||||
if (o->referenceCount > 1) {
|
||||
f->releaseobject(o);
|
||||
return;
|
||||
}
|
||||
|
||||
NS_DispatchToCurrentThread(new DeferNPObjectReleaseRunnable(f, o));
|
||||
}
|
||||
|
||||
void DeferNPVariantLastRelease(const NPNetscapeFuncs* f, NPVariant* v)
|
||||
{
|
||||
if (!NPVARIANT_IS_OBJECT(*v)) {
|
||||
f->releasevariantvalue(v);
|
||||
return;
|
||||
}
|
||||
DeferNPObjectLastRelease(f, v->value.objectValue);
|
||||
VOID_TO_NPVARIANT(*v);
|
||||
}
|
||||
|
||||
} // namespace plugins
|
||||
} // namespace mozilla
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include "npfunctions.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsStringGlue.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "prlog.h"
|
||||
|
||||
@ -64,6 +65,12 @@ typedef intptr_t NPRemoteIdentifier;
|
||||
|
||||
namespace plugins {
|
||||
|
||||
enum ScriptableObjectType
|
||||
{
|
||||
LocalObject,
|
||||
Proxy
|
||||
};
|
||||
|
||||
extern PRLogModuleInfo* gPluginLog;
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
|
@ -246,8 +246,6 @@ PluginModuleChild::UnregisterNPObject(NPObject* aObject)
|
||||
AssertPluginThread();
|
||||
NS_ASSERTION(mObjectMap.IsInitialized(), "Not initialized!");
|
||||
NS_ASSERTION(aObject, "Null pointer!");
|
||||
NS_ASSERTION(mObjectMap.Get(aObject, nsnull),
|
||||
"Unregistering an object that was never added!");
|
||||
mObjectMap.Remove(aObject);
|
||||
}
|
||||
|
||||
@ -287,6 +285,12 @@ ActorSearch(const void* aKey,
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
bool
|
||||
PluginModuleChild::NPObjectIsRegistered(NPObject* aObject)
|
||||
{
|
||||
return !!mObjectMap.Get(aObject, nsnull);
|
||||
}
|
||||
|
||||
bool
|
||||
PluginModuleChild::NPObjectIsRegisteredForActor(
|
||||
PluginScriptableObjectChild* aActor)
|
||||
@ -1476,9 +1480,10 @@ PluginModuleChild::PluginInstanceDestroyed(PluginInstanceChild* aActor,
|
||||
PLUGIN_LOG_DEBUG_METHOD;
|
||||
AssertPluginThread();
|
||||
|
||||
*rv = mFunctions.destroy(aActor->GetNPP(), 0);
|
||||
aActor->Destroy();
|
||||
aActor->GetNPP()->ndata = 0;
|
||||
NPP npp = aActor->GetNPP();
|
||||
|
||||
*rv = mFunctions.destroy(npp, 0);
|
||||
npp->ndata = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -146,6 +146,7 @@ public:
|
||||
PluginScriptableObjectChild* GetActorForNPObject(NPObject* aObject);
|
||||
|
||||
#ifdef DEBUG
|
||||
bool NPObjectIsRegistered(NPObject* aObject);
|
||||
bool NPObjectIsRegisteredForActor(PluginScriptableObjectChild* aActor);
|
||||
#endif
|
||||
|
||||
|
@ -160,7 +160,7 @@ PluginModuleParent::SetPluginFuncs(NPPluginFuncs* aFuncs)
|
||||
|
||||
NPError
|
||||
PluginModuleParent::NPP_Destroy(NPP instance,
|
||||
NPSavedData** save)
|
||||
NPSavedData** /*saved*/)
|
||||
{
|
||||
// FIXME/cjones:
|
||||
// (1) send a "destroy" message to the child
|
||||
@ -175,15 +175,14 @@ PluginModuleParent::NPP_Destroy(NPP instance,
|
||||
if (!parentInstance)
|
||||
return NPERR_NO_ERROR;
|
||||
|
||||
parentInstance->Destroy();
|
||||
|
||||
NPError prv;
|
||||
if (!PPluginInstanceParent::Call__delete__(parentInstance, &prv)) {
|
||||
prv = NPERR_GENERIC_ERROR;
|
||||
}
|
||||
NPError retval = parentInstance->Destroy();
|
||||
instance->pdata = nsnull;
|
||||
|
||||
return prv;
|
||||
if (!PluginInstanceParent::Call__delete__(parentInstance)) {
|
||||
NS_ERROR("Failed to delete instance!");
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -641,6 +640,11 @@ PluginModuleParent::NPP_New(NPMIMEType pluginType, NPP instance,
|
||||
PluginInstanceParent* parentInstance =
|
||||
new PluginInstanceParent(this, instance, mNPNIface);
|
||||
|
||||
if (!parentInstance->Init()) {
|
||||
delete parentInstance;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
instance->pdata = parentInstance;
|
||||
|
||||
if (!CallPPluginInstanceConstructor(parentInstance,
|
||||
@ -657,9 +661,8 @@ PluginModuleParent::NPP_New(NPMIMEType pluginType, NPP instance,
|
||||
}
|
||||
|
||||
if (*error != NPERR_NO_ERROR) {
|
||||
PPluginInstanceParent::Call__delete__(parentInstance, error);
|
||||
instance->pdata = nsnull;
|
||||
return NS_ERROR_FAILURE;
|
||||
NPP_Destroy(instance, 0);
|
||||
return *error;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=4 ts=4 et :
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=2 et :
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
@ -37,138 +37,11 @@
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "PluginScriptableObjectChild.h"
|
||||
|
||||
#include "npapi.h"
|
||||
#include "npruntime.h"
|
||||
#include "nsDebug.h"
|
||||
|
||||
#include "PluginModuleChild.h"
|
||||
#include "PluginInstanceChild.h"
|
||||
#include "PluginScriptableObjectUtils.h"
|
||||
|
||||
using namespace mozilla::plugins;
|
||||
using mozilla::ipc::NPRemoteIdentifier;
|
||||
|
||||
namespace {
|
||||
|
||||
inline NPObject*
|
||||
NPObjectFromVariant(const Variant& aRemoteVariant)
|
||||
{
|
||||
NS_ASSERTION(aRemoteVariant.type() ==
|
||||
Variant::TPPluginScriptableObjectChild,
|
||||
"Wrong variant type!");
|
||||
PluginScriptableObjectChild* actor =
|
||||
const_cast<PluginScriptableObjectChild*>(
|
||||
reinterpret_cast<const PluginScriptableObjectChild*>(
|
||||
aRemoteVariant.get_PPluginScriptableObjectChild()));
|
||||
return actor->GetObject();
|
||||
}
|
||||
|
||||
inline NPObject*
|
||||
NPObjectFromVariant(const NPVariant& aVariant)
|
||||
{
|
||||
NS_ASSERTION(NPVARIANT_IS_OBJECT(aVariant), "Wrong variant type!");
|
||||
return NPVARIANT_TO_OBJECT(aVariant);
|
||||
}
|
||||
|
||||
void
|
||||
ConvertToVariant(const Variant& aRemoteVariant,
|
||||
NPVariant& aVariant)
|
||||
{
|
||||
switch (aRemoteVariant.type()) {
|
||||
case Variant::Tvoid_t: {
|
||||
VOID_TO_NPVARIANT(aVariant);
|
||||
break;
|
||||
}
|
||||
|
||||
case Variant::Tnull_t: {
|
||||
NULL_TO_NPVARIANT(aVariant);
|
||||
break;
|
||||
}
|
||||
|
||||
case Variant::Tbool: {
|
||||
BOOLEAN_TO_NPVARIANT(aRemoteVariant.get_bool(), aVariant);
|
||||
break;
|
||||
}
|
||||
|
||||
case Variant::Tint: {
|
||||
INT32_TO_NPVARIANT(aRemoteVariant.get_int(), aVariant);
|
||||
break;
|
||||
}
|
||||
|
||||
case Variant::Tdouble: {
|
||||
DOUBLE_TO_NPVARIANT(aRemoteVariant.get_double(), aVariant);
|
||||
break;
|
||||
}
|
||||
|
||||
case Variant::TnsCString: {
|
||||
const nsCString& string = aRemoteVariant.get_nsCString();
|
||||
NPUTF8* buffer = reinterpret_cast<NPUTF8*>(strdup(string.get()));
|
||||
NS_ASSERTION(buffer, "Out of memory!");
|
||||
STRINGN_TO_NPVARIANT(buffer, string.Length(), aVariant);
|
||||
break;
|
||||
}
|
||||
|
||||
case Variant::TPPluginScriptableObjectChild: {
|
||||
NPObject* object = NPObjectFromVariant(aRemoteVariant);
|
||||
NS_ASSERTION(object, "Null object?!");
|
||||
PluginModuleChild::sBrowserFuncs.retainobject(object);
|
||||
OBJECT_TO_NPVARIANT(object, aVariant);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
NS_RUNTIMEABORT("Shouldn't get here!");
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ConvertToRemoteVariant(const NPVariant& aVariant,
|
||||
Variant& aRemoteVariant,
|
||||
PluginInstanceChild* aInstance)
|
||||
{
|
||||
if (NPVARIANT_IS_VOID(aVariant)) {
|
||||
aRemoteVariant = mozilla::void_t();
|
||||
}
|
||||
else if (NPVARIANT_IS_NULL(aVariant)) {
|
||||
aRemoteVariant = mozilla::null_t();
|
||||
}
|
||||
else if (NPVARIANT_IS_BOOLEAN(aVariant)) {
|
||||
aRemoteVariant = NPVARIANT_TO_BOOLEAN(aVariant);
|
||||
}
|
||||
else if (NPVARIANT_IS_INT32(aVariant)) {
|
||||
aRemoteVariant = NPVARIANT_TO_INT32(aVariant);
|
||||
}
|
||||
else if (NPVARIANT_IS_DOUBLE(aVariant)) {
|
||||
aRemoteVariant = NPVARIANT_TO_DOUBLE(aVariant);
|
||||
}
|
||||
else if (NPVARIANT_IS_STRING(aVariant)) {
|
||||
NPString str = NPVARIANT_TO_STRING(aVariant);
|
||||
nsCString string(str.UTF8Characters, str.UTF8Length);
|
||||
aRemoteVariant = string;
|
||||
}
|
||||
else if (NPVARIANT_IS_OBJECT(aVariant)) {
|
||||
NS_ASSERTION(aInstance, "Must have an instance to wrap!");
|
||||
|
||||
NPObject* object = NPVARIANT_TO_OBJECT(aVariant);
|
||||
NS_ASSERTION(object, "Null object?!");
|
||||
|
||||
PluginScriptableObjectChild* actor = aInstance->GetActorForNPObject(object);
|
||||
if (!actor) {
|
||||
NS_ERROR("Failed to create actor!");
|
||||
return false;
|
||||
}
|
||||
aRemoteVariant = actor;
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Shouldn't get here!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
// static
|
||||
NPObject*
|
||||
PluginScriptableObjectChild::ScriptableAllocate(NPP aInstance,
|
||||
@ -176,15 +49,11 @@ PluginScriptableObjectChild::ScriptableAllocate(NPP aInstance,
|
||||
{
|
||||
AssertPluginThread();
|
||||
|
||||
NS_ASSERTION(aClass == PluginScriptableObjectChild::GetClass(),
|
||||
"Huh?! Wrong class!");
|
||||
|
||||
ChildNPObject* object = reinterpret_cast<ChildNPObject*>(
|
||||
PluginModuleChild::sBrowserFuncs.memalloc(sizeof(ChildNPObject)));
|
||||
if (object) {
|
||||
memset(object, 0, sizeof(ChildNPObject));
|
||||
if (aClass != GetClass()) {
|
||||
NS_RUNTIMEABORT("Huh?! Wrong class!");
|
||||
}
|
||||
return object;
|
||||
|
||||
return new ChildNPObject();
|
||||
}
|
||||
|
||||
// static
|
||||
@ -193,9 +62,8 @@ PluginScriptableObjectChild::ScriptableInvalidate(NPObject* aObject)
|
||||
{
|
||||
AssertPluginThread();
|
||||
|
||||
if (aObject->_class != PluginScriptableObjectChild::GetClass()) {
|
||||
NS_ERROR("Don't know what kind of object this is!");
|
||||
return;
|
||||
if (aObject->_class != GetClass()) {
|
||||
NS_RUNTIMEABORT("Don't know what kind of object this is!");
|
||||
}
|
||||
|
||||
ChildNPObject* object = reinterpret_cast<ChildNPObject*>(aObject);
|
||||
@ -204,21 +72,7 @@ PluginScriptableObjectChild::ScriptableInvalidate(NPObject* aObject)
|
||||
return;
|
||||
}
|
||||
|
||||
PluginScriptableObjectChild* actor = object->parent;
|
||||
|
||||
PluginInstanceChild* instance = actor ? actor->GetInstance() : nsnull;
|
||||
NS_WARN_IF_FALSE(instance, "No instance!");
|
||||
|
||||
if (actor && !actor->CallInvalidate()) {
|
||||
NS_WARNING("Failed to send message!");
|
||||
}
|
||||
|
||||
object->invalidated = true;
|
||||
|
||||
if (instance &&
|
||||
!PPluginScriptableObjectChild::Call__delete__(object->parent)) {
|
||||
NS_WARNING("Failed to send message!");
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
@ -227,19 +81,23 @@ PluginScriptableObjectChild::ScriptableDeallocate(NPObject* aObject)
|
||||
{
|
||||
AssertPluginThread();
|
||||
|
||||
if (aObject->_class != PluginScriptableObjectChild::GetClass()) {
|
||||
NS_ERROR("Don't know what kind of object this is!");
|
||||
return;
|
||||
if (aObject->_class != GetClass()) {
|
||||
NS_RUNTIMEABORT("Don't know what kind of object this is!");
|
||||
}
|
||||
|
||||
ChildNPObject* object = reinterpret_cast<ChildNPObject*>(aObject);
|
||||
if (!object->invalidated) {
|
||||
ScriptableInvalidate(aObject);
|
||||
}
|
||||
NS_ASSERTION(object->invalidated, "Should have invalidated already!");
|
||||
|
||||
NS_ASSERTION(object->invalidated, "Should be invalidated!");
|
||||
PluginScriptableObjectChild* actor = object->parent;
|
||||
if (actor) {
|
||||
NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
|
||||
actor->DropNPObject();
|
||||
}
|
||||
|
||||
NS_Free(aObject);
|
||||
delete object;
|
||||
}
|
||||
|
||||
// static
|
||||
@ -249,9 +107,8 @@ PluginScriptableObjectChild::ScriptableHasMethod(NPObject* aObject,
|
||||
{
|
||||
AssertPluginThread();
|
||||
|
||||
if (aObject->_class != PluginScriptableObjectChild::GetClass()) {
|
||||
NS_ERROR("Don't know what kind of object this is!");
|
||||
return false;
|
||||
if (aObject->_class != GetClass()) {
|
||||
NS_RUNTIMEABORT("Don't know what kind of object this is!");
|
||||
}
|
||||
|
||||
ChildNPObject* object = reinterpret_cast<ChildNPObject*>(aObject);
|
||||
@ -260,14 +117,12 @@ PluginScriptableObjectChild::ScriptableHasMethod(NPObject* aObject,
|
||||
return false;
|
||||
}
|
||||
|
||||
PluginScriptableObjectChild* actor = object->parent;
|
||||
ProtectedActor<PluginScriptableObjectChild> actor(object->parent);
|
||||
NS_ASSERTION(actor, "This shouldn't ever be null!");
|
||||
NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
|
||||
|
||||
bool result;
|
||||
if (!actor->CallHasMethod((NPRemoteIdentifier)aName, &result)) {
|
||||
NS_WARNING("Failed to send message!");
|
||||
return false;
|
||||
}
|
||||
actor->CallHasMethod((NPRemoteIdentifier)aName, &result);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -282,9 +137,8 @@ PluginScriptableObjectChild::ScriptableInvoke(NPObject* aObject,
|
||||
{
|
||||
AssertPluginThread();
|
||||
|
||||
if (aObject->_class != PluginScriptableObjectChild::GetClass()) {
|
||||
NS_ERROR("Don't know what kind of object this is!");
|
||||
return false;
|
||||
if (aObject->_class != GetClass()) {
|
||||
NS_RUNTIMEABORT("Don't know what kind of object this is!");
|
||||
}
|
||||
|
||||
ChildNPObject* object = reinterpret_cast<ChildNPObject*>(aObject);
|
||||
@ -293,30 +147,19 @@ PluginScriptableObjectChild::ScriptableInvoke(NPObject* aObject,
|
||||
return false;
|
||||
}
|
||||
|
||||
PluginScriptableObjectChild* actor = object->parent;
|
||||
ProtectedActor<PluginScriptableObjectChild> actor(object->parent);
|
||||
NS_ASSERTION(actor, "This shouldn't ever be null!");
|
||||
NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
|
||||
|
||||
nsAutoTArray<Variant, 10> args;
|
||||
if (!args.SetLength(aArgCount)) {
|
||||
NS_ERROR("Out of memory?!");
|
||||
ProtectedVariantArray args(aArgs, aArgCount, actor->GetInstance());
|
||||
if (!args.IsOk()) {
|
||||
NS_ERROR("Failed to convert arguments!");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (PRUint32 index = 0; index < aArgCount; index++) {
|
||||
Variant& arg = args[index];
|
||||
if (!ConvertToRemoteVariant(aArgs[index], arg, actor->GetInstance())) {
|
||||
NS_WARNING("Failed to convert argument!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Variant remoteResult;
|
||||
bool success;
|
||||
if (!actor->CallInvoke((NPRemoteIdentifier)aName, args, &remoteResult,
|
||||
&success)) {
|
||||
NS_WARNING("Failed to send message!");
|
||||
return false;
|
||||
}
|
||||
actor->CallInvoke((NPRemoteIdentifier)aName, args, &remoteResult, &success);
|
||||
|
||||
if (!success) {
|
||||
return false;
|
||||
@ -335,9 +178,8 @@ PluginScriptableObjectChild::ScriptableInvokeDefault(NPObject* aObject,
|
||||
{
|
||||
AssertPluginThread();
|
||||
|
||||
if (aObject->_class != PluginScriptableObjectChild::GetClass()) {
|
||||
NS_ERROR("Don't know what kind of object this is!");
|
||||
return false;
|
||||
if (aObject->_class != GetClass()) {
|
||||
NS_RUNTIMEABORT("Don't know what kind of object this is!");
|
||||
}
|
||||
|
||||
ChildNPObject* object = reinterpret_cast<ChildNPObject*>(aObject);
|
||||
@ -346,29 +188,19 @@ PluginScriptableObjectChild::ScriptableInvokeDefault(NPObject* aObject,
|
||||
return false;
|
||||
}
|
||||
|
||||
PluginScriptableObjectChild* actor = object->parent;
|
||||
ProtectedActor<PluginScriptableObjectChild> actor(object->parent);
|
||||
NS_ASSERTION(actor, "This shouldn't ever be null!");
|
||||
NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
|
||||
|
||||
nsAutoTArray<Variant, 10> args;
|
||||
if (!args.SetLength(aArgCount)) {
|
||||
NS_ERROR("Out of memory?!");
|
||||
ProtectedVariantArray args(aArgs, aArgCount, actor->GetInstance());
|
||||
if (!args.IsOk()) {
|
||||
NS_ERROR("Failed to convert arguments!");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (PRUint32 index = 0; index < aArgCount; index++) {
|
||||
Variant& arg = args[index];
|
||||
if (!ConvertToRemoteVariant(aArgs[index], arg, actor->GetInstance())) {
|
||||
NS_WARNING("Failed to convert argument!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Variant remoteResult;
|
||||
bool success;
|
||||
if (!actor->CallInvokeDefault(args, &remoteResult, &success)) {
|
||||
NS_WARNING("Failed to send message!");
|
||||
return false;
|
||||
}
|
||||
actor->CallInvokeDefault(args, &remoteResult, &success);
|
||||
|
||||
if (!success) {
|
||||
return false;
|
||||
@ -385,9 +217,8 @@ PluginScriptableObjectChild::ScriptableHasProperty(NPObject* aObject,
|
||||
{
|
||||
AssertPluginThread();
|
||||
|
||||
if (aObject->_class != PluginScriptableObjectChild::GetClass()) {
|
||||
NS_ERROR("Don't know what kind of object this is!");
|
||||
return false;
|
||||
if (aObject->_class != GetClass()) {
|
||||
NS_RUNTIMEABORT("Don't know what kind of object this is!");
|
||||
}
|
||||
|
||||
ChildNPObject* object = reinterpret_cast<ChildNPObject*>(aObject);
|
||||
@ -396,14 +227,12 @@ PluginScriptableObjectChild::ScriptableHasProperty(NPObject* aObject,
|
||||
return false;
|
||||
}
|
||||
|
||||
PluginScriptableObjectChild* actor = object->parent;
|
||||
ProtectedActor<PluginScriptableObjectChild> actor(object->parent);
|
||||
NS_ASSERTION(actor, "This shouldn't ever be null!");
|
||||
NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
|
||||
|
||||
bool result;
|
||||
if (!actor->CallHasProperty((NPRemoteIdentifier)aName, &result)) {
|
||||
NS_WARNING("Failed to send message!");
|
||||
return false;
|
||||
}
|
||||
actor->CallHasProperty((NPRemoteIdentifier)aName, &result);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -416,9 +245,8 @@ PluginScriptableObjectChild::ScriptableGetProperty(NPObject* aObject,
|
||||
{
|
||||
AssertPluginThread();
|
||||
|
||||
if (aObject->_class != PluginScriptableObjectChild::GetClass()) {
|
||||
NS_ERROR("Don't know what kind of object this is!");
|
||||
return false;
|
||||
if (aObject->_class != GetClass()) {
|
||||
NS_RUNTIMEABORT("Don't know what kind of object this is!");
|
||||
}
|
||||
|
||||
ChildNPObject* object = reinterpret_cast<ChildNPObject*>(aObject);
|
||||
@ -427,15 +255,13 @@ PluginScriptableObjectChild::ScriptableGetProperty(NPObject* aObject,
|
||||
return false;
|
||||
}
|
||||
|
||||
PluginScriptableObjectChild* actor = object->parent;
|
||||
ProtectedActor<PluginScriptableObjectChild> actor(object->parent);
|
||||
NS_ASSERTION(actor, "This shouldn't ever be null!");
|
||||
NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
|
||||
|
||||
Variant result;
|
||||
bool success;
|
||||
if (!actor->CallGetProperty((NPRemoteIdentifier)aName, &result, &success)) {
|
||||
NS_WARNING("Failed to send message!");
|
||||
return false;
|
||||
}
|
||||
actor->CallGetProperty((NPRemoteIdentifier)aName, &result, &success);
|
||||
|
||||
if (!success) {
|
||||
return false;
|
||||
@ -453,9 +279,8 @@ PluginScriptableObjectChild::ScriptableSetProperty(NPObject* aObject,
|
||||
{
|
||||
AssertPluginThread();
|
||||
|
||||
if (aObject->_class != PluginScriptableObjectChild::GetClass()) {
|
||||
NS_ERROR("Don't know what kind of object this is!");
|
||||
return false;
|
||||
if (aObject->_class != GetClass()) {
|
||||
NS_RUNTIMEABORT("Don't know what kind of object this is!");
|
||||
}
|
||||
|
||||
ChildNPObject* object = reinterpret_cast<ChildNPObject*>(aObject);
|
||||
@ -464,20 +289,18 @@ PluginScriptableObjectChild::ScriptableSetProperty(NPObject* aObject,
|
||||
return false;
|
||||
}
|
||||
|
||||
PluginScriptableObjectChild* actor = object->parent;
|
||||
ProtectedActor<PluginScriptableObjectChild> actor(object->parent);
|
||||
NS_ASSERTION(actor, "This shouldn't ever be null!");
|
||||
NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
|
||||
|
||||
Variant value;
|
||||
if (!ConvertToRemoteVariant(*aValue, value, actor->GetInstance())) {
|
||||
ProtectedVariant value(*aValue, actor->GetInstance());
|
||||
if (!value.IsOk()) {
|
||||
NS_WARNING("Failed to convert variant!");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool success;
|
||||
if (!actor->CallSetProperty((NPRemoteIdentifier)aName, value, &success)) {
|
||||
NS_WARNING("Failed to send message!");
|
||||
return false;
|
||||
}
|
||||
actor->CallSetProperty((NPRemoteIdentifier)aName, value, &success);
|
||||
|
||||
return success;
|
||||
}
|
||||
@ -489,9 +312,8 @@ PluginScriptableObjectChild::ScriptableRemoveProperty(NPObject* aObject,
|
||||
{
|
||||
AssertPluginThread();
|
||||
|
||||
if (aObject->_class != PluginScriptableObjectChild::GetClass()) {
|
||||
NS_ERROR("Don't know what kind of object this is!");
|
||||
return false;
|
||||
if (aObject->_class != GetClass()) {
|
||||
NS_RUNTIMEABORT("Don't know what kind of object this is!");
|
||||
}
|
||||
|
||||
ChildNPObject* object = reinterpret_cast<ChildNPObject*>(aObject);
|
||||
@ -500,14 +322,12 @@ PluginScriptableObjectChild::ScriptableRemoveProperty(NPObject* aObject,
|
||||
return false;
|
||||
}
|
||||
|
||||
PluginScriptableObjectChild* actor = object->parent;
|
||||
ProtectedActor<PluginScriptableObjectChild> actor(object->parent);
|
||||
NS_ASSERTION(actor, "This shouldn't ever be null!");
|
||||
NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
|
||||
|
||||
bool success;
|
||||
if (!actor->CallRemoveProperty((NPRemoteIdentifier)aName, &success)) {
|
||||
NS_WARNING("Failed to send message!");
|
||||
return false;
|
||||
}
|
||||
actor->CallRemoveProperty((NPRemoteIdentifier)aName, &success);
|
||||
|
||||
return success;
|
||||
}
|
||||
@ -520,9 +340,8 @@ PluginScriptableObjectChild::ScriptableEnumerate(NPObject* aObject,
|
||||
{
|
||||
AssertPluginThread();
|
||||
|
||||
if (aObject->_class != PluginScriptableObjectChild::GetClass()) {
|
||||
NS_ERROR("Don't know what kind of object this is!");
|
||||
return false;
|
||||
if (aObject->_class != GetClass()) {
|
||||
NS_RUNTIMEABORT("Don't know what kind of object this is!");
|
||||
}
|
||||
|
||||
ChildNPObject* object = reinterpret_cast<ChildNPObject*>(aObject);
|
||||
@ -531,15 +350,13 @@ PluginScriptableObjectChild::ScriptableEnumerate(NPObject* aObject,
|
||||
return false;
|
||||
}
|
||||
|
||||
PluginScriptableObjectChild* actor = object->parent;
|
||||
ProtectedActor<PluginScriptableObjectChild> actor(object->parent);
|
||||
NS_ASSERTION(actor, "This shouldn't ever be null!");
|
||||
NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
|
||||
|
||||
nsAutoTArray<NPRemoteIdentifier, 10> identifiers;
|
||||
bool success;
|
||||
if (!actor->CallEnumerate(&identifiers, &success)) {
|
||||
NS_WARNING("Failed to send message!");
|
||||
return false;
|
||||
}
|
||||
actor->CallEnumerate(&identifiers, &success);
|
||||
|
||||
if (!success) {
|
||||
return false;
|
||||
@ -573,9 +390,8 @@ PluginScriptableObjectChild::ScriptableConstruct(NPObject* aObject,
|
||||
{
|
||||
AssertPluginThread();
|
||||
|
||||
if (aObject->_class != PluginScriptableObjectChild::GetClass()) {
|
||||
NS_ERROR("Don't know what kind of object this is!");
|
||||
return false;
|
||||
if (aObject->_class != GetClass()) {
|
||||
NS_RUNTIMEABORT("Don't know what kind of object this is!");
|
||||
}
|
||||
|
||||
ChildNPObject* object = reinterpret_cast<ChildNPObject*>(aObject);
|
||||
@ -584,29 +400,19 @@ PluginScriptableObjectChild::ScriptableConstruct(NPObject* aObject,
|
||||
return false;
|
||||
}
|
||||
|
||||
PluginScriptableObjectChild* actor = object->parent;
|
||||
ProtectedActor<PluginScriptableObjectChild> actor(object->parent);
|
||||
NS_ASSERTION(actor, "This shouldn't ever be null!");
|
||||
NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
|
||||
|
||||
nsAutoTArray<Variant, 10> args;
|
||||
if (!args.SetLength(aArgCount)) {
|
||||
NS_ERROR("Out of memory?!");
|
||||
ProtectedVariantArray args(aArgs, aArgCount, actor->GetInstance());
|
||||
if (!args.IsOk()) {
|
||||
NS_ERROR("Failed to convert arguments!");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (PRUint32 index = 0; index < aArgCount; index++) {
|
||||
Variant& arg = args[index];
|
||||
if (!ConvertToRemoteVariant(aArgs[index], arg, actor->GetInstance())) {
|
||||
NS_WARNING("Failed to convert argument!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Variant remoteResult;
|
||||
bool success;
|
||||
if (!actor->CallConstruct(args, &remoteResult, &success)) {
|
||||
NS_WARNING("Failed to send message!");
|
||||
return false;
|
||||
}
|
||||
actor->CallConstruct(args, &remoteResult, &success);
|
||||
|
||||
if (!success) {
|
||||
return false;
|
||||
@ -632,9 +438,13 @@ const NPClass PluginScriptableObjectChild::sNPClass = {
|
||||
PluginScriptableObjectChild::ScriptableConstruct
|
||||
};
|
||||
|
||||
PluginScriptableObjectChild::PluginScriptableObjectChild()
|
||||
PluginScriptableObjectChild::PluginScriptableObjectChild(
|
||||
ScriptableObjectType aType)
|
||||
: mInstance(nsnull),
|
||||
mObject(nsnull)
|
||||
mObject(nsnull),
|
||||
mInvalidated(false),
|
||||
mProtectCount(0),
|
||||
mType(aType)
|
||||
{
|
||||
AssertPluginThread();
|
||||
}
|
||||
@ -645,69 +455,183 @@ PluginScriptableObjectChild::~PluginScriptableObjectChild()
|
||||
|
||||
if (mObject) {
|
||||
if (mObject->_class == GetClass()) {
|
||||
if (!static_cast<ChildNPObject*>(mObject)->invalidated) {
|
||||
NS_WARNING("This should have happened already!");
|
||||
ScriptableInvalidate(mObject);
|
||||
}
|
||||
NS_ASSERTION(mType == Proxy, "Wrong type!");
|
||||
static_cast<ChildNPObject*>(mObject)->parent = nsnull;
|
||||
}
|
||||
else {
|
||||
// Make sure we've invalidated our NPObject so that the plugin doesn't
|
||||
// hold an object with a dangling pointer.
|
||||
|
||||
// Calling a virtual in the destructor, make sure we call the right one.
|
||||
PluginScriptableObjectChild::AnswerInvalidate();
|
||||
NS_ASSERTION(mType == LocalObject, "Wrong type!");
|
||||
PluginModuleChild::sBrowserFuncs.releaseobject(mObject);
|
||||
}
|
||||
}
|
||||
|
||||
NS_ASSERTION(!PluginModuleChild::current()->
|
||||
NPObjectIsRegisteredForActor(this),
|
||||
"NPObjects still registered for this actor!");
|
||||
}
|
||||
|
||||
void
|
||||
PluginScriptableObjectChild::Initialize(PluginInstanceChild* aInstance,
|
||||
NPObject* aObject)
|
||||
PluginScriptableObjectChild::InitializeProxy()
|
||||
{
|
||||
AssertPluginThread();
|
||||
NS_ASSERTION(mType == Proxy, "Bad type!");
|
||||
NS_ASSERTION(!mObject, "Calling Initialize more than once!");
|
||||
NS_ASSERTION(!mInvalidated, "Already invalidated?!");
|
||||
|
||||
NS_ASSERTION(!(mInstance && mObject), "Calling Initialize class twice!");
|
||||
mInstance = static_cast<PluginInstanceChild*>(Manager());
|
||||
NS_ASSERTION(mInstance, "Null manager?!");
|
||||
|
||||
if (aObject->_class == GetClass()) {
|
||||
ChildNPObject* object = static_cast<ChildNPObject*>(aObject);
|
||||
NPObject* object = CreateProxyObject();
|
||||
NS_ASSERTION(object, "Failed to create object!");
|
||||
|
||||
NS_ASSERTION(!object->parent, "Bad object!");
|
||||
object->parent = const_cast<PluginScriptableObjectChild*>(this);
|
||||
|
||||
// We don't want to have the actor own this object but rather let the object
|
||||
// own this actor. Set the reference count to 0 here so that when the object
|
||||
// dies we will send the destructor message to the parent.
|
||||
NS_ASSERTION(aObject->referenceCount == 1, "Some kind of live object!");
|
||||
aObject->referenceCount = 0;
|
||||
NS_LOG_RELEASE(aObject, 0, "ChildNPObject");
|
||||
}
|
||||
else {
|
||||
// Plugin-provided object, retain here. This should be the only reference we
|
||||
// ever need.
|
||||
PluginModuleChild::sBrowserFuncs.retainobject(aObject);
|
||||
if (!PluginModuleChild::current()->RegisterNPObject(object, this)) {
|
||||
NS_ERROR("Out of memory?");
|
||||
}
|
||||
|
||||
mObject = object;
|
||||
}
|
||||
|
||||
void
|
||||
PluginScriptableObjectChild::InitializeLocal(NPObject* aObject)
|
||||
{
|
||||
AssertPluginThread();
|
||||
NS_ASSERTION(mType == LocalObject, "Bad type!");
|
||||
NS_ASSERTION(!mObject, "Calling Initialize more than once!");
|
||||
NS_ASSERTION(!mInvalidated, "Already invalidated?!");
|
||||
|
||||
mInstance = static_cast<PluginInstanceChild*>(Manager());
|
||||
NS_ASSERTION(mInstance, "Null manager?!");
|
||||
|
||||
PluginModuleChild::sBrowserFuncs.retainobject(aObject);
|
||||
|
||||
NS_ASSERTION(!mProtectCount, "Should be zero!");
|
||||
mProtectCount++;
|
||||
|
||||
if (!PluginModuleChild::current()->RegisterNPObject(aObject, this)) {
|
||||
NS_ERROR("Out of memory?");
|
||||
}
|
||||
|
||||
mInstance = aInstance;
|
||||
mObject = aObject;
|
||||
}
|
||||
|
||||
NPObject*
|
||||
PluginScriptableObjectChild::CreateProxyObject()
|
||||
{
|
||||
NS_ASSERTION(mInstance, "Must have an instance!");
|
||||
NS_ASSERTION(mType == Proxy, "Shouldn't call this for non-proxy object!");
|
||||
|
||||
NPClass* proxyClass = const_cast<NPClass*>(GetClass());
|
||||
NPObject* npobject =
|
||||
PluginModuleChild::sBrowserFuncs.createobject(mInstance->GetNPP(),
|
||||
proxyClass);
|
||||
NS_ASSERTION(npobject, "Failed to create object?!");
|
||||
NS_ASSERTION(npobject->_class == GetClass(), "Wrong kind of object!");
|
||||
NS_ASSERTION(npobject->referenceCount == 1, "Some kind of live object!");
|
||||
|
||||
ChildNPObject* object = static_cast<ChildNPObject*>(npobject);
|
||||
NS_ASSERTION(!object->invalidated, "Bad object!");
|
||||
NS_ASSERTION(!object->parent, "Bad object!");
|
||||
|
||||
// We don't want to have the actor own this object but rather let the object
|
||||
// own this actor. Set the reference count to 0 here so that when the object
|
||||
// dies we will send the destructor message to the child.
|
||||
object->referenceCount = 0;
|
||||
NS_LOG_RELEASE(object, 0, "ChildNPObject");
|
||||
|
||||
object->parent = const_cast<PluginScriptableObjectChild*>(this);
|
||||
return object;
|
||||
}
|
||||
|
||||
bool
|
||||
PluginScriptableObjectChild::ResurrectProxyObject()
|
||||
{
|
||||
NS_ASSERTION(mInstance, "Must have an instance already!");
|
||||
NS_ASSERTION(!mObject, "Should not have an object already!");
|
||||
NS_ASSERTION(mType == Proxy, "Shouldn't call this for non-proxy object!");
|
||||
|
||||
NPObject* object = CreateProxyObject();
|
||||
if (!object) {
|
||||
NS_WARNING("Failed to create object!");
|
||||
return false;
|
||||
}
|
||||
|
||||
InitializeProxy();
|
||||
NS_ASSERTION(mObject, "Initialize failed!");
|
||||
|
||||
CallProtect();
|
||||
return true;
|
||||
}
|
||||
|
||||
NPObject*
|
||||
PluginScriptableObjectChild::GetObject(bool aCanResurrect)
|
||||
{
|
||||
if (!mObject && aCanResurrect && !ResurrectProxyObject()) {
|
||||
NS_ERROR("Null object!");
|
||||
return nsnull;
|
||||
}
|
||||
return mObject;
|
||||
}
|
||||
|
||||
void
|
||||
PluginScriptableObjectChild::Protect()
|
||||
{
|
||||
NS_ASSERTION(mObject, "No object!");
|
||||
NS_ASSERTION(mProtectCount >= 0, "Negative retain count?!");
|
||||
|
||||
if (mType == LocalObject) {
|
||||
++mProtectCount;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PluginScriptableObjectChild::Unprotect()
|
||||
{
|
||||
NS_ASSERTION(mObject, "Bad state!");
|
||||
NS_ASSERTION(mProtectCount >= 0, "Negative retain count?!");
|
||||
|
||||
if (mType == LocalObject) {
|
||||
if (--mProtectCount == 0) {
|
||||
PluginScriptableObjectChild::Call__delete__(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PluginScriptableObjectChild::DropNPObject()
|
||||
{
|
||||
NS_ASSERTION(mObject, "Invalidated object!");
|
||||
NS_ASSERTION(mObject->_class == GetClass(), "Wrong type of object!");
|
||||
NS_ASSERTION(mType == Proxy, "Shouldn't call this for non-proxy object!");
|
||||
|
||||
// We think we're about to be deleted, but we could be racing with the other
|
||||
// process.
|
||||
PluginModuleChild::current()->UnregisterNPObject(mObject);
|
||||
mObject = nsnull;
|
||||
|
||||
CallUnprotect();
|
||||
}
|
||||
|
||||
bool
|
||||
PluginScriptableObjectChild::AnswerInvalidate()
|
||||
{
|
||||
AssertPluginThread();
|
||||
|
||||
if (mObject) {
|
||||
NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
|
||||
if (mObject->_class && mObject->_class->invalidate) {
|
||||
mObject->_class->invalidate(mObject);
|
||||
}
|
||||
PluginModuleChild::current()->UnregisterNPObject(mObject);
|
||||
PluginModuleChild::sBrowserFuncs.releaseobject(mObject);
|
||||
mObject = nsnull;
|
||||
if (mInvalidated) {
|
||||
NS_WARNING("Called invalidate more than once?!");
|
||||
return true;
|
||||
}
|
||||
|
||||
mInvalidated = true;
|
||||
|
||||
NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
|
||||
NS_ASSERTION(mType == LocalObject, "Bad type!");
|
||||
|
||||
if (mObject->_class && mObject->_class->invalidate) {
|
||||
mObject->_class->invalidate(mObject);
|
||||
}
|
||||
|
||||
PluginModuleChild::current()->UnregisterNPObject(mObject);
|
||||
Unprotect();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -717,13 +641,14 @@ PluginScriptableObjectChild::AnswerHasMethod(const NPRemoteIdentifier& aId,
|
||||
{
|
||||
AssertPluginThread();
|
||||
|
||||
if (!mObject) {
|
||||
if (mInvalidated) {
|
||||
NS_WARNING("Calling AnswerHasMethod with an invalidated object!");
|
||||
*aHasMethod = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
|
||||
NS_ASSERTION(mType == LocalObject, "Bad type!");
|
||||
|
||||
if (!(mObject->_class && mObject->_class->hasMethod)) {
|
||||
*aHasMethod = false;
|
||||
@ -742,7 +667,7 @@ PluginScriptableObjectChild::AnswerInvoke(const NPRemoteIdentifier& aId,
|
||||
{
|
||||
AssertPluginThread();
|
||||
|
||||
if (!mObject) {
|
||||
if (mInvalidated) {
|
||||
NS_WARNING("Calling AnswerInvoke with an invalidated object!");
|
||||
*aResult = void_t();
|
||||
*aSuccess = false;
|
||||
@ -750,6 +675,7 @@ PluginScriptableObjectChild::AnswerInvoke(const NPRemoteIdentifier& aId,
|
||||
}
|
||||
|
||||
NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
|
||||
NS_ASSERTION(mType == LocalObject, "Bad type!");
|
||||
|
||||
if (!(mObject->_class && mObject->_class->invoke)) {
|
||||
*aResult = void_t();
|
||||
@ -786,7 +712,8 @@ PluginScriptableObjectChild::AnswerInvoke(const NPRemoteIdentifier& aId,
|
||||
}
|
||||
|
||||
Variant convertedResult;
|
||||
success = ConvertToRemoteVariant(result, convertedResult, GetInstance());
|
||||
success = ConvertToRemoteVariant(result, convertedResult, GetInstance(),
|
||||
false);
|
||||
|
||||
DeferNPVariantLastRelease(&PluginModuleChild::sBrowserFuncs, &result);
|
||||
|
||||
@ -808,7 +735,7 @@ PluginScriptableObjectChild::AnswerInvokeDefault(const nsTArray<Variant>& aArgs,
|
||||
{
|
||||
AssertPluginThread();
|
||||
|
||||
if (!mObject) {
|
||||
if (mInvalidated) {
|
||||
NS_WARNING("Calling AnswerInvokeDefault with an invalidated object!");
|
||||
*aResult = void_t();
|
||||
*aSuccess = false;
|
||||
@ -816,6 +743,7 @@ PluginScriptableObjectChild::AnswerInvokeDefault(const nsTArray<Variant>& aArgs,
|
||||
}
|
||||
|
||||
NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
|
||||
NS_ASSERTION(mType == LocalObject, "Bad type!");
|
||||
|
||||
if (!(mObject->_class && mObject->_class->invokeDefault)) {
|
||||
*aResult = void_t();
|
||||
@ -852,7 +780,8 @@ PluginScriptableObjectChild::AnswerInvokeDefault(const nsTArray<Variant>& aArgs,
|
||||
}
|
||||
|
||||
Variant convertedResult;
|
||||
success = ConvertToRemoteVariant(result, convertedResult, GetInstance());
|
||||
success = ConvertToRemoteVariant(result, convertedResult, GetInstance(),
|
||||
false);
|
||||
|
||||
DeferNPVariantLastRelease(&PluginModuleChild::sBrowserFuncs, &result);
|
||||
|
||||
@ -873,13 +802,14 @@ PluginScriptableObjectChild::AnswerHasProperty(const NPRemoteIdentifier& aId,
|
||||
{
|
||||
AssertPluginThread();
|
||||
|
||||
if (!mObject) {
|
||||
if (mInvalidated) {
|
||||
NS_WARNING("Calling AnswerHasProperty with an invalidated object!");
|
||||
*aHasProperty = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
|
||||
NS_ASSERTION(mType == LocalObject, "Bad type!");
|
||||
|
||||
if (!(mObject->_class && mObject->_class->hasProperty)) {
|
||||
*aHasProperty = false;
|
||||
@ -897,7 +827,7 @@ PluginScriptableObjectChild::AnswerGetProperty(const NPRemoteIdentifier& aId,
|
||||
{
|
||||
AssertPluginThread();
|
||||
|
||||
if (!mObject) {
|
||||
if (mInvalidated) {
|
||||
NS_WARNING("Calling AnswerGetProperty with an invalidated object!");
|
||||
*aResult = void_t();
|
||||
*aSuccess = false;
|
||||
@ -905,6 +835,7 @@ PluginScriptableObjectChild::AnswerGetProperty(const NPRemoteIdentifier& aId,
|
||||
}
|
||||
|
||||
NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
|
||||
NS_ASSERTION(mType == LocalObject, "Bad type!");
|
||||
|
||||
if (!(mObject->_class && mObject->_class->getProperty)) {
|
||||
*aResult = void_t();
|
||||
@ -920,7 +851,8 @@ PluginScriptableObjectChild::AnswerGetProperty(const NPRemoteIdentifier& aId,
|
||||
}
|
||||
|
||||
Variant converted;
|
||||
if ((*aSuccess = ConvertToRemoteVariant(result, converted, GetInstance()))) {
|
||||
if ((*aSuccess = ConvertToRemoteVariant(result, converted, GetInstance(),
|
||||
false))) {
|
||||
DeferNPVariantLastRelease(&PluginModuleChild::sBrowserFuncs, &result);
|
||||
*aResult = converted;
|
||||
}
|
||||
@ -938,13 +870,14 @@ PluginScriptableObjectChild::AnswerSetProperty(const NPRemoteIdentifier& aId,
|
||||
{
|
||||
AssertPluginThread();
|
||||
|
||||
if (!mObject) {
|
||||
if (mInvalidated) {
|
||||
NS_WARNING("Calling AnswerSetProperty with an invalidated object!");
|
||||
*aSuccess = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
|
||||
NS_ASSERTION(mType == LocalObject, "Bad type!");
|
||||
|
||||
if (!(mObject->_class && mObject->_class->setProperty)) {
|
||||
*aSuccess = false;
|
||||
@ -967,13 +900,14 @@ PluginScriptableObjectChild::AnswerRemoveProperty(const NPRemoteIdentifier& aId,
|
||||
{
|
||||
AssertPluginThread();
|
||||
|
||||
if (!mObject) {
|
||||
if (mInvalidated) {
|
||||
NS_WARNING("Calling AnswerRemoveProperty with an invalidated object!");
|
||||
*aSuccess = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
|
||||
NS_ASSERTION(mType == LocalObject, "Bad type!");
|
||||
|
||||
if (!(mObject->_class && mObject->_class->removeProperty)) {
|
||||
*aSuccess = false;
|
||||
@ -990,13 +924,14 @@ PluginScriptableObjectChild::AnswerEnumerate(nsTArray<NPRemoteIdentifier>* aProp
|
||||
{
|
||||
AssertPluginThread();
|
||||
|
||||
if (!mObject) {
|
||||
if (mInvalidated) {
|
||||
NS_WARNING("Calling AnswerEnumerate with an invalidated object!");
|
||||
*aSuccess = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
|
||||
NS_ASSERTION(mType == LocalObject, "Bad type!");
|
||||
|
||||
if (!(mObject->_class && mObject->_class->enumerate)) {
|
||||
*aSuccess = false;
|
||||
@ -1036,7 +971,7 @@ PluginScriptableObjectChild::AnswerConstruct(const nsTArray<Variant>& aArgs,
|
||||
{
|
||||
AssertPluginThread();
|
||||
|
||||
if (!mObject) {
|
||||
if (mInvalidated) {
|
||||
NS_WARNING("Calling AnswerConstruct with an invalidated object!");
|
||||
*aResult = void_t();
|
||||
*aSuccess = false;
|
||||
@ -1044,6 +979,7 @@ PluginScriptableObjectChild::AnswerConstruct(const nsTArray<Variant>& aArgs,
|
||||
}
|
||||
|
||||
NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
|
||||
NS_ASSERTION(mType == LocalObject, "Bad type!");
|
||||
|
||||
if (!(mObject->_class && mObject->_class->construct)) {
|
||||
*aResult = void_t();
|
||||
@ -1079,7 +1015,8 @@ PluginScriptableObjectChild::AnswerConstruct(const nsTArray<Variant>& aArgs,
|
||||
}
|
||||
|
||||
Variant convertedResult;
|
||||
success = ConvertToRemoteVariant(result, convertedResult, GetInstance());
|
||||
success = ConvertToRemoteVariant(result, convertedResult, GetInstance(),
|
||||
false);
|
||||
|
||||
DeferNPVariantLastRelease(&PluginModuleChild::sBrowserFuncs, &result);
|
||||
|
||||
@ -1094,6 +1031,26 @@ PluginScriptableObjectChild::AnswerConstruct(const nsTArray<Variant>& aArgs,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
PluginScriptableObjectChild::AnswerProtect()
|
||||
{
|
||||
NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
|
||||
NS_ASSERTION(mType == LocalObject, "Bad type!");
|
||||
|
||||
Protect();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
PluginScriptableObjectChild::AnswerUnprotect()
|
||||
{
|
||||
NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
|
||||
NS_ASSERTION(mType == LocalObject, "Bad type!");
|
||||
|
||||
Unprotect();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
PluginScriptableObjectChild::Evaluate(NPString* aScript,
|
||||
NPVariant* aResult)
|
||||
@ -1105,7 +1062,9 @@ PluginScriptableObjectChild::Evaluate(NPString* aScript,
|
||||
|
||||
bool success;
|
||||
Variant result;
|
||||
if (!(CallNPN_Evaluate(script, &result, &success) && success)) {
|
||||
CallNPN_Evaluate(script, &result, &success);
|
||||
|
||||
if (!success) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: sw=4 ts=4 et :
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=2 et :
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
@ -51,6 +51,11 @@ class PluginScriptableObjectChild;
|
||||
|
||||
struct ChildNPObject : NPObject
|
||||
{
|
||||
ChildNPObject()
|
||||
: NPObject(), parent(NULL), invalidated(false) { }
|
||||
|
||||
// |parent| is always valid as long as the actor is alive. Once the actor is
|
||||
// destroyed this will be set to null.
|
||||
PluginScriptableObjectChild* parent;
|
||||
bool invalidated;
|
||||
};
|
||||
@ -60,9 +65,16 @@ class PluginScriptableObjectChild : public PPluginScriptableObjectChild
|
||||
friend class PluginInstanceChild;
|
||||
|
||||
public:
|
||||
PluginScriptableObjectChild();
|
||||
PluginScriptableObjectChild(ScriptableObjectType aType);
|
||||
virtual ~PluginScriptableObjectChild();
|
||||
|
||||
void
|
||||
InitializeProxy();
|
||||
|
||||
void
|
||||
InitializeLocal(NPObject* aObject);
|
||||
|
||||
|
||||
virtual bool
|
||||
AnswerInvalidate();
|
||||
|
||||
@ -108,15 +120,14 @@ public:
|
||||
Variant* aResult,
|
||||
bool* aSuccess);
|
||||
|
||||
void
|
||||
Initialize(PluginInstanceChild* aInstance,
|
||||
NPObject* aObject);
|
||||
virtual bool
|
||||
AnswerProtect();
|
||||
|
||||
virtual bool
|
||||
AnswerUnprotect();
|
||||
|
||||
NPObject*
|
||||
GetObject()
|
||||
{
|
||||
return mObject;
|
||||
}
|
||||
GetObject(bool aCanResurrect);
|
||||
|
||||
static const NPClass*
|
||||
GetClass()
|
||||
@ -125,15 +136,39 @@ public:
|
||||
}
|
||||
|
||||
PluginInstanceChild*
|
||||
GetInstance()
|
||||
GetInstance() const
|
||||
{
|
||||
return mInstance;
|
||||
}
|
||||
|
||||
// Protect only affects LocalObject actors. It is called by the
|
||||
// ProtectedVariant/Actor helper classes before the actor is used as an
|
||||
// argument to an IPC call and when the parent process resurrects a
|
||||
// proxy object to the NPObject associated with this actor.
|
||||
void Protect();
|
||||
|
||||
// Unprotect only affects LocalObject actors. It is called by the
|
||||
// ProtectedVariant/Actor helper classes after the actor is used as an
|
||||
// argument to an IPC call and when the parent process is no longer using
|
||||
// this actor.
|
||||
void Unprotect();
|
||||
|
||||
// DropNPObject is only used for Proxy actors and is called when the child
|
||||
// process is no longer using the NPObject associated with this actor. The
|
||||
// parent process may subsequently use this actor again in which case a new
|
||||
// NPObject will be created and associated with this actor (see
|
||||
// ResurrectProxyObject).
|
||||
void DropNPObject();
|
||||
|
||||
bool
|
||||
Evaluate(NPString* aScript,
|
||||
NPVariant* aResult);
|
||||
|
||||
ScriptableObjectType
|
||||
Type() const {
|
||||
return mType;
|
||||
}
|
||||
|
||||
private:
|
||||
static NPObject*
|
||||
ScriptableAllocate(NPP aInstance,
|
||||
@ -191,9 +226,21 @@ private:
|
||||
uint32_t aArgCount,
|
||||
NPVariant* aResult);
|
||||
|
||||
NPObject*
|
||||
CreateProxyObject();
|
||||
|
||||
// ResurrectProxyObject is only used with Proxy actors. It is called when the
|
||||
// parent process uses an actor whose NPObject was deleted by the child
|
||||
// process.
|
||||
bool ResurrectProxyObject();
|
||||
|
||||
private:
|
||||
PluginInstanceChild* mInstance;
|
||||
NPObject* mObject;
|
||||
bool mInvalidated;
|
||||
int mProtectCount;
|
||||
|
||||
ScriptableObjectType mType;
|
||||
|
||||
static const NPClass sNPClass;
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=4 ts=4 et :
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=2 et :
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
@ -37,75 +37,13 @@
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "PluginScriptableObjectParent.h"
|
||||
#include "PluginInstanceParent.h"
|
||||
#include "PluginModuleParent.h"
|
||||
|
||||
#include "npapi.h"
|
||||
#include "nsDebug.h"
|
||||
#include "PluginScriptableObjectUtils.h"
|
||||
|
||||
using namespace mozilla::plugins;
|
||||
|
||||
using mozilla::ipc::NPRemoteIdentifier;
|
||||
|
||||
namespace {
|
||||
|
||||
inline PluginInstanceParent*
|
||||
GetInstance(NPObject* aObject)
|
||||
{
|
||||
NS_ASSERTION(aObject->_class == PluginScriptableObjectParent::GetClass(),
|
||||
"Bad class!");
|
||||
|
||||
ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
|
||||
if (!object->parent) {
|
||||
NS_WARNING("Calling method on an invalidated object!");
|
||||
return nsnull;
|
||||
}
|
||||
return object->parent->GetInstance();
|
||||
}
|
||||
|
||||
inline const NPNetscapeFuncs*
|
||||
GetNetscapeFuncs(PluginInstanceParent* aInstance)
|
||||
{
|
||||
PluginModuleParent* module = aInstance->Module();
|
||||
if (!module) {
|
||||
NS_WARNING("Null module?!");
|
||||
return nsnull;
|
||||
}
|
||||
return module->GetNetscapeFuncs();
|
||||
}
|
||||
|
||||
inline const NPNetscapeFuncs*
|
||||
GetNetscapeFuncs(NPObject* aObject)
|
||||
{
|
||||
NS_ASSERTION(aObject->_class == PluginScriptableObjectParent::GetClass(),
|
||||
"Bad class!");
|
||||
|
||||
PluginInstanceParent* instance = GetInstance(aObject);
|
||||
if (!instance) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
return GetNetscapeFuncs(instance);
|
||||
}
|
||||
|
||||
inline NPObject*
|
||||
NPObjectFromVariant(const Variant& aRemoteVariant) {
|
||||
NS_ASSERTION(aRemoteVariant.type() ==
|
||||
Variant::TPPluginScriptableObjectParent,
|
||||
"Wrong variant type!");
|
||||
PluginScriptableObjectParent* actor =
|
||||
const_cast<PluginScriptableObjectParent*>(
|
||||
reinterpret_cast<const PluginScriptableObjectParent*>(
|
||||
aRemoteVariant.get_PPluginScriptableObjectParent()));
|
||||
return actor->GetObject();
|
||||
}
|
||||
|
||||
inline NPObject*
|
||||
NPObjectFromVariant(const NPVariant& aVariant) {
|
||||
NS_ASSERTION(NPVARIANT_IS_OBJECT(aVariant), "Wrong variant type!");
|
||||
return NPVARIANT_TO_OBJECT(aVariant);
|
||||
}
|
||||
|
||||
inline void
|
||||
ReleaseVariant(NPVariant& aVariant,
|
||||
PluginInstanceParent* aInstance)
|
||||
@ -142,115 +80,6 @@ EnsureValidIdentifier(NPObject* aObject,
|
||||
return EnsureValidIdentifier(instance, aIdentifier);
|
||||
}
|
||||
|
||||
bool
|
||||
ConvertToVariant(const Variant& aRemoteVariant,
|
||||
NPVariant& aVariant,
|
||||
PluginInstanceParent* aInstance)
|
||||
{
|
||||
switch (aRemoteVariant.type()) {
|
||||
case Variant::Tvoid_t: {
|
||||
VOID_TO_NPVARIANT(aVariant);
|
||||
break;
|
||||
}
|
||||
|
||||
case Variant::Tnull_t: {
|
||||
NULL_TO_NPVARIANT(aVariant);
|
||||
break;
|
||||
}
|
||||
|
||||
case Variant::Tbool: {
|
||||
BOOLEAN_TO_NPVARIANT(aRemoteVariant.get_bool(), aVariant);
|
||||
break;
|
||||
}
|
||||
|
||||
case Variant::Tint: {
|
||||
INT32_TO_NPVARIANT(aRemoteVariant.get_int(), aVariant);
|
||||
break;
|
||||
}
|
||||
|
||||
case Variant::Tdouble: {
|
||||
DOUBLE_TO_NPVARIANT(aRemoteVariant.get_double(), aVariant);
|
||||
break;
|
||||
}
|
||||
|
||||
case Variant::TnsCString: {
|
||||
const nsCString& string = aRemoteVariant.get_nsCString();
|
||||
NPUTF8* buffer = reinterpret_cast<NPUTF8*>(strdup(string.get()));
|
||||
if (!buffer) {
|
||||
NS_ERROR("Out of memory!");
|
||||
return false;
|
||||
}
|
||||
STRINGN_TO_NPVARIANT(buffer, string.Length(), aVariant);
|
||||
break;
|
||||
}
|
||||
|
||||
case Variant::TPPluginScriptableObjectParent: {
|
||||
NPObject* object = NPObjectFromVariant(aRemoteVariant);
|
||||
if (!object) {
|
||||
NS_ERROR("Er, this shouldn't fail!");
|
||||
return false;
|
||||
}
|
||||
|
||||
const NPNetscapeFuncs* npn = GetNetscapeFuncs(aInstance);
|
||||
if (!npn) {
|
||||
NS_ERROR("Null netscape funcs!");
|
||||
return false;
|
||||
}
|
||||
npn->retainobject(object);
|
||||
OBJECT_TO_NPVARIANT(object, aVariant);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
NS_NOTREACHED("Shouldn't get here!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ConvertToRemoteVariant(const NPVariant& aVariant,
|
||||
Variant& aRemoteVariant,
|
||||
PluginInstanceParent* aInstance)
|
||||
{
|
||||
if (NPVARIANT_IS_VOID(aVariant)) {
|
||||
aRemoteVariant = mozilla::void_t();
|
||||
}
|
||||
else if (NPVARIANT_IS_NULL(aVariant)) {
|
||||
aRemoteVariant = mozilla::null_t();
|
||||
}
|
||||
else if (NPVARIANT_IS_BOOLEAN(aVariant)) {
|
||||
aRemoteVariant = NPVARIANT_TO_BOOLEAN(aVariant);
|
||||
}
|
||||
else if (NPVARIANT_IS_INT32(aVariant)) {
|
||||
aRemoteVariant = NPVARIANT_TO_INT32(aVariant);
|
||||
}
|
||||
else if (NPVARIANT_IS_DOUBLE(aVariant)) {
|
||||
aRemoteVariant = NPVARIANT_TO_DOUBLE(aVariant);
|
||||
}
|
||||
else if (NPVARIANT_IS_STRING(aVariant)) {
|
||||
NPString str = NPVARIANT_TO_STRING(aVariant);
|
||||
nsCString string(str.UTF8Characters, str.UTF8Length);
|
||||
aRemoteVariant = string;
|
||||
}
|
||||
else if (NPVARIANT_IS_OBJECT(aVariant)) {
|
||||
NPObject* object = NPVARIANT_TO_OBJECT(aVariant);
|
||||
PluginScriptableObjectParent* actor = aInstance->GetActorForNPObject(object);
|
||||
if (!actor) {
|
||||
NS_ERROR("Null actor!");
|
||||
return false;
|
||||
}
|
||||
aRemoteVariant = actor;
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Shouldn't get here!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
// static
|
||||
@ -258,15 +87,8 @@ NPObject*
|
||||
PluginScriptableObjectParent::ScriptableAllocate(NPP aInstance,
|
||||
NPClass* aClass)
|
||||
{
|
||||
NS_ASSERTION(aClass == PluginScriptableObjectParent::GetClass(),
|
||||
"Huh?! Wrong class!");
|
||||
|
||||
PluginInstanceParent* instance = PluginModuleParent::InstCast(aInstance);
|
||||
NS_ASSERTION(instance, "This should never be null!");
|
||||
|
||||
const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance);
|
||||
if (!npn) {
|
||||
NS_WARNING("Can't allocate!");
|
||||
if (aClass != GetClass()) {
|
||||
NS_ERROR("Huh?! Wrong class!");
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
@ -277,31 +99,22 @@ PluginScriptableObjectParent::ScriptableAllocate(NPP aInstance,
|
||||
void
|
||||
PluginScriptableObjectParent::ScriptableInvalidate(NPObject* aObject)
|
||||
{
|
||||
if (aObject->_class != PluginScriptableObjectParent::GetClass()) {
|
||||
if (aObject->_class != GetClass()) {
|
||||
NS_ERROR("Don't know what kind of object this is!");
|
||||
return;
|
||||
}
|
||||
|
||||
ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
|
||||
if (!object->parent) {
|
||||
if (object->invalidated) {
|
||||
// This can happen more than once, and is just fine.
|
||||
return;
|
||||
}
|
||||
|
||||
PluginScriptableObjectParent* actor = object->parent;
|
||||
object->invalidated = true;
|
||||
|
||||
object->parent = NULL;
|
||||
|
||||
PluginInstanceParent* instance = actor->GetInstance();
|
||||
NS_WARN_IF_FALSE(instance, "No instance?!");
|
||||
|
||||
if (!actor->CallInvalidate()) {
|
||||
NS_WARNING("Failed to send message!");
|
||||
}
|
||||
|
||||
if (instance &&
|
||||
!PPluginScriptableObjectParent::Call__delete__(actor)) {
|
||||
NS_WARNING("Failed to send message!");
|
||||
// |object->parent| may be null already if the instance has gone away.
|
||||
if (object->parent && !object->parent->CallInvalidate()) {
|
||||
NS_ERROR("Failed to send message!");
|
||||
}
|
||||
}
|
||||
|
||||
@ -309,17 +122,22 @@ PluginScriptableObjectParent::ScriptableInvalidate(NPObject* aObject)
|
||||
void
|
||||
PluginScriptableObjectParent::ScriptableDeallocate(NPObject* aObject)
|
||||
{
|
||||
if (aObject->_class != PluginScriptableObjectParent::GetClass()) {
|
||||
if (aObject->_class != GetClass()) {
|
||||
NS_ERROR("Don't know what kind of object this is!");
|
||||
return;
|
||||
}
|
||||
|
||||
ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
|
||||
if (object->parent) {
|
||||
if (!object->invalidated) {
|
||||
ScriptableInvalidate(aObject);
|
||||
}
|
||||
NS_ASSERTION(object->invalidated, "Should have invalidated already!");
|
||||
|
||||
NS_ASSERTION(!object->parent, "Should be invalidated!");
|
||||
PluginScriptableObjectParent* actor = object->parent;
|
||||
if (actor) {
|
||||
NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
|
||||
actor->DropNPObject();
|
||||
}
|
||||
|
||||
delete object;
|
||||
}
|
||||
@ -329,13 +147,13 @@ bool
|
||||
PluginScriptableObjectParent::ScriptableHasMethod(NPObject* aObject,
|
||||
NPIdentifier aName)
|
||||
{
|
||||
if (aObject->_class != PluginScriptableObjectParent::GetClass()) {
|
||||
if (aObject->_class != GetClass()) {
|
||||
NS_ERROR("Don't know what kind of object this is!");
|
||||
return false;
|
||||
}
|
||||
|
||||
ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
|
||||
if (!object->parent) {
|
||||
if (object->invalidated) {
|
||||
NS_WARNING("Calling method on an invalidated object!");
|
||||
return false;
|
||||
}
|
||||
@ -344,8 +162,12 @@ PluginScriptableObjectParent::ScriptableHasMethod(NPObject* aObject,
|
||||
return false;
|
||||
}
|
||||
|
||||
PluginScriptableObjectParent* actor = object->parent;
|
||||
NS_ASSERTION(actor, "This shouldn't ever be null!");
|
||||
ProtectedActor<PluginScriptableObjectParent> actor(object->parent);
|
||||
if (!actor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
|
||||
|
||||
bool result;
|
||||
if (!actor->CallHasMethod((NPRemoteIdentifier)aName, &result)) {
|
||||
@ -364,13 +186,13 @@ PluginScriptableObjectParent::ScriptableInvoke(NPObject* aObject,
|
||||
uint32_t aArgCount,
|
||||
NPVariant* aResult)
|
||||
{
|
||||
if (aObject->_class != PluginScriptableObjectParent::GetClass()) {
|
||||
if (aObject->_class != GetClass()) {
|
||||
NS_ERROR("Don't know what kind of object this is!");
|
||||
return false;
|
||||
}
|
||||
|
||||
ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
|
||||
if (!object->parent) {
|
||||
if (object->invalidated) {
|
||||
NS_WARNING("Calling method on an invalidated object!");
|
||||
return false;
|
||||
}
|
||||
@ -379,27 +201,23 @@ PluginScriptableObjectParent::ScriptableInvoke(NPObject* aObject,
|
||||
return false;
|
||||
}
|
||||
|
||||
PluginScriptableObjectParent* actor = object->parent;
|
||||
NS_ASSERTION(actor, "This shouldn't ever be null!");
|
||||
|
||||
nsAutoTArray<Variant, 10> args;
|
||||
if (!args.SetLength(aArgCount)) {
|
||||
NS_ERROR("Out of memory?!");
|
||||
ProtectedActor<PluginScriptableObjectParent> actor(object->parent);
|
||||
if (!actor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (PRUint32 index = 0; index < aArgCount; index++) {
|
||||
Variant& arg = args[index];
|
||||
if (!ConvertToRemoteVariant(aArgs[index], arg, actor->GetInstance())) {
|
||||
NS_WARNING("Failed to convert argument!");
|
||||
return false;
|
||||
}
|
||||
NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
|
||||
|
||||
ProtectedVariantArray args(aArgs, aArgCount, actor->GetInstance());
|
||||
if (!args.IsOk()) {
|
||||
NS_ERROR("Failed to convert arguments!");
|
||||
return false;
|
||||
}
|
||||
|
||||
Variant remoteResult;
|
||||
bool success;
|
||||
if (!actor->CallInvoke((NPRemoteIdentifier)aName, args, &remoteResult,
|
||||
&success)) {
|
||||
&success)) {
|
||||
NS_WARNING("Failed to send message!");
|
||||
return false;
|
||||
}
|
||||
@ -422,32 +240,28 @@ PluginScriptableObjectParent::ScriptableInvokeDefault(NPObject* aObject,
|
||||
uint32_t aArgCount,
|
||||
NPVariant* aResult)
|
||||
{
|
||||
if (aObject->_class != PluginScriptableObjectParent::GetClass()) {
|
||||
if (aObject->_class != GetClass()) {
|
||||
NS_ERROR("Don't know what kind of object this is!");
|
||||
return false;
|
||||
}
|
||||
|
||||
ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
|
||||
if (!object->parent) {
|
||||
if (object->invalidated) {
|
||||
NS_WARNING("Calling method on an invalidated object!");
|
||||
return false;
|
||||
}
|
||||
|
||||
PluginScriptableObjectParent* actor = object->parent;
|
||||
NS_ASSERTION(actor, "This shouldn't ever be null!");
|
||||
|
||||
nsAutoTArray<Variant, 10> args;
|
||||
if (!args.SetLength(aArgCount)) {
|
||||
NS_ERROR("Out of memory?!");
|
||||
ProtectedActor<PluginScriptableObjectParent> actor(object->parent);
|
||||
if (!actor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (PRUint32 index = 0; index < aArgCount; index++) {
|
||||
Variant& arg = args[index];
|
||||
if (!ConvertToRemoteVariant(aArgs[index], arg, actor->GetInstance())) {
|
||||
NS_WARNING("Failed to convert argument!");
|
||||
return false;
|
||||
}
|
||||
NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
|
||||
|
||||
ProtectedVariantArray args(aArgs, aArgCount, actor->GetInstance());
|
||||
if (!args.IsOk()) {
|
||||
NS_ERROR("Failed to convert arguments!");
|
||||
return false;
|
||||
}
|
||||
|
||||
Variant remoteResult;
|
||||
@ -473,13 +287,13 @@ bool
|
||||
PluginScriptableObjectParent::ScriptableHasProperty(NPObject* aObject,
|
||||
NPIdentifier aName)
|
||||
{
|
||||
if (aObject->_class != PluginScriptableObjectParent::GetClass()) {
|
||||
if (aObject->_class != GetClass()) {
|
||||
NS_ERROR("Don't know what kind of object this is!");
|
||||
return false;
|
||||
}
|
||||
|
||||
ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
|
||||
if (!object->parent) {
|
||||
if (object->invalidated) {
|
||||
NS_WARNING("Calling method on an invalidated object!");
|
||||
return false;
|
||||
}
|
||||
@ -488,8 +302,12 @@ PluginScriptableObjectParent::ScriptableHasProperty(NPObject* aObject,
|
||||
return false;
|
||||
}
|
||||
|
||||
PluginScriptableObjectParent* actor = object->parent;
|
||||
NS_ASSERTION(actor, "This shouldn't ever be null!");
|
||||
ProtectedActor<PluginScriptableObjectParent> actor(object->parent);
|
||||
if (!actor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
|
||||
|
||||
bool result;
|
||||
if (!actor->CallHasProperty((NPRemoteIdentifier)aName, &result)) {
|
||||
@ -506,13 +324,13 @@ PluginScriptableObjectParent::ScriptableGetProperty(NPObject* aObject,
|
||||
NPIdentifier aName,
|
||||
NPVariant* aResult)
|
||||
{
|
||||
if (aObject->_class != PluginScriptableObjectParent::GetClass()) {
|
||||
if (aObject->_class != GetClass()) {
|
||||
NS_ERROR("Don't know what kind of object this is!");
|
||||
return false;
|
||||
}
|
||||
|
||||
ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
|
||||
if (!object->parent) {
|
||||
if (object->invalidated) {
|
||||
NS_WARNING("Calling method on an invalidated object!");
|
||||
return false;
|
||||
}
|
||||
@ -521,8 +339,12 @@ PluginScriptableObjectParent::ScriptableGetProperty(NPObject* aObject,
|
||||
return false;
|
||||
}
|
||||
|
||||
PluginScriptableObjectParent* actor = object->parent;
|
||||
NS_ASSERTION(actor, "This shouldn't ever be null!");
|
||||
ProtectedActor<PluginScriptableObjectParent> actor(object->parent);
|
||||
if (!actor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
|
||||
|
||||
Variant result;
|
||||
bool success;
|
||||
@ -549,13 +371,13 @@ PluginScriptableObjectParent::ScriptableSetProperty(NPObject* aObject,
|
||||
NPIdentifier aName,
|
||||
const NPVariant* aValue)
|
||||
{
|
||||
if (aObject->_class != PluginScriptableObjectParent::GetClass()) {
|
||||
if (aObject->_class != GetClass()) {
|
||||
NS_ERROR("Don't know what kind of object this is!");
|
||||
return false;
|
||||
}
|
||||
|
||||
ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
|
||||
if (!object->parent) {
|
||||
if (object->invalidated) {
|
||||
NS_WARNING("Calling method on an invalidated object!");
|
||||
return false;
|
||||
}
|
||||
@ -564,11 +386,15 @@ PluginScriptableObjectParent::ScriptableSetProperty(NPObject* aObject,
|
||||
return false;
|
||||
}
|
||||
|
||||
PluginScriptableObjectParent* actor = object->parent;
|
||||
NS_ASSERTION(actor, "This shouldn't ever be null!");
|
||||
ProtectedActor<PluginScriptableObjectParent> actor(object->parent);
|
||||
if (!actor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Variant value;
|
||||
if (!ConvertToRemoteVariant(*aValue, value, actor->GetInstance())) {
|
||||
NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
|
||||
|
||||
ProtectedVariant value(*aValue, actor->GetInstance());
|
||||
if (!value.IsOk()) {
|
||||
NS_WARNING("Failed to convert variant!");
|
||||
return false;
|
||||
}
|
||||
@ -587,13 +413,13 @@ bool
|
||||
PluginScriptableObjectParent::ScriptableRemoveProperty(NPObject* aObject,
|
||||
NPIdentifier aName)
|
||||
{
|
||||
if (aObject->_class != PluginScriptableObjectParent::GetClass()) {
|
||||
if (aObject->_class != GetClass()) {
|
||||
NS_ERROR("Don't know what kind of object this is!");
|
||||
return false;
|
||||
}
|
||||
|
||||
ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
|
||||
if (!object->parent) {
|
||||
if (object->invalidated) {
|
||||
NS_WARNING("Calling method on an invalidated object!");
|
||||
return false;
|
||||
}
|
||||
@ -602,8 +428,12 @@ PluginScriptableObjectParent::ScriptableRemoveProperty(NPObject* aObject,
|
||||
return false;
|
||||
}
|
||||
|
||||
PluginScriptableObjectParent* actor = object->parent;
|
||||
NS_ASSERTION(actor, "This shouldn't ever be null!");
|
||||
ProtectedActor<PluginScriptableObjectParent> actor(object->parent);
|
||||
if (!actor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
|
||||
|
||||
bool success;
|
||||
if (!actor->CallRemoveProperty((NPRemoteIdentifier)aName, &success)) {
|
||||
@ -620,19 +450,23 @@ PluginScriptableObjectParent::ScriptableEnumerate(NPObject* aObject,
|
||||
NPIdentifier** aIdentifiers,
|
||||
uint32_t* aCount)
|
||||
{
|
||||
if (aObject->_class != PluginScriptableObjectParent::GetClass()) {
|
||||
if (aObject->_class != GetClass()) {
|
||||
NS_ERROR("Don't know what kind of object this is!");
|
||||
return false;
|
||||
}
|
||||
|
||||
ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
|
||||
if (!object->parent) {
|
||||
if (object->invalidated) {
|
||||
NS_WARNING("Calling method on an invalidated object!");
|
||||
return false;
|
||||
}
|
||||
|
||||
PluginScriptableObjectParent* actor = object->parent;
|
||||
NS_ASSERTION(actor, "This shouldn't ever be null!");
|
||||
ProtectedActor<PluginScriptableObjectParent> actor(object->parent);
|
||||
if (!actor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
|
||||
|
||||
const NPNetscapeFuncs* npn = GetNetscapeFuncs(aObject);
|
||||
if (!npn) {
|
||||
@ -680,32 +514,28 @@ PluginScriptableObjectParent::ScriptableConstruct(NPObject* aObject,
|
||||
uint32_t aArgCount,
|
||||
NPVariant* aResult)
|
||||
{
|
||||
if (aObject->_class != PluginScriptableObjectParent::GetClass()) {
|
||||
if (aObject->_class != GetClass()) {
|
||||
NS_ERROR("Don't know what kind of object this is!");
|
||||
return false;
|
||||
}
|
||||
|
||||
ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
|
||||
if (!object->parent) {
|
||||
if (object->invalidated) {
|
||||
NS_WARNING("Calling method on an invalidated object!");
|
||||
return false;
|
||||
}
|
||||
|
||||
PluginScriptableObjectParent* actor = object->parent;
|
||||
NS_ASSERTION(actor, "This shouldn't ever be null!");
|
||||
|
||||
nsAutoTArray<Variant, 10> args;
|
||||
if (!args.SetLength(aArgCount)) {
|
||||
NS_ERROR("Out of memory?!");
|
||||
ProtectedActor<PluginScriptableObjectParent> actor(object->parent);
|
||||
if (!actor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (PRUint32 index = 0; index < aArgCount; index++) {
|
||||
Variant& arg = args[index];
|
||||
if (!ConvertToRemoteVariant(aArgs[index], arg, actor->GetInstance())) {
|
||||
NS_WARNING("Failed to convert argument!");
|
||||
return false;
|
||||
}
|
||||
NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
|
||||
|
||||
ProtectedVariantArray args(aArgs, aArgCount, actor->GetInstance());
|
||||
if (!args.IsOk()) {
|
||||
NS_ERROR("Failed to convert arguments!");
|
||||
return false;
|
||||
}
|
||||
|
||||
Variant remoteResult;
|
||||
@ -742,66 +572,169 @@ const NPClass PluginScriptableObjectParent::sNPClass = {
|
||||
PluginScriptableObjectParent::ScriptableConstruct
|
||||
};
|
||||
|
||||
PluginScriptableObjectParent::PluginScriptableObjectParent()
|
||||
PluginScriptableObjectParent::PluginScriptableObjectParent(
|
||||
ScriptableObjectType aType)
|
||||
: mInstance(nsnull),
|
||||
mObject(nsnull)
|
||||
mObject(nsnull),
|
||||
mProtectCount(0),
|
||||
mType(aType)
|
||||
{
|
||||
}
|
||||
|
||||
PluginScriptableObjectParent::~PluginScriptableObjectParent()
|
||||
{
|
||||
if (mObject) {
|
||||
if (GetClass() == mObject->_class) {
|
||||
static_cast<ParentNPObject*>(mObject)->parent = NULL;
|
||||
if (mObject->_class == GetClass()) {
|
||||
NS_ASSERTION(mType == Proxy, "Wrong type!");
|
||||
static_cast<ParentNPObject*>(mObject)->parent = nsnull;
|
||||
}
|
||||
else {
|
||||
mInstance->GetNPNIface()->releaseobject(mObject);
|
||||
NS_ASSERTION(mType == LocalObject, "Wrong type!");
|
||||
GetInstance()->GetNPNIface()->releaseobject(mObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PluginScriptableObjectParent::Initialize(PluginInstanceParent* aInstance,
|
||||
NPObject* aObject)
|
||||
PluginScriptableObjectParent::InitializeProxy()
|
||||
{
|
||||
NS_ASSERTION(aInstance && aObject, "Null pointers!");
|
||||
NS_ASSERTION(mType == Proxy, "Bad type!");
|
||||
NS_ASSERTION(!mObject, "Calling Initialize more than once!");
|
||||
|
||||
mInstance = static_cast<PluginInstanceParent*>(Manager());
|
||||
NS_ASSERTION(mInstance, "Null manager?!");
|
||||
|
||||
NPObject* object = CreateProxyObject();
|
||||
NS_ASSERTION(object, "Failed to create object!");
|
||||
|
||||
if (!mInstance->RegisterNPObjectForActor(object, this)) {
|
||||
NS_ERROR("Out of memory?");
|
||||
}
|
||||
|
||||
mObject = object;
|
||||
}
|
||||
|
||||
void
|
||||
PluginScriptableObjectParent::InitializeLocal(NPObject* aObject)
|
||||
{
|
||||
NS_ASSERTION(mType == LocalObject, "Bad type!");
|
||||
NS_ASSERTION(!(mInstance && mObject), "Calling Initialize more than once!");
|
||||
|
||||
if (aObject->_class == GetClass()) {
|
||||
ParentNPObject* object = static_cast<ParentNPObject*>(aObject);
|
||||
mInstance = static_cast<PluginInstanceParent*>(Manager());
|
||||
NS_ASSERTION(mInstance, "Null manager?!");
|
||||
|
||||
NS_ASSERTION(!object->parent, "Bad object!");
|
||||
object->parent = const_cast<PluginScriptableObjectParent*>(this);
|
||||
mInstance->GetNPNIface()->retainobject(aObject);
|
||||
|
||||
// We don't want to have the actor own this object but rather let the object
|
||||
// own this actor. Set the reference count to 0 here so that when the object
|
||||
// dies we will send the destructor message to the child.
|
||||
NS_ASSERTION(aObject->referenceCount == 1, "Some kind of live object!");
|
||||
object->referenceCount = 0;
|
||||
NS_LOG_RELEASE(aObject, 0, "BrowserNPObject");
|
||||
}
|
||||
else {
|
||||
aInstance->GetNPNIface()->retainobject(aObject);
|
||||
NS_ASSERTION(!mProtectCount, "Should be zero!");
|
||||
mProtectCount++;
|
||||
|
||||
if (!mInstance->RegisterNPObjectForActor(aObject, this)) {
|
||||
NS_ERROR("Out of memory?");
|
||||
}
|
||||
|
||||
mInstance = aInstance;
|
||||
mObject = aObject;
|
||||
}
|
||||
|
||||
bool
|
||||
PluginScriptableObjectParent::AnswerInvalidate()
|
||||
NPObject*
|
||||
PluginScriptableObjectParent::CreateProxyObject()
|
||||
{
|
||||
if (mObject) {
|
||||
NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
|
||||
const NPNetscapeFuncs* npn = GetNetscapeFuncs(GetInstance());
|
||||
if (npn) {
|
||||
npn->releaseobject(mObject);
|
||||
}
|
||||
mObject = nsnull;
|
||||
NS_ASSERTION(mInstance, "Must have an instance!");
|
||||
NS_ASSERTION(mType == Proxy, "Shouldn't call this for non-proxy object!");
|
||||
|
||||
const NPNetscapeFuncs* npn = GetNetscapeFuncs(mInstance);
|
||||
|
||||
NPObject* npobject = npn->createobject(mInstance->GetNPP(),
|
||||
const_cast<NPClass*>(GetClass()));
|
||||
NS_ASSERTION(npobject, "Failed to create object?!");
|
||||
NS_ASSERTION(npobject->_class == GetClass(), "Wrong kind of object!");
|
||||
NS_ASSERTION(npobject->referenceCount == 1, "Some kind of live object!");
|
||||
|
||||
ParentNPObject* object = static_cast<ParentNPObject*>(npobject);
|
||||
NS_ASSERTION(!object->invalidated, "Bad object!");
|
||||
NS_ASSERTION(!object->parent, "Bad object!");
|
||||
|
||||
// We don't want to have the actor own this object but rather let the object
|
||||
// own this actor. Set the reference count to 0 here so that when the object
|
||||
// dies we will send the destructor message to the child.
|
||||
object->referenceCount = 0;
|
||||
NS_LOG_RELEASE(object, 0, "BrowserNPObject");
|
||||
|
||||
object->parent = const_cast<PluginScriptableObjectParent*>(this);
|
||||
return object;
|
||||
}
|
||||
|
||||
bool
|
||||
PluginScriptableObjectParent::ResurrectProxyObject()
|
||||
{
|
||||
NS_ASSERTION(mInstance, "Must have an instance already!");
|
||||
NS_ASSERTION(!mObject, "Should not have an object already!");
|
||||
NS_ASSERTION(mType == Proxy, "Shouldn't call this for non-proxy object!");
|
||||
|
||||
InitializeProxy();
|
||||
NS_ASSERTION(mObject, "Initialize failed!");
|
||||
|
||||
if (!CallProtect()) {
|
||||
NS_WARNING("Failed to send message!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
NPObject*
|
||||
PluginScriptableObjectParent::GetObject(bool aCanResurrect)
|
||||
{
|
||||
if (!mObject && aCanResurrect && !ResurrectProxyObject()) {
|
||||
NS_ERROR("Null object!");
|
||||
return nsnull;
|
||||
}
|
||||
return mObject;
|
||||
}
|
||||
|
||||
void
|
||||
PluginScriptableObjectParent::Protect()
|
||||
{
|
||||
NS_ASSERTION(mObject, "No object!");
|
||||
NS_ASSERTION(mProtectCount >= 0, "Negative protect count?!");
|
||||
|
||||
if (mType == LocalObject) {
|
||||
++mProtectCount;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PluginScriptableObjectParent::Unprotect()
|
||||
{
|
||||
NS_ASSERTION(mObject, "No object!");
|
||||
NS_ASSERTION(mProtectCount >= 0, "Negative protect count?!");
|
||||
|
||||
if (mType == LocalObject) {
|
||||
if (--mProtectCount == 0) {
|
||||
PluginScriptableObjectParent::Call__delete__(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PluginScriptableObjectParent::DropNPObject()
|
||||
{
|
||||
NS_ASSERTION(mObject, "Invalidated object!");
|
||||
NS_ASSERTION(mObject->_class == GetClass(), "Wrong type of object!");
|
||||
NS_ASSERTION(mType == Proxy, "Shouldn't call this for non-proxy object!");
|
||||
|
||||
// We think we're about to be deleted, but we could be racing with the other
|
||||
// process.
|
||||
PluginInstanceParent* instance = GetInstance();
|
||||
NS_ASSERTION(instance, "Must have an instance!");
|
||||
|
||||
instance->UnregisterNPObject(mObject);
|
||||
mObject = nsnull;
|
||||
|
||||
if (!CallUnprotect()) {
|
||||
NS_WARNING("Failed to send message!");
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
PluginScriptableObjectParent::AnswerHasMethod(const NPRemoteIdentifier& aId,
|
||||
bool* aHasMethod)
|
||||
@ -813,6 +746,7 @@ PluginScriptableObjectParent::AnswerHasMethod(const NPRemoteIdentifier& aId,
|
||||
}
|
||||
|
||||
NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
|
||||
NS_ASSERTION(mType == LocalObject, "Bad type!");
|
||||
|
||||
PluginInstanceParent* instance = GetInstance();
|
||||
if (!instance) {
|
||||
@ -852,6 +786,7 @@ PluginScriptableObjectParent::AnswerInvoke(const NPRemoteIdentifier& aId,
|
||||
}
|
||||
|
||||
NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
|
||||
NS_ASSERTION(mType == LocalObject, "Bad type!");
|
||||
|
||||
PluginInstanceParent* instance = GetInstance();
|
||||
if (!instance) {
|
||||
@ -914,7 +849,7 @@ PluginScriptableObjectParent::AnswerInvoke(const NPRemoteIdentifier& aId,
|
||||
Variant convertedResult;
|
||||
success = ConvertToRemoteVariant(result, convertedResult, GetInstance());
|
||||
|
||||
ReleaseVariant(result, instance);
|
||||
DeferNPVariantLastRelease(npn, &result);
|
||||
|
||||
if (!success) {
|
||||
*aResult = void_t();
|
||||
@ -940,6 +875,7 @@ PluginScriptableObjectParent::AnswerInvokeDefault(const nsTArray<Variant>& aArgs
|
||||
}
|
||||
|
||||
NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
|
||||
NS_ASSERTION(mType == LocalObject, "Bad type!");
|
||||
|
||||
PluginInstanceParent* instance = GetInstance();
|
||||
if (!instance) {
|
||||
@ -996,7 +932,7 @@ PluginScriptableObjectParent::AnswerInvokeDefault(const nsTArray<Variant>& aArgs
|
||||
Variant convertedResult;
|
||||
success = ConvertToRemoteVariant(result, convertedResult, GetInstance());
|
||||
|
||||
ReleaseVariant(result, instance);
|
||||
DeferNPVariantLastRelease(npn, &result);
|
||||
|
||||
if (!success) {
|
||||
*aResult = void_t();
|
||||
@ -1020,6 +956,7 @@ PluginScriptableObjectParent::AnswerHasProperty(const NPRemoteIdentifier& aId,
|
||||
}
|
||||
|
||||
NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
|
||||
NS_ASSERTION(mType == LocalObject, "Bad type!");
|
||||
|
||||
PluginInstanceParent* instance = GetInstance();
|
||||
if (!instance) {
|
||||
@ -1059,6 +996,7 @@ PluginScriptableObjectParent::AnswerGetProperty(const NPRemoteIdentifier& aId,
|
||||
}
|
||||
|
||||
NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
|
||||
NS_ASSERTION(mType == LocalObject, "Bad type!");
|
||||
|
||||
PluginInstanceParent* instance = GetInstance();
|
||||
if (!instance) {
|
||||
@ -1093,7 +1031,7 @@ PluginScriptableObjectParent::AnswerGetProperty(const NPRemoteIdentifier& aId,
|
||||
|
||||
Variant converted;
|
||||
if ((*aSuccess = ConvertToRemoteVariant(result, converted, instance))) {
|
||||
ReleaseVariant(result, instance);
|
||||
DeferNPVariantLastRelease(npn, &result);
|
||||
*aResult = converted;
|
||||
}
|
||||
else {
|
||||
@ -1115,6 +1053,7 @@ PluginScriptableObjectParent::AnswerSetProperty(const NPRemoteIdentifier& aId,
|
||||
}
|
||||
|
||||
NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
|
||||
NS_ASSERTION(mType == LocalObject, "Bad type!");
|
||||
|
||||
PluginInstanceParent* instance = GetInstance();
|
||||
if (!instance) {
|
||||
@ -1160,6 +1099,7 @@ PluginScriptableObjectParent::AnswerRemoveProperty(const NPRemoteIdentifier& aId
|
||||
}
|
||||
|
||||
NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
|
||||
NS_ASSERTION(mType == LocalObject, "Bad type!");
|
||||
|
||||
PluginInstanceParent* instance = GetInstance();
|
||||
if (!instance) {
|
||||
@ -1197,6 +1137,7 @@ PluginScriptableObjectParent::AnswerEnumerate(nsTArray<NPRemoteIdentifier>* aPro
|
||||
}
|
||||
|
||||
NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
|
||||
NS_ASSERTION(mType == LocalObject, "Bad type!");
|
||||
|
||||
PluginInstanceParent* instance = GetInstance();
|
||||
if (!instance) {
|
||||
@ -1253,6 +1194,7 @@ PluginScriptableObjectParent::AnswerConstruct(const nsTArray<Variant>& aArgs,
|
||||
}
|
||||
|
||||
NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
|
||||
NS_ASSERTION(mType == LocalObject, "Bad type!");
|
||||
|
||||
PluginInstanceParent* instance = GetInstance();
|
||||
if (!instance) {
|
||||
@ -1308,7 +1250,7 @@ PluginScriptableObjectParent::AnswerConstruct(const nsTArray<Variant>& aArgs,
|
||||
Variant convertedResult;
|
||||
success = ConvertToRemoteVariant(result, convertedResult, instance);
|
||||
|
||||
ReleaseVariant(result, instance);
|
||||
DeferNPVariantLastRelease(npn, &result);
|
||||
|
||||
if (!success) {
|
||||
*aResult = void_t();
|
||||
@ -1321,6 +1263,26 @@ PluginScriptableObjectParent::AnswerConstruct(const nsTArray<Variant>& aArgs,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
PluginScriptableObjectParent::AnswerProtect()
|
||||
{
|
||||
NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
|
||||
NS_ASSERTION(mType == LocalObject, "Bad type!");
|
||||
|
||||
Protect();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
PluginScriptableObjectParent::AnswerUnprotect()
|
||||
{
|
||||
NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
|
||||
NS_ASSERTION(mType == LocalObject, "Bad type!");
|
||||
|
||||
Unprotect();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
PluginScriptableObjectParent::AnswerNPN_Evaluate(const nsCString& aScript,
|
||||
Variant* aResult,
|
||||
@ -1355,7 +1317,7 @@ PluginScriptableObjectParent::AnswerNPN_Evaluate(const nsCString& aScript,
|
||||
Variant convertedResult;
|
||||
success = ConvertToRemoteVariant(result, convertedResult, instance);
|
||||
|
||||
ReleaseVariant(result, instance);
|
||||
DeferNPVariantLastRelease(npn, &result);
|
||||
|
||||
if (!success) {
|
||||
*aResult = void_t();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=4 ts=4 et :
|
||||
* vim: sw=2 ts=2 et :
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
@ -53,9 +53,12 @@ class PluginScriptableObjectParent;
|
||||
struct ParentNPObject : NPObject
|
||||
{
|
||||
ParentNPObject()
|
||||
: parent(NULL) { }
|
||||
: NPObject(), parent(NULL), invalidated(false) { }
|
||||
|
||||
// |parent| is always valid as long as the actor is alive. Once the actor is
|
||||
// destroyed this will be set to null.
|
||||
PluginScriptableObjectParent* parent;
|
||||
bool invalidated;
|
||||
};
|
||||
|
||||
class PluginScriptableObjectParent : public PPluginScriptableObjectParent
|
||||
@ -63,11 +66,14 @@ class PluginScriptableObjectParent : public PPluginScriptableObjectParent
|
||||
friend class PluginInstanceParent;
|
||||
|
||||
public:
|
||||
PluginScriptableObjectParent();
|
||||
PluginScriptableObjectParent(ScriptableObjectType aType);
|
||||
virtual ~PluginScriptableObjectParent();
|
||||
|
||||
virtual bool
|
||||
AnswerInvalidate();
|
||||
void
|
||||
InitializeProxy();
|
||||
|
||||
void
|
||||
InitializeLocal(NPObject* aObject);
|
||||
|
||||
virtual bool
|
||||
AnswerHasMethod(const NPRemoteIdentifier& aId,
|
||||
@ -116,9 +122,11 @@ public:
|
||||
Variant* aResult,
|
||||
bool* aSuccess);
|
||||
|
||||
void
|
||||
Initialize(PluginInstanceParent* aInstance,
|
||||
NPObject* aObject);
|
||||
virtual bool
|
||||
AnswerProtect();
|
||||
|
||||
virtual bool
|
||||
AnswerUnprotect();
|
||||
|
||||
static const NPClass*
|
||||
GetClass()
|
||||
@ -127,15 +135,36 @@ public:
|
||||
}
|
||||
|
||||
PluginInstanceParent*
|
||||
GetInstance()
|
||||
GetInstance() const
|
||||
{
|
||||
return mInstance;
|
||||
}
|
||||
|
||||
NPObject*
|
||||
GetObject()
|
||||
{
|
||||
return mObject;
|
||||
GetObject(bool aCanResurrect);
|
||||
|
||||
// Protect only affects LocalObject actors. It is called by the
|
||||
// ProtectedVariant/Actor helper classes before the actor is used as an
|
||||
// argument to an IPC call and when the child process resurrects a
|
||||
// proxy object to the NPObject associated with this actor.
|
||||
void Protect();
|
||||
|
||||
// Unprotect only affects LocalObject actors. It is called by the
|
||||
// ProtectedVariant/Actor helper classes after the actor is used as an
|
||||
// argument to an IPC call and when the child process is no longer using this
|
||||
// actor.
|
||||
void Unprotect();
|
||||
|
||||
// DropNPObject is only used for Proxy actors and is called when the parent
|
||||
// process is no longer using the NPObject associated with this actor. The
|
||||
// child process may subsequently use this actor again in which case a new
|
||||
// NPObject will be created and associated with this actor (see
|
||||
// ResurrectProxyObject).
|
||||
void DropNPObject();
|
||||
|
||||
ScriptableObjectType
|
||||
Type() const {
|
||||
return mType;
|
||||
}
|
||||
|
||||
private:
|
||||
@ -195,12 +224,23 @@ private:
|
||||
uint32_t aArgCount,
|
||||
NPVariant* aResult);
|
||||
|
||||
NPObject*
|
||||
CreateProxyObject();
|
||||
|
||||
// ResurrectProxyObject is only used with Proxy actors. It is called when the
|
||||
// child process uses an actor whose NPObject was deleted by the parent
|
||||
// process.
|
||||
bool ResurrectProxyObject();
|
||||
|
||||
private:
|
||||
PluginInstanceParent* mInstance;
|
||||
|
||||
// This may be a ParentNPObject or some other kind depending on who created
|
||||
// it. Have to check its class to find out.
|
||||
NPObject* mObject;
|
||||
int mProtectCount;
|
||||
|
||||
ScriptableObjectType mType;
|
||||
|
||||
static const NPClass sNPClass;
|
||||
};
|
||||
|
217
dom/plugins/PluginScriptableObjectUtils.cpp
Normal file
217
dom/plugins/PluginScriptableObjectUtils.cpp
Normal file
@ -0,0 +1,217 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=2 et :
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Plugin App.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* The Mozilla Foundation
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Ben Turner <bent.mozilla@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "PluginScriptableObjectUtils.h"
|
||||
|
||||
using namespace mozilla::plugins;
|
||||
|
||||
namespace {
|
||||
|
||||
template<class InstanceType>
|
||||
class VariantTraits;
|
||||
|
||||
template<>
|
||||
class VariantTraits<PluginInstanceParent>
|
||||
{
|
||||
public:
|
||||
typedef PluginScriptableObjectParent ScriptableObjectType;
|
||||
};
|
||||
|
||||
template<>
|
||||
class VariantTraits<PluginInstanceChild>
|
||||
{
|
||||
public:
|
||||
typedef PluginScriptableObjectChild ScriptableObjectType;
|
||||
};
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
bool
|
||||
mozilla::plugins::ConvertToVariant(const Variant& aRemoteVariant,
|
||||
NPVariant& aVariant,
|
||||
PluginInstanceParent* aInstance)
|
||||
{
|
||||
switch (aRemoteVariant.type()) {
|
||||
case Variant::Tvoid_t: {
|
||||
VOID_TO_NPVARIANT(aVariant);
|
||||
break;
|
||||
}
|
||||
|
||||
case Variant::Tnull_t: {
|
||||
NULL_TO_NPVARIANT(aVariant);
|
||||
break;
|
||||
}
|
||||
|
||||
case Variant::Tbool: {
|
||||
BOOLEAN_TO_NPVARIANT(aRemoteVariant.get_bool(), aVariant);
|
||||
break;
|
||||
}
|
||||
|
||||
case Variant::Tint: {
|
||||
INT32_TO_NPVARIANT(aRemoteVariant.get_int(), aVariant);
|
||||
break;
|
||||
}
|
||||
|
||||
case Variant::Tdouble: {
|
||||
DOUBLE_TO_NPVARIANT(aRemoteVariant.get_double(), aVariant);
|
||||
break;
|
||||
}
|
||||
|
||||
case Variant::TnsCString: {
|
||||
const nsCString& string = aRemoteVariant.get_nsCString();
|
||||
NPUTF8* buffer = reinterpret_cast<NPUTF8*>(strdup(string.get()));
|
||||
if (!buffer) {
|
||||
NS_ERROR("Out of memory!");
|
||||
return false;
|
||||
}
|
||||
STRINGN_TO_NPVARIANT(buffer, string.Length(), aVariant);
|
||||
break;
|
||||
}
|
||||
|
||||
case Variant::TPPluginScriptableObjectParent: {
|
||||
NS_ASSERTION(aInstance, "Must have an instance!");
|
||||
NPObject* object = NPObjectFromVariant(aRemoteVariant);
|
||||
if (!object) {
|
||||
NS_ERROR("Er, this shouldn't fail!");
|
||||
return false;
|
||||
}
|
||||
|
||||
const NPNetscapeFuncs* npn = GetNetscapeFuncs(aInstance);
|
||||
if (!npn) {
|
||||
NS_ERROR("Null netscape funcs!");
|
||||
return false;
|
||||
}
|
||||
|
||||
npn->retainobject(object);
|
||||
OBJECT_TO_NPVARIANT(object, aVariant);
|
||||
break;
|
||||
}
|
||||
|
||||
case Variant::TPPluginScriptableObjectChild: {
|
||||
NS_ASSERTION(!aInstance, "No instance should be given!");
|
||||
NS_ASSERTION(PluginModuleChild::current(),
|
||||
"Should be running on child only!");
|
||||
|
||||
NPObject* object = NPObjectFromVariant(aRemoteVariant);
|
||||
NS_ASSERTION(object, "Null object?!");
|
||||
|
||||
PluginModuleChild::sBrowserFuncs.retainobject(object);
|
||||
OBJECT_TO_NPVARIANT(object, aVariant);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
NS_NOTREACHED("Shouldn't get here!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class InstanceType>
|
||||
bool
|
||||
mozilla::plugins::ConvertToRemoteVariant(const NPVariant& aVariant,
|
||||
Variant& aRemoteVariant,
|
||||
InstanceType* aInstance,
|
||||
bool aProtectActors)
|
||||
{
|
||||
if (NPVARIANT_IS_VOID(aVariant)) {
|
||||
aRemoteVariant = mozilla::void_t();
|
||||
}
|
||||
else if (NPVARIANT_IS_NULL(aVariant)) {
|
||||
aRemoteVariant = mozilla::null_t();
|
||||
}
|
||||
else if (NPVARIANT_IS_BOOLEAN(aVariant)) {
|
||||
aRemoteVariant = NPVARIANT_TO_BOOLEAN(aVariant);
|
||||
}
|
||||
else if (NPVARIANT_IS_INT32(aVariant)) {
|
||||
aRemoteVariant = NPVARIANT_TO_INT32(aVariant);
|
||||
}
|
||||
else if (NPVARIANT_IS_DOUBLE(aVariant)) {
|
||||
aRemoteVariant = NPVARIANT_TO_DOUBLE(aVariant);
|
||||
}
|
||||
else if (NPVARIANT_IS_STRING(aVariant)) {
|
||||
NPString str = NPVARIANT_TO_STRING(aVariant);
|
||||
nsCString string(str.UTF8Characters, str.UTF8Length);
|
||||
aRemoteVariant = string;
|
||||
}
|
||||
else if (NPVARIANT_IS_OBJECT(aVariant)) {
|
||||
NPObject* object = NPVARIANT_TO_OBJECT(aVariant);
|
||||
|
||||
typename VariantTraits<InstanceType>::ScriptableObjectType* actor =
|
||||
aInstance->GetActorForNPObject(object);
|
||||
|
||||
if (!actor) {
|
||||
NS_ERROR("Null actor!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aProtectActors) {
|
||||
actor->Protect();
|
||||
}
|
||||
|
||||
aRemoteVariant = actor;
|
||||
}
|
||||
else {
|
||||
NS_NOTREACHED("Shouldn't get here!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
// This function only exists to get both flavors of the ConvertToRemoteVariant
|
||||
// function instantiated and should never be called.
|
||||
|
||||
void
|
||||
XXXNeverCalled()
|
||||
{
|
||||
NS_NOTREACHED("This should never be called!");
|
||||
PluginInstanceParent* parent = nsnull;
|
||||
PluginInstanceChild* child = nsnull;
|
||||
NPVariant variant;
|
||||
VOID_TO_NPVARIANT(variant);
|
||||
Variant remoteVariant;
|
||||
ConvertToRemoteVariant(variant, remoteVariant, parent, false);
|
||||
ConvertToRemoteVariant(variant, remoteVariant, child, false);
|
||||
}
|
||||
|
||||
} /* anonymous namespace */
|
317
dom/plugins/PluginScriptableObjectUtils.h
Normal file
317
dom/plugins/PluginScriptableObjectUtils.h
Normal file
@ -0,0 +1,317 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=2 et :
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Plugin App.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* The Mozilla Foundation
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Ben Turner <bent.mozilla@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef dom_plugins_PluginScriptableObjectUtils_h
|
||||
#define dom_plugins_PluginScriptableObjectUtils_h
|
||||
|
||||
#include "PluginModuleParent.h"
|
||||
#include "PluginModuleChild.h"
|
||||
#include "PluginInstanceParent.h"
|
||||
#include "PluginInstanceChild.h"
|
||||
#include "PluginScriptableObjectParent.h"
|
||||
#include "PluginScriptableObjectChild.h"
|
||||
|
||||
#include "npapi.h"
|
||||
#include "npfunctions.h"
|
||||
#include "npruntime.h"
|
||||
|
||||
#include "nsDebug.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace plugins {
|
||||
|
||||
inline PluginInstanceParent*
|
||||
GetInstance(NPObject* aObject)
|
||||
{
|
||||
NS_ASSERTION(aObject->_class == PluginScriptableObjectParent::GetClass(),
|
||||
"Bad class!");
|
||||
|
||||
ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
|
||||
if (object->invalidated) {
|
||||
NS_WARNING("Calling method on an invalidated object!");
|
||||
return nsnull;
|
||||
}
|
||||
if (!object->parent) {
|
||||
return nsnull;
|
||||
}
|
||||
return object->parent->GetInstance();
|
||||
}
|
||||
|
||||
inline NPObject*
|
||||
NPObjectFromVariant(const Variant& aRemoteVariant)
|
||||
{
|
||||
switch (aRemoteVariant.type()) {
|
||||
case Variant::TPPluginScriptableObjectParent: {
|
||||
PluginScriptableObjectParent* actor =
|
||||
const_cast<PluginScriptableObjectParent*>(
|
||||
reinterpret_cast<const PluginScriptableObjectParent*>(
|
||||
aRemoteVariant.get_PPluginScriptableObjectParent()));
|
||||
return actor->GetObject(true);
|
||||
}
|
||||
|
||||
case Variant::TPPluginScriptableObjectChild: {
|
||||
PluginScriptableObjectChild* actor =
|
||||
const_cast<PluginScriptableObjectChild*>(
|
||||
reinterpret_cast<const PluginScriptableObjectChild*>(
|
||||
aRemoteVariant.get_PPluginScriptableObjectChild()));
|
||||
return actor->GetObject(true);
|
||||
}
|
||||
|
||||
default:
|
||||
NS_NOTREACHED("Shouldn't get here!");
|
||||
return nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
inline NPObject*
|
||||
NPObjectFromVariant(const NPVariant& aVariant)
|
||||
{
|
||||
NS_ASSERTION(NPVARIANT_IS_OBJECT(aVariant), "Wrong variant type!");
|
||||
return NPVARIANT_TO_OBJECT(aVariant);
|
||||
}
|
||||
|
||||
inline const NPNetscapeFuncs*
|
||||
GetNetscapeFuncs(PluginInstanceParent* aInstance)
|
||||
{
|
||||
PluginModuleParent* module = aInstance->Module();
|
||||
if (!module) {
|
||||
NS_WARNING("Null module?!");
|
||||
return nsnull;
|
||||
}
|
||||
return module->GetNetscapeFuncs();
|
||||
}
|
||||
|
||||
inline const NPNetscapeFuncs*
|
||||
GetNetscapeFuncs(NPObject* aObject)
|
||||
{
|
||||
NS_ASSERTION(aObject->_class == PluginScriptableObjectParent::GetClass(),
|
||||
"Bad class!");
|
||||
|
||||
PluginInstanceParent* instance = GetInstance(aObject);
|
||||
if (!instance) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
return GetNetscapeFuncs(instance);
|
||||
}
|
||||
|
||||
inline void
|
||||
ReleaseRemoteVariant(Variant& aVariant)
|
||||
{
|
||||
switch (aVariant.type()) {
|
||||
case Variant::TPPluginScriptableObjectParent: {
|
||||
PluginScriptableObjectParent* actor =
|
||||
const_cast<PluginScriptableObjectParent*>(
|
||||
reinterpret_cast<const PluginScriptableObjectParent*>(
|
||||
aVariant.get_PPluginScriptableObjectParent()));
|
||||
actor->Unprotect();
|
||||
break;
|
||||
}
|
||||
|
||||
case Variant::TPPluginScriptableObjectChild: {
|
||||
NS_ASSERTION(PluginModuleChild::current(),
|
||||
"Should only be running in the child!");
|
||||
PluginScriptableObjectChild* actor =
|
||||
const_cast<PluginScriptableObjectChild*>(
|
||||
reinterpret_cast<const PluginScriptableObjectChild*>(
|
||||
aVariant.get_PPluginScriptableObjectChild()));
|
||||
actor->Unprotect();
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break; // Intentional fall-through for other variant types.
|
||||
}
|
||||
|
||||
aVariant = mozilla::void_t();
|
||||
}
|
||||
|
||||
bool
|
||||
ConvertToVariant(const Variant& aRemoteVariant,
|
||||
NPVariant& aVariant,
|
||||
PluginInstanceParent* aInstance = nsnull);
|
||||
|
||||
template <class InstanceType>
|
||||
bool
|
||||
ConvertToRemoteVariant(const NPVariant& aVariant,
|
||||
Variant& aRemoteVariant,
|
||||
InstanceType* aInstance,
|
||||
bool aProtectActors = false);
|
||||
|
||||
class ProtectedVariant
|
||||
{
|
||||
public:
|
||||
ProtectedVariant(const NPVariant& aVariant,
|
||||
PluginInstanceParent* aInstance)
|
||||
{
|
||||
mOk = ConvertToRemoteVariant(aVariant, mVariant, aInstance, true);
|
||||
}
|
||||
|
||||
ProtectedVariant(const NPVariant& aVariant,
|
||||
PluginInstanceChild* aInstance)
|
||||
{
|
||||
mOk = ConvertToRemoteVariant(aVariant, mVariant, aInstance, true);
|
||||
}
|
||||
|
||||
~ProtectedVariant() {
|
||||
ReleaseRemoteVariant(mVariant);
|
||||
}
|
||||
|
||||
PRBool IsOk() {
|
||||
return mOk;
|
||||
}
|
||||
|
||||
operator const Variant&() {
|
||||
return mVariant;
|
||||
}
|
||||
|
||||
private:
|
||||
Variant mVariant;
|
||||
bool mOk;
|
||||
};
|
||||
|
||||
class ProtectedVariantArray
|
||||
{
|
||||
public:
|
||||
ProtectedVariantArray(const NPVariant* aArgs,
|
||||
PRUint32 aCount,
|
||||
PluginInstanceParent* aInstance)
|
||||
{
|
||||
for (PRUint32 index = 0; index < aCount; index++) {
|
||||
Variant* remoteVariant = mArray.AppendElement();
|
||||
if (!(remoteVariant &&
|
||||
ConvertToRemoteVariant(aArgs[index], *remoteVariant, aInstance,
|
||||
true))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
mOk = mArray.Length() == aCount;
|
||||
}
|
||||
|
||||
ProtectedVariantArray(const NPVariant* aArgs,
|
||||
PRUint32 aCount,
|
||||
PluginInstanceChild* aInstance)
|
||||
{
|
||||
for (PRUint32 index = 0; index < aCount; index++) {
|
||||
Variant* remoteVariant = mArray.AppendElement();
|
||||
if (!(remoteVariant &&
|
||||
ConvertToRemoteVariant(aArgs[index], *remoteVariant, aInstance,
|
||||
true))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
mOk = mArray.Length() == aCount;
|
||||
}
|
||||
~ProtectedVariantArray()
|
||||
{
|
||||
PRUint32 count = mArray.Length();
|
||||
for (PRUint32 index = 0; index < count; index++) {
|
||||
ReleaseRemoteVariant(mArray[index]);
|
||||
}
|
||||
}
|
||||
|
||||
operator const nsTArray<Variant>&()
|
||||
{
|
||||
return mArray;
|
||||
}
|
||||
|
||||
bool IsOk()
|
||||
{
|
||||
return mOk;
|
||||
}
|
||||
|
||||
private:
|
||||
nsTArray<Variant> mArray;
|
||||
bool mOk;
|
||||
};
|
||||
|
||||
template<class ActorType>
|
||||
struct ProtectedActorTraits
|
||||
{
|
||||
static bool Nullable();
|
||||
};
|
||||
|
||||
template<class ActorType, class Traits=ProtectedActorTraits<ActorType> >
|
||||
class ProtectedActor
|
||||
{
|
||||
public:
|
||||
ProtectedActor(ActorType* aActor) : mActor(aActor)
|
||||
{
|
||||
if (!Traits::Nullable()) {
|
||||
NS_ASSERTION(mActor, "This should never be null!");
|
||||
}
|
||||
}
|
||||
|
||||
~ProtectedActor()
|
||||
{
|
||||
if (Traits::Nullable() && !mActor)
|
||||
return;
|
||||
mActor->Unprotect();
|
||||
}
|
||||
|
||||
ActorType* operator->()
|
||||
{
|
||||
return mActor;
|
||||
}
|
||||
|
||||
operator bool()
|
||||
{
|
||||
return !!mActor;
|
||||
}
|
||||
|
||||
private:
|
||||
ActorType* mActor;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ProtectedActorTraits<PluginScriptableObjectParent>
|
||||
{
|
||||
static bool Nullable() { return true; }
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ProtectedActorTraits<PluginScriptableObjectChild>
|
||||
{
|
||||
static bool Nullable() { return false; }
|
||||
};
|
||||
|
||||
} /* namespace plugins */
|
||||
} /* namespace mozilla */
|
||||
|
||||
#endif /* dom_plugins_PluginScriptableObjectUtils_h */
|
@ -333,13 +333,13 @@ OOPPluginsEnabled()
|
||||
}
|
||||
|
||||
#ifdef XP_WIN
|
||||
OSVERSIONINFO osVerInfo = {0};
|
||||
osVerInfo.dwOSVersionInfoSize = sizeof(osVerInfo);
|
||||
GetVersionEx(&osVerInfo);
|
||||
// Always disabled on 2K or less. (bug 536303)
|
||||
if (osVerInfo.dwMajorVersion < 5 ||
|
||||
(osVerInfo.dwMajorVersion == 5 && osVerInfo.dwMinorVersion == 0))
|
||||
return PR_FALSE;
|
||||
OSVERSIONINFO osVerInfo = {0};
|
||||
osVerInfo.dwOSVersionInfoSize = sizeof(osVerInfo);
|
||||
GetVersionEx(&osVerInfo);
|
||||
// Always disabled on 2K or less. (bug 536303)
|
||||
if (osVerInfo.dwMajorVersion < 5 ||
|
||||
(osVerInfo.dwMajorVersion == 5 && osVerInfo.dwMinorVersion == 0))
|
||||
return PR_FALSE;
|
||||
#endif
|
||||
|
||||
return PR_TRUE;
|
||||
|
Loading…
x
Reference in New Issue
Block a user