зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1081353 - Eliminate PPluginIdentifier (r=bsmedberg)
This commit is contained in:
Родитель
273f76d366
Коммит
1809fa7212
|
@ -126,7 +126,7 @@ IntToNPIdentifier(int i)
|
|||
JSContext* GetJSContext(NPP npp);
|
||||
|
||||
inline bool
|
||||
NPStringIdentifierIsPermanent(NPP npp, NPIdentifier id)
|
||||
NPStringIdentifierIsPermanent(NPIdentifier id)
|
||||
{
|
||||
AutoSafeJSContext cx;
|
||||
return JS_StringHasBeenInterned(cx, NPIdentifierToString(id));
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
include protocol PPluginModule;
|
||||
|
||||
namespace mozilla {
|
||||
namespace plugins {
|
||||
|
||||
/**
|
||||
* Represents an NPIdentifier that wraps either a string or an integer.
|
||||
*/
|
||||
async protocol PPluginIdentifier
|
||||
{
|
||||
manager PPluginModule;
|
||||
|
||||
parent:
|
||||
/**
|
||||
* If this is a temporary identifier, inform the parent that the plugin
|
||||
* has made the identifier permanent by calling NPN_GetStringIdentifier.
|
||||
*/
|
||||
async Retain();
|
||||
|
||||
child:
|
||||
async __delete__();
|
||||
};
|
||||
|
||||
} // namespace plugins
|
||||
} // namespace mozilla
|
|
@ -3,12 +3,10 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
include protocol PPluginIdentifier;
|
||||
include protocol PPluginInstance;
|
||||
include protocol PPluginScriptableObject;
|
||||
include protocol PCrashReporter;
|
||||
|
||||
|
||||
using NPError from "npapi.h";
|
||||
using NPNVariable from "npapi.h";
|
||||
using mozilla::dom::NativeThreadId from "mozilla/dom/TabMessageUtils.h";
|
||||
|
@ -21,25 +19,9 @@ namespace plugins {
|
|||
intr protocol PPluginModule
|
||||
{
|
||||
manages PPluginInstance;
|
||||
manages PPluginIdentifier;
|
||||
manages PCrashReporter;
|
||||
|
||||
both:
|
||||
/**
|
||||
* Sending a void string to this constructor creates an int identifier whereas
|
||||
* sending a non-void string will create a string identifier. This constructor
|
||||
* may be called by either child or parent. If a race occurs by calling the
|
||||
* constructor with the same string or int argument then we create two actors
|
||||
* and detect the second instance in the child. We prevent the parent's actor
|
||||
* from leaking out to plugin code and only allow the child's to be used.
|
||||
*
|
||||
* When calling into the plugin, the parent may create a "temporary"
|
||||
* identifier which is only valid for the lifetime of the current inerrupt frame.
|
||||
*/
|
||||
async PPluginIdentifier(nsCString aString,
|
||||
int32_t aInt,
|
||||
bool temporary);
|
||||
|
||||
// Window-specific message which instructs the interrupt mechanism to enter
|
||||
// a nested event loop for the current interrupt call.
|
||||
async ProcessNativeEventsInInterruptCall();
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
include protocol PPluginInstance;
|
||||
include protocol PPluginIdentifier;
|
||||
include PluginTypes;
|
||||
|
||||
using struct mozilla::void_t from "ipc/IPCMessageUtils.h";
|
||||
using struct mozilla::null_t from "ipc/IPCMessageUtils.h";
|
||||
|
@ -39,10 +39,10 @@ child:
|
|||
|
||||
both:
|
||||
// NPClass methods
|
||||
intr HasMethod(PPluginIdentifier aId)
|
||||
intr HasMethod(PluginIdentifier aId)
|
||||
returns (bool aHasMethod);
|
||||
|
||||
intr Invoke(PPluginIdentifier aId,
|
||||
intr Invoke(PluginIdentifier aId,
|
||||
Variant[] aArgs)
|
||||
returns (Variant aResult,
|
||||
bool aSuccess);
|
||||
|
@ -51,18 +51,18 @@ both:
|
|||
returns (Variant aResult,
|
||||
bool aSuccess);
|
||||
|
||||
intr HasProperty(PPluginIdentifier aId)
|
||||
intr HasProperty(PluginIdentifier aId)
|
||||
returns (bool aHasProperty);
|
||||
|
||||
intr SetProperty(PPluginIdentifier aId,
|
||||
intr SetProperty(PluginIdentifier aId,
|
||||
Variant aValue)
|
||||
returns (bool aSuccess);
|
||||
|
||||
intr RemoveProperty(PPluginIdentifier aId)
|
||||
intr RemoveProperty(PluginIdentifier aId)
|
||||
returns (bool aSuccess);
|
||||
|
||||
intr Enumerate()
|
||||
returns (PPluginIdentifier[] aProperties,
|
||||
returns (PluginIdentifier[] aProperties,
|
||||
bool aSuccess);
|
||||
|
||||
intr Construct(Variant[] aArgs)
|
||||
|
@ -86,12 +86,12 @@ both:
|
|||
* several checks at once and return all the results simultaneously.
|
||||
*/
|
||||
parent:
|
||||
intr GetParentProperty(PPluginIdentifier aId)
|
||||
intr GetParentProperty(PluginIdentifier aId)
|
||||
returns (Variant aResult,
|
||||
bool aSuccess);
|
||||
|
||||
child:
|
||||
intr GetChildProperty(PPluginIdentifier aId)
|
||||
intr GetChildProperty(PluginIdentifier aId)
|
||||
returns (bool aHasProperty,
|
||||
bool aHasMethod,
|
||||
Variant aResult,
|
||||
|
|
|
@ -1,141 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=2 et :
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "PluginIdentifierChild.h"
|
||||
#include "PluginModuleChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace plugins {
|
||||
|
||||
void
|
||||
PluginIdentifierChild::MakePermanent()
|
||||
{
|
||||
if (mCanonicalIdentifier) {
|
||||
NS_ASSERTION(mCanonicalIdentifier->mHashed && mCanonicalIdentifier->mTemporaryRefs == 0,
|
||||
"Canonical identifiers should always be permanent.");
|
||||
return; // nothing to do
|
||||
}
|
||||
|
||||
if (!mHashed) {
|
||||
NS_ASSERTION(mTemporaryRefs == 0, "Not hashed, but temporary refs?");
|
||||
|
||||
PluginIdentifierChild* c = GetCanonical();
|
||||
if (c) {
|
||||
NS_ASSERTION(c != this, "How did I get in the hash?");
|
||||
mCanonicalIdentifier = c;
|
||||
NS_ASSERTION(mCanonicalIdentifier->mHashed && mCanonicalIdentifier->mTemporaryRefs == 0,
|
||||
"Canonical identifiers should always be permanent.");
|
||||
return;
|
||||
}
|
||||
|
||||
Hash();
|
||||
mHashed = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (mTemporaryRefs) {
|
||||
SendRetain();
|
||||
mTemporaryRefs = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PluginIdentifierChild::StartTemporary()
|
||||
{
|
||||
if (mCanonicalIdentifier) {
|
||||
NS_ASSERTION(mCanonicalIdentifier->mHashed && mCanonicalIdentifier->mTemporaryRefs == 0,
|
||||
"Canonical identifiers should always be permanent.");
|
||||
return; // nothing to do
|
||||
}
|
||||
|
||||
if (!mHashed) {
|
||||
NS_ASSERTION(mTemporaryRefs == 0, "Not hashed, but temporary refs?");
|
||||
|
||||
PluginIdentifierChild* c = GetCanonical();
|
||||
if (c) {
|
||||
NS_ASSERTION(c != this, "How did I get in the hash?");
|
||||
mCanonicalIdentifier = c;
|
||||
NS_ASSERTION(mCanonicalIdentifier->mHashed && mCanonicalIdentifier->mTemporaryRefs == 0,
|
||||
"Canonical identifiers should always be permanent.");
|
||||
return;
|
||||
}
|
||||
|
||||
Hash();
|
||||
mHashed = true;
|
||||
mTemporaryRefs = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (mTemporaryRefs)
|
||||
++mTemporaryRefs;
|
||||
}
|
||||
|
||||
void
|
||||
PluginIdentifierChild::FinishTemporary()
|
||||
{
|
||||
if (mCanonicalIdentifier)
|
||||
return;
|
||||
|
||||
NS_ASSERTION(mHashed, "Finishing unhashed identifier?");
|
||||
if (!mTemporaryRefs)
|
||||
return;
|
||||
|
||||
--mTemporaryRefs;
|
||||
if (mTemporaryRefs)
|
||||
return;
|
||||
|
||||
Unhash();
|
||||
mHashed = false;
|
||||
}
|
||||
|
||||
PluginIdentifierChild*
|
||||
PluginIdentifierChildString::GetCanonical()
|
||||
{
|
||||
PluginModuleChild* module = static_cast<PluginModuleChild*>(Manager());
|
||||
return module->mStringIdentifiers.Get(mString);
|
||||
}
|
||||
|
||||
void
|
||||
PluginIdentifierChildString::Hash()
|
||||
{
|
||||
PluginModuleChild* module = static_cast<PluginModuleChild*>(Manager());
|
||||
NS_ASSERTION(module->mStringIdentifiers.Get(mString) == nullptr, "Replacing Hash?");
|
||||
module->mStringIdentifiers.Put(mString, this);
|
||||
}
|
||||
|
||||
void
|
||||
PluginIdentifierChildString::Unhash()
|
||||
{
|
||||
PluginModuleChild* module = static_cast<PluginModuleChild*>(Manager());
|
||||
NS_ASSERTION(module->mStringIdentifiers.Get(mString) == this, "Incorrect identifier hash?");
|
||||
module->mStringIdentifiers.Remove(mString);
|
||||
}
|
||||
|
||||
PluginIdentifierChild*
|
||||
PluginIdentifierChildInt::GetCanonical()
|
||||
{
|
||||
PluginModuleChild* module = static_cast<PluginModuleChild*>(Manager());
|
||||
return module->mIntIdentifiers.Get(mInt);
|
||||
}
|
||||
|
||||
void
|
||||
PluginIdentifierChildInt::Hash()
|
||||
{
|
||||
PluginModuleChild* module = static_cast<PluginModuleChild*>(Manager());
|
||||
NS_ASSERTION(module->mIntIdentifiers.Get(mInt) == nullptr, "Replacing Hash?");
|
||||
module->mIntIdentifiers.Put(mInt, this);
|
||||
}
|
||||
|
||||
void
|
||||
PluginIdentifierChildInt::Unhash()
|
||||
{
|
||||
PluginModuleChild* module = static_cast<PluginModuleChild*>(Manager());
|
||||
NS_ASSERTION(module->mIntIdentifiers.Get(mInt) == this, "Incorrect identifier hash?");
|
||||
module->mIntIdentifiers.Remove(mInt);
|
||||
}
|
||||
|
||||
} // namespace mozilla::plugins
|
||||
} // namespace mozilla
|
|
@ -1,164 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=2 et :
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef dom_plugins_PluginIdentifierChild_h
|
||||
#define dom_plugins_PluginIdentifierChild_h
|
||||
|
||||
#include "mozilla/plugins/PPluginIdentifierChild.h"
|
||||
#include "npapi.h"
|
||||
#include "npruntime.h"
|
||||
|
||||
#include "nsString.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace plugins {
|
||||
|
||||
class PluginModuleChild;
|
||||
|
||||
/**
|
||||
* Plugin identifiers may be "temporary", see the comment on the
|
||||
* PPluginIdentifier constructor for details. This means that any IPDL method
|
||||
* which receives a PPluginIdentifierChild* parameter must use StackIdentifier
|
||||
* to track it.
|
||||
*/
|
||||
class PluginIdentifierChild : public PPluginIdentifierChild
|
||||
{
|
||||
friend class PluginModuleChild;
|
||||
public:
|
||||
bool IsString()
|
||||
{
|
||||
return mIsString;
|
||||
}
|
||||
|
||||
NPIdentifier ToNPIdentifier()
|
||||
{
|
||||
if (mCanonicalIdentifier) {
|
||||
return mCanonicalIdentifier;
|
||||
}
|
||||
|
||||
NS_ASSERTION(mHashed, "Handing out an unhashed identifier?");
|
||||
return this;
|
||||
}
|
||||
|
||||
void MakePermanent();
|
||||
|
||||
class MOZ_STACK_CLASS StackIdentifier
|
||||
{
|
||||
public:
|
||||
explicit StackIdentifier(PPluginIdentifierChild* actor)
|
||||
: mIdentifier(static_cast<PluginIdentifierChild*>(actor))
|
||||
{
|
||||
if (mIdentifier)
|
||||
mIdentifier->StartTemporary();
|
||||
}
|
||||
|
||||
~StackIdentifier() {
|
||||
if (mIdentifier)
|
||||
mIdentifier->FinishTemporary();
|
||||
}
|
||||
|
||||
PluginIdentifierChild* operator->() { return mIdentifier; }
|
||||
|
||||
private:
|
||||
PluginIdentifierChild* mIdentifier;
|
||||
};
|
||||
|
||||
protected:
|
||||
explicit PluginIdentifierChild(bool aIsString)
|
||||
: mCanonicalIdentifier(nullptr)
|
||||
, mHashed(false)
|
||||
, mTemporaryRefs(0)
|
||||
, mIsString(aIsString)
|
||||
{
|
||||
MOZ_COUNT_CTOR(PluginIdentifierChild);
|
||||
}
|
||||
|
||||
virtual ~PluginIdentifierChild()
|
||||
{
|
||||
MOZ_COUNT_DTOR(PluginIdentifierChild);
|
||||
}
|
||||
|
||||
// The following functions are implemented by the subclasses for their
|
||||
// identifier maps.
|
||||
virtual PluginIdentifierChild* GetCanonical() = 0;
|
||||
virtual void Hash() = 0;
|
||||
virtual void Unhash() = 0;
|
||||
|
||||
private:
|
||||
void StartTemporary();
|
||||
void FinishTemporary();
|
||||
|
||||
// There's a possibility that we already have an actor that wraps the same
|
||||
// string or int because we do all this identifier construction
|
||||
// asynchronously. In this case we need to hand out the canonical version
|
||||
// created by the child side.
|
||||
//
|
||||
// In order to deal with temporary identifiers which appear on the stack,
|
||||
// identifiers use the following state invariants:
|
||||
//
|
||||
// * mCanonicalIdentifier is non-nullptr: this is a duplicate identifier, no
|
||||
// further information is necessary.
|
||||
// * mHashed is false: this identifier is a newborn, non-permanent identifier
|
||||
// * mHashed is true, mTemporaryRefs is 0: this identifier is permanent
|
||||
// * mHashed is true, mTemporaryRefs is non-0: this identifier is temporary;
|
||||
// if NPN_GetFooIdentifier is called for it, we need to retain it. If
|
||||
// all stack references are lost, unhash it because it will soon be
|
||||
// deleted.
|
||||
|
||||
PluginIdentifierChild* mCanonicalIdentifier;
|
||||
bool mHashed;
|
||||
unsigned int mTemporaryRefs;
|
||||
bool mIsString;
|
||||
};
|
||||
|
||||
class PluginIdentifierChildString : public PluginIdentifierChild
|
||||
{
|
||||
friend class PluginModuleChild;
|
||||
public:
|
||||
NPUTF8* ToString()
|
||||
{
|
||||
return ToNewCString(mString);
|
||||
}
|
||||
|
||||
protected:
|
||||
explicit PluginIdentifierChildString(const nsCString& aString)
|
||||
: PluginIdentifierChild(true),
|
||||
mString(aString)
|
||||
{ }
|
||||
|
||||
virtual PluginIdentifierChild* GetCanonical();
|
||||
virtual void Hash();
|
||||
virtual void Unhash();
|
||||
|
||||
nsCString mString;
|
||||
};
|
||||
|
||||
class PluginIdentifierChildInt : public PluginIdentifierChild
|
||||
{
|
||||
friend class PluginModuleChild;
|
||||
public:
|
||||
int32_t ToInt()
|
||||
{
|
||||
return mInt;
|
||||
}
|
||||
|
||||
protected:
|
||||
explicit PluginIdentifierChildInt(int32_t aInt)
|
||||
: PluginIdentifierChild(false),
|
||||
mInt(aInt)
|
||||
{ }
|
||||
|
||||
virtual PluginIdentifierChild* GetCanonical();
|
||||
virtual void Hash();
|
||||
virtual void Unhash();
|
||||
|
||||
int32_t mInt;
|
||||
};
|
||||
|
||||
} // namespace plugins
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // dom_plugins_PluginIdentifierChild_h
|
|
@ -1,80 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=2 et :
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "PluginIdentifierParent.h"
|
||||
|
||||
#include "nsNPAPIPlugin.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "PluginScriptableObjectUtils.h"
|
||||
#include "mozilla/unused.h"
|
||||
|
||||
using namespace mozilla::plugins::parent;
|
||||
|
||||
namespace mozilla {
|
||||
namespace plugins {
|
||||
|
||||
void
|
||||
PluginIdentifierParent::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
// Implement me! Bug 1005161
|
||||
}
|
||||
|
||||
bool
|
||||
PluginIdentifierParent::RecvRetain()
|
||||
{
|
||||
mTemporaryRefs = 0;
|
||||
|
||||
// Intern the jsid if necessary.
|
||||
AutoSafeJSContext cx;
|
||||
JS::Rooted<jsid> id(cx, NPIdentifierToJSId(mIdentifier));
|
||||
if (!JSID_IS_STRING(id)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// The following is what nsNPAPIPlugin.cpp does. Gross, but the API doesn't
|
||||
// give you a NPP to play with.
|
||||
JS::Rooted<JSString*> str(cx, JSID_TO_STRING(id));
|
||||
JSString* str2 = JS_InternJSString(cx, str);
|
||||
if (!str2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
NS_ASSERTION(str == str2, "Interning a string in a JSID should always return the same string.");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
PluginIdentifierParent::StackIdentifier::StackIdentifier
|
||||
(PluginInstanceParent* inst, NPIdentifier aIdentifier)
|
||||
: mIdentifier(inst->Module()->GetIdentifierForNPIdentifier(inst->GetNPP(), aIdentifier))
|
||||
{
|
||||
}
|
||||
|
||||
PluginIdentifierParent::StackIdentifier::StackIdentifier
|
||||
(NPObject* aObject, NPIdentifier aIdentifier)
|
||||
: mIdentifier(nullptr)
|
||||
{
|
||||
PluginInstanceParent* inst = GetInstance(aObject);
|
||||
mIdentifier = inst->Module()->GetIdentifierForNPIdentifier(inst->GetNPP(), aIdentifier);
|
||||
}
|
||||
|
||||
PluginIdentifierParent::StackIdentifier::~StackIdentifier()
|
||||
{
|
||||
if (!mIdentifier) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mIdentifier->IsTemporary()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mIdentifier->RemoveTemporaryRef()) {
|
||||
unused << PPluginIdentifierParent::Send__delete__(mIdentifier);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mozilla::plugins
|
||||
} // namespace mozilla
|
|
@ -1,91 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=2 et :
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef dom_plugins_PluginIdentifierParent_h
|
||||
#define dom_plugins_PluginIdentifierParent_h
|
||||
|
||||
#include "mozilla/plugins/PPluginIdentifierParent.h"
|
||||
|
||||
#include "npapi.h"
|
||||
#include "npruntime.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace plugins {
|
||||
|
||||
class PluginInstanceParent;
|
||||
|
||||
class PluginIdentifierParent : public PPluginIdentifierParent
|
||||
{
|
||||
friend class PluginModuleParent;
|
||||
|
||||
public:
|
||||
NPIdentifier ToNPIdentifier()
|
||||
{
|
||||
return mIdentifier;
|
||||
}
|
||||
|
||||
bool IsTemporary() {
|
||||
return !!mTemporaryRefs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds a perhaps-temporary identifier for the current stack frame.
|
||||
*/
|
||||
class MOZ_STACK_CLASS StackIdentifier
|
||||
{
|
||||
public:
|
||||
StackIdentifier(PluginInstanceParent* inst, NPIdentifier aIdentifier);
|
||||
StackIdentifier(NPObject* aObject, NPIdentifier aIdentifier);
|
||||
~StackIdentifier();
|
||||
|
||||
operator PluginIdentifierParent*() {
|
||||
return mIdentifier;
|
||||
}
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(StackIdentifier);
|
||||
|
||||
PluginIdentifierParent* mIdentifier;
|
||||
};
|
||||
|
||||
protected:
|
||||
PluginIdentifierParent(NPIdentifier aIdentifier, bool aTemporary)
|
||||
: mIdentifier(aIdentifier)
|
||||
, mTemporaryRefs(aTemporary ? 1 : 0)
|
||||
{
|
||||
MOZ_COUNT_CTOR(PluginIdentifierParent);
|
||||
}
|
||||
|
||||
virtual ~PluginIdentifierParent()
|
||||
{
|
||||
MOZ_COUNT_DTOR(PluginIdentifierParent);
|
||||
}
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvRetain() MOZ_OVERRIDE;
|
||||
|
||||
void AddTemporaryRef() {
|
||||
mTemporaryRefs++;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns true if the last temporary reference was removed.
|
||||
*/
|
||||
bool RemoveTemporaryRef() {
|
||||
--mTemporaryRefs;
|
||||
return !mTemporaryRefs;
|
||||
}
|
||||
|
||||
private:
|
||||
NPIdentifier mIdentifier;
|
||||
unsigned int mTemporaryRefs;
|
||||
};
|
||||
|
||||
} // namespace plugins
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // dom_plugins_PluginIdentifierParent_h
|
|
@ -37,7 +37,6 @@
|
|||
#include "mozilla/plugins/StreamNotifyChild.h"
|
||||
#include "mozilla/plugins/BrowserStreamChild.h"
|
||||
#include "mozilla/plugins/PluginStreamChild.h"
|
||||
#include "PluginIdentifierChild.h"
|
||||
#include "mozilla/dom/CrashReporterChild.h"
|
||||
|
||||
#include "nsNPAPIPlugin.h"
|
||||
|
@ -121,6 +120,7 @@ PluginModuleChild::~PluginModuleChild()
|
|||
// other similar hooks.
|
||||
|
||||
DeinitGraphics();
|
||||
PluginScriptableObjectChild::ClearIdentifiers();
|
||||
|
||||
gInstance = nullptr;
|
||||
}
|
||||
|
@ -1844,38 +1844,6 @@ PluginModuleChild::AnswerNP_Initialize(NPError* _retval)
|
|||
#endif
|
||||
}
|
||||
|
||||
PPluginIdentifierChild*
|
||||
PluginModuleChild::AllocPPluginIdentifierChild(const nsCString& aString,
|
||||
const int32_t& aInt,
|
||||
const bool& aTemporary)
|
||||
{
|
||||
// We cannot call SetPermanent within this function because Manager() isn't
|
||||
// set up yet.
|
||||
if (aString.IsVoid()) {
|
||||
return new PluginIdentifierChildInt(aInt);
|
||||
}
|
||||
return new PluginIdentifierChildString(aString);
|
||||
}
|
||||
|
||||
bool
|
||||
PluginModuleChild::RecvPPluginIdentifierConstructor(PPluginIdentifierChild* actor,
|
||||
const nsCString& aString,
|
||||
const int32_t& aInt,
|
||||
const bool& aTemporary)
|
||||
{
|
||||
if (!aTemporary) {
|
||||
static_cast<PluginIdentifierChild*>(actor)->MakePermanent();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
PluginModuleChild::DeallocPPluginIdentifierChild(PPluginIdentifierChild* aActor)
|
||||
{
|
||||
delete aActor;
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(XP_WIN)
|
||||
BOOL WINAPI
|
||||
PMCGetWindowInfoHook(HWND hWnd, PWINDOWINFO pwi)
|
||||
|
@ -2180,18 +2148,11 @@ PluginModuleChild::NPN_GetStringIdentifier(const NPUTF8* aName)
|
|||
if (!aName)
|
||||
return 0;
|
||||
|
||||
PluginModuleChild* self = PluginModuleChild::current();
|
||||
nsDependentCString name(aName);
|
||||
|
||||
PluginIdentifierChildString* ident = self->mStringIdentifiers.Get(name);
|
||||
if (!ident) {
|
||||
nsCString nameCopy(name);
|
||||
|
||||
ident = new PluginIdentifierChildString(nameCopy);
|
||||
self->SendPPluginIdentifierConstructor(ident, nameCopy, -1, false);
|
||||
}
|
||||
ident->MakePermanent();
|
||||
return ident;
|
||||
PluginIdentifier ident(name);
|
||||
PluginScriptableObjectChild::StackIdentifier stackID(ident);
|
||||
stackID.MakePermanent();
|
||||
return stackID.ToNPIdentifier();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -2206,23 +2167,16 @@ PluginModuleChild::NPN_GetStringIdentifiers(const NPUTF8** aNames,
|
|||
NS_RUNTIMEABORT("Bad input! Headed for a crash!");
|
||||
}
|
||||
|
||||
PluginModuleChild* self = PluginModuleChild::current();
|
||||
|
||||
for (int32_t index = 0; index < aNameCount; ++index) {
|
||||
if (!aNames[index]) {
|
||||
aIdentifiers[index] = 0;
|
||||
continue;
|
||||
}
|
||||
nsDependentCString name(aNames[index]);
|
||||
PluginIdentifierChildString* ident = self->mStringIdentifiers.Get(name);
|
||||
if (!ident) {
|
||||
nsCString nameCopy(name);
|
||||
|
||||
ident = new PluginIdentifierChildString(nameCopy);
|
||||
self->SendPPluginIdentifierConstructor(ident, nameCopy, -1, false);
|
||||
}
|
||||
ident->MakePermanent();
|
||||
aIdentifiers[index] = ident;
|
||||
PluginIdentifier ident(name);
|
||||
PluginScriptableObjectChild::StackIdentifier stackID(ident);
|
||||
stackID.MakePermanent();
|
||||
aIdentifiers[index] = stackID.ToNPIdentifier();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2231,9 +2185,8 @@ PluginModuleChild::NPN_IdentifierIsString(NPIdentifier aIdentifier)
|
|||
{
|
||||
PLUGIN_LOG_DEBUG_FUNCTION;
|
||||
|
||||
PluginIdentifierChild* ident =
|
||||
static_cast<PluginIdentifierChild*>(aIdentifier);
|
||||
return ident->IsString();
|
||||
PluginScriptableObjectChild::StackIdentifier stack(aIdentifier);
|
||||
return stack.IsString();
|
||||
}
|
||||
|
||||
NPIdentifier
|
||||
|
@ -2242,18 +2195,10 @@ PluginModuleChild::NPN_GetIntIdentifier(int32_t aIntId)
|
|||
PLUGIN_LOG_DEBUG_FUNCTION;
|
||||
AssertPluginThread();
|
||||
|
||||
PluginModuleChild* self = PluginModuleChild::current();
|
||||
|
||||
PluginIdentifierChildInt* ident = self->mIntIdentifiers.Get(aIntId);
|
||||
if (!ident) {
|
||||
nsCString voidString;
|
||||
voidString.SetIsVoid(true);
|
||||
|
||||
ident = new PluginIdentifierChildInt(aIntId);
|
||||
self->SendPPluginIdentifierConstructor(ident, voidString, aIntId, false);
|
||||
}
|
||||
ident->MakePermanent();
|
||||
return ident;
|
||||
PluginIdentifier ident(aIntId);
|
||||
PluginScriptableObjectChild::StackIdentifier stackID(ident);
|
||||
stackID.MakePermanent();
|
||||
return stackID.ToNPIdentifier();
|
||||
}
|
||||
|
||||
NPUTF8*
|
||||
|
@ -2261,8 +2206,9 @@ PluginModuleChild::NPN_UTF8FromIdentifier(NPIdentifier aIdentifier)
|
|||
{
|
||||
PLUGIN_LOG_DEBUG_FUNCTION;
|
||||
|
||||
if (static_cast<PluginIdentifierChild*>(aIdentifier)->IsString()) {
|
||||
return static_cast<PluginIdentifierChildString*>(aIdentifier)->ToString();
|
||||
PluginScriptableObjectChild::StackIdentifier stackID(aIdentifier);
|
||||
if (stackID.IsString()) {
|
||||
return ToNewCString(stackID.GetString());
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -2272,8 +2218,9 @@ PluginModuleChild::NPN_IntFromIdentifier(NPIdentifier aIdentifier)
|
|||
{
|
||||
PLUGIN_LOG_DEBUG_FUNCTION;
|
||||
|
||||
if (!static_cast<PluginIdentifierChild*>(aIdentifier)->IsString()) {
|
||||
return static_cast<PluginIdentifierChildInt*>(aIdentifier)->ToInt();
|
||||
PluginScriptableObjectChild::StackIdentifier stackID(aIdentifier);
|
||||
if (!stackID.IsString()) {
|
||||
return stackID.GetInt();
|
||||
}
|
||||
return INT32_MIN;
|
||||
}
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
|
||||
#include "mozilla/plugins/PPluginModuleChild.h"
|
||||
#include "mozilla/plugins/PluginInstanceChild.h"
|
||||
#include "mozilla/plugins/PluginIdentifierChild.h"
|
||||
#include "mozilla/plugins/PluginMessageUtils.h"
|
||||
|
||||
// NOTE: stolen from nsNPAPIPlugin.h
|
||||
|
@ -77,20 +76,6 @@ protected:
|
|||
virtual bool AnswerNP_GetEntryPoints(NPError* rv) MOZ_OVERRIDE;
|
||||
virtual bool AnswerNP_Initialize(NPError* rv) MOZ_OVERRIDE;
|
||||
|
||||
virtual PPluginIdentifierChild*
|
||||
AllocPPluginIdentifierChild(const nsCString& aString,
|
||||
const int32_t& aInt,
|
||||
const bool& aTemporary) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool
|
||||
RecvPPluginIdentifierConstructor(PPluginIdentifierChild* actor,
|
||||
const nsCString& aString,
|
||||
const int32_t& aInt,
|
||||
const bool& aTemporary) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool
|
||||
DeallocPPluginIdentifierChild(PPluginIdentifierChild* aActor) MOZ_OVERRIDE;
|
||||
|
||||
virtual PPluginInstanceChild*
|
||||
AllocPPluginInstanceChild(const nsCString& aMimeType,
|
||||
const uint16_t& aMode,
|
||||
|
@ -388,12 +373,6 @@ private:
|
|||
*/
|
||||
nsTHashtable<NPObjectData> mObjectMap;
|
||||
|
||||
friend class PluginIdentifierChild;
|
||||
friend class PluginIdentifierChildString;
|
||||
friend class PluginIdentifierChildInt;
|
||||
nsDataHashtable<nsCStringHashKey, PluginIdentifierChildString*> mStringIdentifiers;
|
||||
nsDataHashtable<nsUint32HashKey, PluginIdentifierChildInt*> mIntIdentifiers;
|
||||
|
||||
public: // called by PluginInstanceChild
|
||||
/**
|
||||
* Dealloc an NPObject after last-release or when the associated instance
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include "nsIObserverService.h"
|
||||
#include "nsNPAPIPlugin.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "PluginIdentifierParent.h"
|
||||
#include "prsystem.h"
|
||||
#include "GeckoProfiler.h"
|
||||
|
||||
|
@ -779,37 +778,6 @@ PluginModuleParent::NotifyPluginCrashed()
|
|||
mPlugin->PluginCrashed(mPluginDumpID, mBrowserDumpID);
|
||||
}
|
||||
|
||||
PPluginIdentifierParent*
|
||||
PluginModuleParent::AllocPPluginIdentifierParent(const nsCString& aString,
|
||||
const int32_t& aInt,
|
||||
const bool& aTemporary)
|
||||
{
|
||||
if (aTemporary) {
|
||||
NS_ERROR("Plugins don't create temporary identifiers.");
|
||||
return nullptr; // should abort the plugin
|
||||
}
|
||||
|
||||
NPIdentifier npident = aString.IsVoid() ?
|
||||
mozilla::plugins::parent::_getintidentifier(aInt) :
|
||||
mozilla::plugins::parent::_getstringidentifier(aString.get());
|
||||
|
||||
if (!npident) {
|
||||
NS_WARNING("Failed to get identifier!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PluginIdentifierParent* ident = new PluginIdentifierParent(npident, false);
|
||||
mIdentifiers.Put(npident, ident);
|
||||
return ident;
|
||||
}
|
||||
|
||||
bool
|
||||
PluginModuleParent::DeallocPPluginIdentifierParent(PPluginIdentifierParent* aActor)
|
||||
{
|
||||
delete aActor;
|
||||
return true;
|
||||
}
|
||||
|
||||
PPluginInstanceParent*
|
||||
PluginModuleParent::AllocPPluginInstanceParent(const nsCString& aMimeType,
|
||||
const uint16_t& aMode,
|
||||
|
@ -1051,44 +1019,6 @@ PluginModuleParent::AnswerNPN_UserAgent(nsCString* userAgent)
|
|||
return true;
|
||||
}
|
||||
|
||||
PluginIdentifierParent*
|
||||
PluginModuleParent::GetIdentifierForNPIdentifier(NPP npp, NPIdentifier aIdentifier)
|
||||
{
|
||||
PluginIdentifierParent* ident;
|
||||
if (mIdentifiers.Get(aIdentifier, &ident)) {
|
||||
if (ident->IsTemporary()) {
|
||||
ident->AddTemporaryRef();
|
||||
}
|
||||
return ident;
|
||||
}
|
||||
|
||||
nsCString string;
|
||||
int32_t intval = -1;
|
||||
bool temporary = false;
|
||||
if (mozilla::plugins::parent::_identifierisstring(aIdentifier)) {
|
||||
NPUTF8* chars =
|
||||
mozilla::plugins::parent::_utf8fromidentifier(aIdentifier);
|
||||
if (!chars) {
|
||||
return nullptr;
|
||||
}
|
||||
string.Adopt(chars);
|
||||
temporary = !NPStringIdentifierIsPermanent(npp, aIdentifier);
|
||||
}
|
||||
else {
|
||||
intval = mozilla::plugins::parent::_intfromidentifier(aIdentifier);
|
||||
string.SetIsVoid(true);
|
||||
}
|
||||
|
||||
ident = new PluginIdentifierParent(aIdentifier, temporary);
|
||||
if (!SendPPluginIdentifierConstructor(ident, string, intval, temporary))
|
||||
return nullptr;
|
||||
|
||||
if (!temporary) {
|
||||
mIdentifiers.Put(aIdentifier, ident);
|
||||
}
|
||||
return ident;
|
||||
}
|
||||
|
||||
PluginInstanceParent*
|
||||
PluginModuleParent::InstCast(NPP instance)
|
||||
{
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "mozilla/plugins/PluginProcessParent.h"
|
||||
#include "mozilla/plugins/PPluginModuleParent.h"
|
||||
#include "mozilla/plugins/PluginMessageUtils.h"
|
||||
#include "mozilla/plugins/PluginTypes.h"
|
||||
#include "npapi.h"
|
||||
#include "npfunctions.h"
|
||||
#include "nsAutoPtr.h"
|
||||
|
@ -35,7 +36,6 @@ namespace plugins {
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
class BrowserStreamParent;
|
||||
class PluginIdentifierParent;
|
||||
class PluginInstanceParent;
|
||||
|
||||
#ifdef XP_WIN
|
||||
|
@ -67,14 +67,6 @@ private:
|
|||
|
||||
protected:
|
||||
|
||||
virtual PPluginIdentifierParent*
|
||||
AllocPPluginIdentifierParent(const nsCString& aString,
|
||||
const int32_t& aInt,
|
||||
const bool& aTemporary) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool
|
||||
DeallocPPluginIdentifierParent(PPluginIdentifierParent* aActor) MOZ_OVERRIDE;
|
||||
|
||||
PPluginInstanceParent*
|
||||
AllocPPluginInstanceParent(const nsCString& aMimeType,
|
||||
const uint16_t& aMode,
|
||||
|
@ -116,15 +108,6 @@ public:
|
|||
return !IsOnCxxStack();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an identifier actor for this NPIdentifier. If this is a temporary
|
||||
* identifier, the temporary refcount is increased by one. This method
|
||||
* is intended only for use by StackIdentifier and the scriptable
|
||||
* Enumerate hook.
|
||||
*/
|
||||
PluginIdentifierParent*
|
||||
GetIdentifierForNPIdentifier(NPP npp, NPIdentifier aIdentifier);
|
||||
|
||||
void ProcessRemoteNativeEventsInInterruptCall();
|
||||
|
||||
void TerminateChildProcess(MessageLoop* aMsgLoop);
|
||||
|
@ -298,7 +281,6 @@ private:
|
|||
bool mClearSiteDataSupported;
|
||||
bool mGetSitesWithDataSupported;
|
||||
const NPNetscapeFuncs* mNPNIface;
|
||||
nsDataHashtable<nsPtrHashKey<void>, PluginIdentifierParent*> mIdentifiers;
|
||||
nsNPAPIPlugin* mPlugin;
|
||||
ScopedMethodFactory<PluginModuleParent> mTaskFactory;
|
||||
nsString mPluginDumpID;
|
||||
|
|
|
@ -6,10 +6,125 @@
|
|||
|
||||
#include "PluginScriptableObjectChild.h"
|
||||
#include "PluginScriptableObjectUtils.h"
|
||||
#include "PluginIdentifierChild.h"
|
||||
#include "mozilla/plugins/PluginTypes.h"
|
||||
|
||||
using namespace mozilla::plugins;
|
||||
|
||||
/**
|
||||
* NPIdentifiers in the plugin process use a tagged representation. The low bit
|
||||
* stores the tag. If it's zero, the identifier is a string, and the value is a
|
||||
* pointer to a StoredIdentifier. If the tag bit is 1, then the rest of the
|
||||
* NPIdentifier value is the integer itself. Like the JSAPI, we require that all
|
||||
* integers stored in NPIdentifier be non-negative.
|
||||
*
|
||||
* String identifiers are stored in the sIdentifiers hashtable to ensure
|
||||
* uniqueness. The lifetime of these identifiers is only as long as the incoming
|
||||
* IPC call from the chrome process. If the plugin wants to retain an
|
||||
* identifier, it needs to call NPN_GetStringIdentifier, which causes the
|
||||
* mPermanent flag to be set on the identifier. When this flag is set, the
|
||||
* identifier is saved until the plugin process exits.
|
||||
*
|
||||
* The StackIdentifier RAII class is used to manage ownership of
|
||||
* identifiers. Any identifier obtained from this class should not be used
|
||||
* outside its scope, except when the MakePermanent() method has been called on
|
||||
* it.
|
||||
*
|
||||
* The lifetime of an NPIdentifier in the plugin process is totally divorced
|
||||
* from the lifetime of an NPIdentifier in the chrome process (where an
|
||||
* NPIdentifier is stored as a jsid). The JS GC in the chrome process is able to
|
||||
* trace through the entire heap, unlike in the plugin process, so there is no
|
||||
* reason to retain identifiers there.
|
||||
*/
|
||||
|
||||
PluginScriptableObjectChild::IdentifierTable PluginScriptableObjectChild::sIdentifiers;
|
||||
|
||||
/* static */ PluginScriptableObjectChild::StoredIdentifier*
|
||||
PluginScriptableObjectChild::HashIdentifier(const nsCString& aIdentifier)
|
||||
{
|
||||
StoredIdentifier* stored = sIdentifiers.Get(aIdentifier);
|
||||
if (stored) {
|
||||
return stored;
|
||||
}
|
||||
|
||||
stored = new StoredIdentifier(aIdentifier);
|
||||
sIdentifiers.Put(aIdentifier, stored);
|
||||
return stored;
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
PluginScriptableObjectChild::UnhashIdentifier(StoredIdentifier* aStored)
|
||||
{
|
||||
MOZ_ASSERT(sIdentifiers.Get(aStored->mIdentifier));
|
||||
sIdentifiers.Remove(aStored->mIdentifier);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
PluginScriptableObjectChild::ClearIdentifiers()
|
||||
{
|
||||
sIdentifiers.Clear();
|
||||
}
|
||||
|
||||
PluginScriptableObjectChild::StackIdentifier::StackIdentifier(const PluginIdentifier& aIdentifier)
|
||||
: mIdentifier(aIdentifier),
|
||||
mStored(nullptr)
|
||||
{
|
||||
if (aIdentifier.type() == PluginIdentifier::TnsCString) {
|
||||
mStored = PluginScriptableObjectChild::HashIdentifier(mIdentifier.get_nsCString());
|
||||
}
|
||||
}
|
||||
|
||||
PluginScriptableObjectChild::StackIdentifier::StackIdentifier(NPIdentifier aIdentifier)
|
||||
: mStored(nullptr)
|
||||
{
|
||||
uintptr_t bits = reinterpret_cast<uintptr_t>(aIdentifier);
|
||||
if (bits & 1) {
|
||||
int32_t num = int32_t(bits >> 1);
|
||||
mIdentifier = PluginIdentifier(num);
|
||||
} else {
|
||||
mStored = static_cast<StoredIdentifier*>(aIdentifier);
|
||||
mIdentifier = mStored->mIdentifier;
|
||||
}
|
||||
}
|
||||
|
||||
PluginScriptableObjectChild::StackIdentifier::~StackIdentifier()
|
||||
{
|
||||
if (!mStored) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Each StackIdentifier owns one reference to its StoredIdentifier. In
|
||||
// addition, the sIdentifiers table owns a reference. If mPermanent is false
|
||||
// and sIdentifiers has the last reference, then we want to remove the
|
||||
// StoredIdentifier from the table (and destroy it).
|
||||
StoredIdentifier *stored = mStored;
|
||||
mStored = nullptr;
|
||||
if (stored->mRefCnt == 1 && !stored->mPermanent) {
|
||||
PluginScriptableObjectChild::UnhashIdentifier(stored);
|
||||
}
|
||||
}
|
||||
|
||||
NPIdentifier
|
||||
PluginScriptableObjectChild::StackIdentifier::ToNPIdentifier() const
|
||||
{
|
||||
if (mStored) {
|
||||
MOZ_ASSERT(mIdentifier.type() == PluginIdentifier::TnsCString);
|
||||
MOZ_ASSERT((reinterpret_cast<uintptr_t>(mStored.get()) & 1) == 0);
|
||||
return mStored;
|
||||
}
|
||||
|
||||
int32_t num = mIdentifier.get_int32_t();
|
||||
// The JS engine imposes this condition on int32s in jsids, so we assume it.
|
||||
MOZ_ASSERT(num >= 0);
|
||||
return reinterpret_cast<NPIdentifier>((num << 1) | 1);
|
||||
}
|
||||
|
||||
static PluginIdentifier
|
||||
FromNPIdentifier(NPIdentifier aIdentifier)
|
||||
{
|
||||
PluginScriptableObjectChild::StackIdentifier stack(aIdentifier);
|
||||
return stack.GetIdentifier();
|
||||
}
|
||||
|
||||
// static
|
||||
NPObject*
|
||||
PluginScriptableObjectChild::ScriptableAllocate(NPP aInstance,
|
||||
|
@ -85,7 +200,7 @@ PluginScriptableObjectChild::ScriptableHasMethod(NPObject* aObject,
|
|||
NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
|
||||
|
||||
bool result;
|
||||
actor->CallHasMethod(static_cast<PPluginIdentifierChild*>(aName), &result);
|
||||
actor->CallHasMethod(FromNPIdentifier(aName), &result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -122,7 +237,7 @@ PluginScriptableObjectChild::ScriptableInvoke(NPObject* aObject,
|
|||
|
||||
Variant remoteResult;
|
||||
bool success;
|
||||
actor->CallInvoke(static_cast<PPluginIdentifierChild*>(aName), args,
|
||||
actor->CallInvoke(FromNPIdentifier(aName), args,
|
||||
&remoteResult, &success);
|
||||
|
||||
if (!success) {
|
||||
|
@ -196,7 +311,7 @@ PluginScriptableObjectChild::ScriptableHasProperty(NPObject* aObject,
|
|||
NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
|
||||
|
||||
bool result;
|
||||
actor->CallHasProperty(static_cast<PPluginIdentifierChild*>(aName), &result);
|
||||
actor->CallHasProperty(FromNPIdentifier(aName), &result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -225,7 +340,7 @@ PluginScriptableObjectChild::ScriptableGetProperty(NPObject* aObject,
|
|||
|
||||
Variant result;
|
||||
bool success;
|
||||
actor->CallGetParentProperty(static_cast<PPluginIdentifierChild*>(aName),
|
||||
actor->CallGetParentProperty(FromNPIdentifier(aName),
|
||||
&result, &success);
|
||||
|
||||
if (!success) {
|
||||
|
@ -265,7 +380,7 @@ PluginScriptableObjectChild::ScriptableSetProperty(NPObject* aObject,
|
|||
}
|
||||
|
||||
bool success;
|
||||
actor->CallSetProperty(static_cast<PPluginIdentifierChild*>(aName), value,
|
||||
actor->CallSetProperty(FromNPIdentifier(aName), value,
|
||||
&success);
|
||||
|
||||
return success;
|
||||
|
@ -293,7 +408,7 @@ PluginScriptableObjectChild::ScriptableRemoveProperty(NPObject* aObject,
|
|||
NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
|
||||
|
||||
bool success;
|
||||
actor->CallRemoveProperty(static_cast<PPluginIdentifierChild*>(aName),
|
||||
actor->CallRemoveProperty(FromNPIdentifier(aName),
|
||||
&success);
|
||||
|
||||
return success;
|
||||
|
@ -321,7 +436,7 @@ PluginScriptableObjectChild::ScriptableEnumerate(NPObject* aObject,
|
|||
NS_ASSERTION(actor, "This shouldn't ever be null!");
|
||||
NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
|
||||
|
||||
AutoInfallibleTArray<PPluginIdentifierChild*, 10> identifiers;
|
||||
AutoInfallibleTArray<PluginIdentifier, 10> identifiers;
|
||||
bool success;
|
||||
actor->CallEnumerate(&identifiers, &success);
|
||||
|
||||
|
@ -343,8 +458,10 @@ PluginScriptableObjectChild::ScriptableEnumerate(NPObject* aObject,
|
|||
}
|
||||
|
||||
for (uint32_t index = 0; index < *aCount; index++) {
|
||||
(*aIdentifiers)[index] =
|
||||
static_cast<PPluginIdentifierChild*>(identifiers[index]);
|
||||
StackIdentifier id(identifiers[index]);
|
||||
// Make the id permanent in case the plugin retains it.
|
||||
id.MakePermanent();
|
||||
(*aIdentifiers)[index] = id.ToNPIdentifier();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -610,7 +727,7 @@ PluginScriptableObjectChild::AnswerInvalidate()
|
|||
}
|
||||
|
||||
bool
|
||||
PluginScriptableObjectChild::AnswerHasMethod(PPluginIdentifierChild* aId,
|
||||
PluginScriptableObjectChild::AnswerHasMethod(const PluginIdentifier& aId,
|
||||
bool* aHasMethod)
|
||||
{
|
||||
AssertPluginThread();
|
||||
|
@ -629,13 +746,13 @@ PluginScriptableObjectChild::AnswerHasMethod(PPluginIdentifierChild* aId,
|
|||
return true;
|
||||
}
|
||||
|
||||
PluginIdentifierChild::StackIdentifier id(aId);
|
||||
*aHasMethod = mObject->_class->hasMethod(mObject, id->ToNPIdentifier());
|
||||
StackIdentifier id(aId);
|
||||
*aHasMethod = mObject->_class->hasMethod(mObject, id.ToNPIdentifier());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
PluginScriptableObjectChild::AnswerInvoke(PPluginIdentifierChild* aId,
|
||||
PluginScriptableObjectChild::AnswerInvoke(const PluginIdentifier& aId,
|
||||
const InfallibleTArray<Variant>& aArgs,
|
||||
Variant* aResult,
|
||||
bool* aSuccess)
|
||||
|
@ -673,8 +790,8 @@ PluginScriptableObjectChild::AnswerInvoke(PPluginIdentifierChild* aId,
|
|||
|
||||
NPVariant result;
|
||||
VOID_TO_NPVARIANT(result);
|
||||
PluginIdentifierChild::StackIdentifier id(aId);
|
||||
bool success = mObject->_class->invoke(mObject, id->ToNPIdentifier(),
|
||||
StackIdentifier id(aId);
|
||||
bool success = mObject->_class->invoke(mObject, id.ToNPIdentifier(),
|
||||
convertedArgs.Elements(), argCount,
|
||||
&result);
|
||||
|
||||
|
@ -775,7 +892,7 @@ PluginScriptableObjectChild::AnswerInvokeDefault(const InfallibleTArray<Variant>
|
|||
}
|
||||
|
||||
bool
|
||||
PluginScriptableObjectChild::AnswerHasProperty(PPluginIdentifierChild* aId,
|
||||
PluginScriptableObjectChild::AnswerHasProperty(const PluginIdentifier& aId,
|
||||
bool* aHasProperty)
|
||||
{
|
||||
AssertPluginThread();
|
||||
|
@ -794,13 +911,13 @@ PluginScriptableObjectChild::AnswerHasProperty(PPluginIdentifierChild* aId,
|
|||
return true;
|
||||
}
|
||||
|
||||
PluginIdentifierChild::StackIdentifier id(aId);
|
||||
*aHasProperty = mObject->_class->hasProperty(mObject, id->ToNPIdentifier());
|
||||
StackIdentifier id(aId);
|
||||
*aHasProperty = mObject->_class->hasProperty(mObject, id.ToNPIdentifier());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
PluginScriptableObjectChild::AnswerGetChildProperty(PPluginIdentifierChild* aId,
|
||||
PluginScriptableObjectChild::AnswerGetChildProperty(const PluginIdentifier& aId,
|
||||
bool* aHasProperty,
|
||||
bool* aHasMethod,
|
||||
Variant* aResult,
|
||||
|
@ -824,8 +941,8 @@ PluginScriptableObjectChild::AnswerGetChildProperty(PPluginIdentifierChild* aId,
|
|||
return true;
|
||||
}
|
||||
|
||||
PluginIdentifierChild::StackIdentifier stackID(aId);
|
||||
NPIdentifier id = stackID->ToNPIdentifier();
|
||||
StackIdentifier stackID(aId);
|
||||
NPIdentifier id = stackID.ToNPIdentifier();
|
||||
|
||||
*aHasProperty = mObject->_class->hasProperty(mObject, id);
|
||||
*aHasMethod = mObject->_class->hasMethod(mObject, id);
|
||||
|
@ -850,7 +967,7 @@ PluginScriptableObjectChild::AnswerGetChildProperty(PPluginIdentifierChild* aId,
|
|||
}
|
||||
|
||||
bool
|
||||
PluginScriptableObjectChild::AnswerSetProperty(PPluginIdentifierChild* aId,
|
||||
PluginScriptableObjectChild::AnswerSetProperty(const PluginIdentifier& aId,
|
||||
const Variant& aValue,
|
||||
bool* aSuccess)
|
||||
{
|
||||
|
@ -871,8 +988,8 @@ PluginScriptableObjectChild::AnswerSetProperty(PPluginIdentifierChild* aId,
|
|||
return true;
|
||||
}
|
||||
|
||||
PluginIdentifierChild::StackIdentifier stackID(aId);
|
||||
NPIdentifier id = stackID->ToNPIdentifier();
|
||||
StackIdentifier stackID(aId);
|
||||
NPIdentifier id = stackID.ToNPIdentifier();
|
||||
|
||||
if (!mObject->_class->hasProperty(mObject, id)) {
|
||||
*aSuccess = false;
|
||||
|
@ -889,7 +1006,7 @@ PluginScriptableObjectChild::AnswerSetProperty(PPluginIdentifierChild* aId,
|
|||
}
|
||||
|
||||
bool
|
||||
PluginScriptableObjectChild::AnswerRemoveProperty(PPluginIdentifierChild* aId,
|
||||
PluginScriptableObjectChild::AnswerRemoveProperty(const PluginIdentifier& aId,
|
||||
bool* aSuccess)
|
||||
{
|
||||
AssertPluginThread();
|
||||
|
@ -909,8 +1026,8 @@ PluginScriptableObjectChild::AnswerRemoveProperty(PPluginIdentifierChild* aId,
|
|||
return true;
|
||||
}
|
||||
|
||||
PluginIdentifierChild::StackIdentifier stackID(aId);
|
||||
NPIdentifier id = stackID->ToNPIdentifier();
|
||||
StackIdentifier stackID(aId);
|
||||
NPIdentifier id = stackID.ToNPIdentifier();
|
||||
*aSuccess = mObject->_class->hasProperty(mObject, id) ?
|
||||
mObject->_class->removeProperty(mObject, id) :
|
||||
true;
|
||||
|
@ -919,7 +1036,7 @@ PluginScriptableObjectChild::AnswerRemoveProperty(PPluginIdentifierChild* aId,
|
|||
}
|
||||
|
||||
bool
|
||||
PluginScriptableObjectChild::AnswerEnumerate(InfallibleTArray<PPluginIdentifierChild*>* aProperties,
|
||||
PluginScriptableObjectChild::AnswerEnumerate(InfallibleTArray<PluginIdentifier>* aProperties,
|
||||
bool* aSuccess)
|
||||
{
|
||||
AssertPluginThread();
|
||||
|
@ -948,8 +1065,7 @@ PluginScriptableObjectChild::AnswerEnumerate(InfallibleTArray<PPluginIdentifierC
|
|||
aProperties->SetCapacity(idCount);
|
||||
|
||||
for (uint32_t index = 0; index < idCount; index++) {
|
||||
PluginIdentifierChild* id = static_cast<PluginIdentifierChild*>(ids[index]);
|
||||
aProperties->AppendElement(id);
|
||||
aProperties->AppendElement(FromNPIdentifier(ids[index]));
|
||||
}
|
||||
|
||||
PluginModuleChild::sBrowserFuncs.memfree(ids);
|
||||
|
|
|
@ -9,15 +9,16 @@
|
|||
|
||||
#include "mozilla/plugins/PPluginScriptableObjectChild.h"
|
||||
#include "mozilla/plugins/PluginMessageUtils.h"
|
||||
#include "mozilla/plugins/PluginTypes.h"
|
||||
|
||||
#include "npruntime.h"
|
||||
#include "nsDataHashtable.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace plugins {
|
||||
|
||||
class PluginInstanceChild;
|
||||
class PluginScriptableObjectChild;
|
||||
class PPluginIdentifierChild;
|
||||
|
||||
struct ChildNPObject : NPObject
|
||||
{
|
||||
|
@ -57,11 +58,11 @@ public:
|
|||
AnswerInvalidate() MOZ_OVERRIDE;
|
||||
|
||||
virtual bool
|
||||
AnswerHasMethod(PPluginIdentifierChild* aId,
|
||||
AnswerHasMethod(const PluginIdentifier& aId,
|
||||
bool* aHasMethod) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool
|
||||
AnswerInvoke(PPluginIdentifierChild* aId,
|
||||
AnswerInvoke(const PluginIdentifier& aId,
|
||||
const InfallibleTArray<Variant>& aArgs,
|
||||
Variant* aResult,
|
||||
bool* aSuccess) MOZ_OVERRIDE;
|
||||
|
@ -72,27 +73,27 @@ public:
|
|||
bool* aSuccess) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool
|
||||
AnswerHasProperty(PPluginIdentifierChild* aId,
|
||||
AnswerHasProperty(const PluginIdentifier& aId,
|
||||
bool* aHasProperty) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool
|
||||
AnswerGetChildProperty(PPluginIdentifierChild* aId,
|
||||
AnswerGetChildProperty(const PluginIdentifier& aId,
|
||||
bool* aHasProperty,
|
||||
bool* aHasMethod,
|
||||
Variant* aResult,
|
||||
bool* aSuccess) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool
|
||||
AnswerSetProperty(PPluginIdentifierChild* aId,
|
||||
AnswerSetProperty(const PluginIdentifier& aId,
|
||||
const Variant& aValue,
|
||||
bool* aSuccess) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool
|
||||
AnswerRemoveProperty(PPluginIdentifierChild* aId,
|
||||
AnswerRemoveProperty(const PluginIdentifier& aId,
|
||||
bool* aSuccess) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool
|
||||
AnswerEnumerate(InfallibleTArray<PPluginIdentifierChild*>* aProperties,
|
||||
AnswerEnumerate(InfallibleTArray<PluginIdentifier>* aProperties,
|
||||
bool* aSuccess) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool
|
||||
|
@ -156,6 +157,66 @@ public:
|
|||
return mType;
|
||||
}
|
||||
|
||||
private:
|
||||
struct StoredIdentifier
|
||||
{
|
||||
nsCString mIdentifier;
|
||||
nsAutoRefCnt mRefCnt;
|
||||
bool mPermanent;
|
||||
|
||||
nsrefcnt AddRef() {
|
||||
++mRefCnt;
|
||||
return mRefCnt;
|
||||
}
|
||||
|
||||
nsrefcnt Release() {
|
||||
--mRefCnt;
|
||||
if (mRefCnt == 0) {
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
return mRefCnt;
|
||||
}
|
||||
|
||||
explicit StoredIdentifier(const nsCString& aIdentifier)
|
||||
: mIdentifier(aIdentifier), mRefCnt(), mPermanent(false)
|
||||
{ MOZ_COUNT_CTOR(StoredIdentifier); }
|
||||
|
||||
~StoredIdentifier() { MOZ_COUNT_DTOR(StoredIdentifier); }
|
||||
};
|
||||
|
||||
public:
|
||||
class MOZ_STACK_CLASS StackIdentifier
|
||||
{
|
||||
public:
|
||||
StackIdentifier(const PluginIdentifier& aIdentifier);
|
||||
StackIdentifier(NPIdentifier aIdentifier);
|
||||
~StackIdentifier();
|
||||
|
||||
void MakePermanent()
|
||||
{
|
||||
if (mStored) {
|
||||
mStored->mPermanent = true;
|
||||
}
|
||||
}
|
||||
NPIdentifier ToNPIdentifier() const;
|
||||
|
||||
bool IsString() const { return mIdentifier.type() == PluginIdentifier::TnsCString; }
|
||||
const nsCString& GetString() const { return mIdentifier.get_nsCString(); }
|
||||
|
||||
int32_t GetInt() const { return mIdentifier.get_int32_t(); }
|
||||
|
||||
PluginIdentifier GetIdentifier() const { return mIdentifier; }
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(StackIdentifier);
|
||||
|
||||
PluginIdentifier mIdentifier;
|
||||
nsRefPtr<StoredIdentifier> mStored;
|
||||
};
|
||||
|
||||
static void ClearIdentifiers();
|
||||
|
||||
private:
|
||||
static NPObject*
|
||||
ScriptableAllocate(NPP aInstance,
|
||||
|
@ -230,6 +291,12 @@ private:
|
|||
ScriptableObjectType mType;
|
||||
|
||||
static const NPClass sNPClass;
|
||||
|
||||
static StoredIdentifier* HashIdentifier(const nsCString& aIdentifier);
|
||||
static void UnhashIdentifier(StoredIdentifier* aIdentifier);
|
||||
|
||||
typedef nsDataHashtable<nsCStringHashKey, nsRefPtr<StoredIdentifier>> IdentifierTable;
|
||||
static IdentifierTable sIdentifiers;
|
||||
};
|
||||
|
||||
} /* namespace plugins */
|
||||
|
|
|
@ -6,15 +6,103 @@
|
|||
|
||||
#include "PluginScriptableObjectParent.h"
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/plugins/PluginIdentifierParent.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "mozilla/plugins/PluginTypes.h"
|
||||
#include "mozilla/unused.h"
|
||||
#include "nsNPAPIPlugin.h"
|
||||
#include "PluginScriptableObjectUtils.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::plugins;
|
||||
using namespace mozilla::plugins::parent;
|
||||
|
||||
/**
|
||||
* NPIdentifiers in the chrome process are stored as jsids. The difficulty is in
|
||||
* ensuring that string identifiers are rooted without interning them all. We
|
||||
* assume that all NPIdentifiers passed into nsJSNPRuntime will not be used
|
||||
* outside the scope of the NPAPI call (i.e., they won't be stored in the
|
||||
* heap). Rooting is done using the StackIdentifier class, which roots the
|
||||
* identifier via RootedId.
|
||||
*
|
||||
* This system does not allow jsids to be moved, as would be needed for
|
||||
* generational or compacting GC. When Firefox implements a moving GC for
|
||||
* strings, we will need to ensure that no movement happens while NPAPI code is
|
||||
* on the stack: although StackIdentifier roots all identifiers used, the GC has
|
||||
* no way to no that a jsid cast to an NPIdentifier needs to be fixed up if it
|
||||
* is moved.
|
||||
*/
|
||||
|
||||
class MOZ_STACK_CLASS StackIdentifier
|
||||
{
|
||||
public:
|
||||
StackIdentifier(const PluginIdentifier& aIdentifier, bool aIntern = false);
|
||||
|
||||
bool Failed() const { return mFailed; }
|
||||
NPIdentifier ToNPIdentifier() const { return mIdentifier; }
|
||||
|
||||
private:
|
||||
bool mFailed;
|
||||
NPIdentifier mIdentifier;
|
||||
AutoSafeJSContext mCx;
|
||||
JS::RootedId mId;
|
||||
};
|
||||
|
||||
StackIdentifier::StackIdentifier(const PluginIdentifier& aIdentifier, bool aIntern)
|
||||
: mFailed(false),
|
||||
mId(mCx)
|
||||
{
|
||||
if (aIdentifier.type() == PluginIdentifier::TnsCString) {
|
||||
// We don't call _getstringidentifier because we may not want to intern the string.
|
||||
NS_ConvertUTF8toUTF16 utf16name(aIdentifier.get_nsCString());
|
||||
JS::RootedString str(mCx, JS_NewUCStringCopyN(mCx, utf16name.get(), utf16name.Length()));
|
||||
if (!str) {
|
||||
NS_ERROR("Id can't be allocated");
|
||||
mFailed = true;
|
||||
return;
|
||||
}
|
||||
if (aIntern) {
|
||||
str = JS_InternJSString(mCx, str);
|
||||
if (!str) {
|
||||
NS_ERROR("Id can't be allocated");
|
||||
mFailed = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!JS_StringToId(mCx, str, &mId)) {
|
||||
NS_ERROR("Id can't be allocated");
|
||||
mFailed = true;
|
||||
return;
|
||||
}
|
||||
mIdentifier = JSIdToNPIdentifier(mId);
|
||||
return;
|
||||
}
|
||||
|
||||
mIdentifier = mozilla::plugins::parent::_getintidentifier(aIdentifier.get_int32_t());
|
||||
}
|
||||
|
||||
static bool
|
||||
FromNPIdentifier(NPIdentifier aIdentifier, PluginIdentifier* aResult)
|
||||
{
|
||||
if (mozilla::plugins::parent::_identifierisstring(aIdentifier)) {
|
||||
nsCString string;
|
||||
NPUTF8* chars =
|
||||
mozilla::plugins::parent::_utf8fromidentifier(aIdentifier);
|
||||
if (!chars) {
|
||||
return false;
|
||||
}
|
||||
string.Adopt(chars);
|
||||
*aResult = PluginIdentifier(string);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
int32_t intval = mozilla::plugins::parent::_intfromidentifier(aIdentifier);
|
||||
*aResult = PluginIdentifier(intval);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
inline void
|
||||
|
@ -105,8 +193,8 @@ PluginScriptableObjectParent::ScriptableHasMethod(NPObject* aObject,
|
|||
return false;
|
||||
}
|
||||
|
||||
PluginIdentifierParent::StackIdentifier identifier(aObject, aName);
|
||||
if (!identifier) {
|
||||
PluginIdentifier identifier;
|
||||
if (!FromNPIdentifier(aName, &identifier)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -145,8 +233,8 @@ PluginScriptableObjectParent::ScriptableInvoke(NPObject* aObject,
|
|||
return false;
|
||||
}
|
||||
|
||||
PluginIdentifierParent::StackIdentifier identifier(aObject, aName);
|
||||
if (!identifier) {
|
||||
PluginIdentifier identifier;
|
||||
if (!FromNPIdentifier(aName, &identifier)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -247,8 +335,8 @@ PluginScriptableObjectParent::ScriptableHasProperty(NPObject* aObject,
|
|||
return false;
|
||||
}
|
||||
|
||||
PluginIdentifierParent::StackIdentifier identifier(aObject, aName);
|
||||
if (!identifier) {
|
||||
PluginIdentifier identifier;
|
||||
if (!FromNPIdentifier(aName, &identifier)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -296,8 +384,8 @@ PluginScriptableObjectParent::ScriptableSetProperty(NPObject* aObject,
|
|||
return false;
|
||||
}
|
||||
|
||||
PluginIdentifierParent::StackIdentifier identifier(aObject, aName);
|
||||
if (!identifier) {
|
||||
PluginIdentifier identifier;
|
||||
if (!FromNPIdentifier(aName, &identifier)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -339,8 +427,8 @@ PluginScriptableObjectParent::ScriptableRemoveProperty(NPObject* aObject,
|
|||
return false;
|
||||
}
|
||||
|
||||
PluginIdentifierParent::StackIdentifier identifier(aObject, aName);
|
||||
if (!identifier) {
|
||||
PluginIdentifier identifier;
|
||||
if (!FromNPIdentifier(aName, &identifier)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -385,7 +473,7 @@ PluginScriptableObjectParent::ScriptableEnumerate(NPObject* aObject,
|
|||
return false;
|
||||
}
|
||||
|
||||
AutoInfallibleTArray<PPluginIdentifierParent*, 10> identifiers;
|
||||
AutoInfallibleTArray<PluginIdentifier, 10> identifiers;
|
||||
bool success;
|
||||
if (!actor->CallEnumerate(&identifiers, &success)) {
|
||||
NS_WARNING("Failed to send message!");
|
||||
|
@ -409,9 +497,13 @@ PluginScriptableObjectParent::ScriptableEnumerate(NPObject* aObject,
|
|||
}
|
||||
|
||||
for (uint32_t index = 0; index < *aCount; index++) {
|
||||
PluginIdentifierParent* id =
|
||||
static_cast<PluginIdentifierParent*>(identifiers[index]);
|
||||
(*aIdentifiers)[index] = id->ToNPIdentifier();
|
||||
// We intern the ID to avoid a GC hazard here. This could probably be fixed
|
||||
// if the interface with nsJSNPRuntime were smarter.
|
||||
StackIdentifier stackID(identifiers[index], true /* aIntern */);
|
||||
if (stackID.Failed()) {
|
||||
return false;
|
||||
}
|
||||
(*aIdentifiers)[index] = stackID.ToNPIdentifier();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -649,7 +741,7 @@ PluginScriptableObjectParent::ActorDestroy(ActorDestroyReason aWhy)
|
|||
}
|
||||
|
||||
bool
|
||||
PluginScriptableObjectParent::AnswerHasMethod(PPluginIdentifierParent* aId,
|
||||
PluginScriptableObjectParent::AnswerHasMethod(const PluginIdentifier& aId,
|
||||
bool* aHasMethod)
|
||||
{
|
||||
if (!mObject) {
|
||||
|
@ -675,13 +767,17 @@ PluginScriptableObjectParent::AnswerHasMethod(PPluginIdentifierParent* aId,
|
|||
return true;
|
||||
}
|
||||
|
||||
PluginIdentifierParent* id = static_cast<PluginIdentifierParent*>(aId);
|
||||
*aHasMethod = npn->hasmethod(instance->GetNPP(), mObject, id->ToNPIdentifier());
|
||||
StackIdentifier stackID(aId);
|
||||
if (stackID.Failed()) {
|
||||
*aHasMethod = false;
|
||||
return true;
|
||||
}
|
||||
*aHasMethod = npn->hasmethod(instance->GetNPP(), mObject, stackID.ToNPIdentifier());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
PluginScriptableObjectParent::AnswerInvoke(PPluginIdentifierParent* aId,
|
||||
PluginScriptableObjectParent::AnswerInvoke(const PluginIdentifier& aId,
|
||||
const InfallibleTArray<Variant>& aArgs,
|
||||
Variant* aResult,
|
||||
bool* aSuccess)
|
||||
|
@ -712,6 +808,13 @@ PluginScriptableObjectParent::AnswerInvoke(PPluginIdentifierParent* aId,
|
|||
return true;
|
||||
}
|
||||
|
||||
StackIdentifier stackID(aId);
|
||||
if (stackID.Failed()) {
|
||||
*aResult = void_t();
|
||||
*aSuccess = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
AutoFallibleTArray<NPVariant, 10> convertedArgs;
|
||||
uint32_t argCount = aArgs.Length();
|
||||
|
||||
|
@ -733,9 +836,8 @@ PluginScriptableObjectParent::AnswerInvoke(PPluginIdentifierParent* aId,
|
|||
}
|
||||
}
|
||||
|
||||
PluginIdentifierParent* id = static_cast<PluginIdentifierParent*>(aId);
|
||||
NPVariant result;
|
||||
bool success = npn->invoke(instance->GetNPP(), mObject, id->ToNPIdentifier(),
|
||||
bool success = npn->invoke(instance->GetNPP(), mObject, stackID.ToNPIdentifier(),
|
||||
convertedArgs.Elements(), argCount, &result);
|
||||
|
||||
for (uint32_t index = 0; index < argCount; index++) {
|
||||
|
@ -848,7 +950,7 @@ PluginScriptableObjectParent::AnswerInvokeDefault(const InfallibleTArray<Variant
|
|||
}
|
||||
|
||||
bool
|
||||
PluginScriptableObjectParent::AnswerHasProperty(PPluginIdentifierParent* aId,
|
||||
PluginScriptableObjectParent::AnswerHasProperty(const PluginIdentifier& aId,
|
||||
bool* aHasProperty)
|
||||
{
|
||||
if (!mObject) {
|
||||
|
@ -874,15 +976,20 @@ PluginScriptableObjectParent::AnswerHasProperty(PPluginIdentifierParent* aId,
|
|||
return true;
|
||||
}
|
||||
|
||||
PluginIdentifierParent* id = static_cast<PluginIdentifierParent*>(aId);
|
||||
StackIdentifier stackID(aId);
|
||||
if (stackID.Failed()) {
|
||||
*aHasProperty = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
*aHasProperty = npn->hasproperty(instance->GetNPP(), mObject,
|
||||
id->ToNPIdentifier());
|
||||
stackID.ToNPIdentifier());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
PluginScriptableObjectParent::AnswerGetParentProperty(
|
||||
PPluginIdentifierParent* aId,
|
||||
const PluginIdentifier& aId,
|
||||
Variant* aResult,
|
||||
bool* aSuccess)
|
||||
{
|
||||
|
@ -912,9 +1019,15 @@ PluginScriptableObjectParent::AnswerGetParentProperty(
|
|||
return true;
|
||||
}
|
||||
|
||||
PluginIdentifierParent* id = static_cast<PluginIdentifierParent*>(aId);
|
||||
StackIdentifier stackID(aId);
|
||||
if (stackID.Failed()) {
|
||||
*aResult = void_t();
|
||||
*aSuccess = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
NPVariant result;
|
||||
if (!npn->getproperty(instance->GetNPP(), mObject, id->ToNPIdentifier(),
|
||||
if (!npn->getproperty(instance->GetNPP(), mObject, stackID.ToNPIdentifier(),
|
||||
&result)) {
|
||||
*aResult = void_t();
|
||||
*aSuccess = false;
|
||||
|
@ -934,7 +1047,7 @@ PluginScriptableObjectParent::AnswerGetParentProperty(
|
|||
}
|
||||
|
||||
bool
|
||||
PluginScriptableObjectParent::AnswerSetProperty(PPluginIdentifierParent* aId,
|
||||
PluginScriptableObjectParent::AnswerSetProperty(const PluginIdentifier& aId,
|
||||
const Variant& aValue,
|
||||
bool* aSuccess)
|
||||
{
|
||||
|
@ -967,16 +1080,21 @@ PluginScriptableObjectParent::AnswerSetProperty(PPluginIdentifierParent* aId,
|
|||
return true;
|
||||
}
|
||||
|
||||
PluginIdentifierParent* id = static_cast<PluginIdentifierParent*>(aId);
|
||||
StackIdentifier stackID(aId);
|
||||
if (stackID.Failed()) {
|
||||
*aSuccess = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((*aSuccess = npn->setproperty(instance->GetNPP(), mObject,
|
||||
id->ToNPIdentifier(), &converted))) {
|
||||
stackID.ToNPIdentifier(), &converted))) {
|
||||
ReleaseVariant(converted, instance);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
PluginScriptableObjectParent::AnswerRemoveProperty(PPluginIdentifierParent* aId,
|
||||
PluginScriptableObjectParent::AnswerRemoveProperty(const PluginIdentifier& aId,
|
||||
bool* aSuccess)
|
||||
{
|
||||
if (!mObject) {
|
||||
|
@ -1002,14 +1120,19 @@ PluginScriptableObjectParent::AnswerRemoveProperty(PPluginIdentifierParent* aId,
|
|||
return true;
|
||||
}
|
||||
|
||||
PluginIdentifierParent* id = static_cast<PluginIdentifierParent*>(aId);
|
||||
StackIdentifier stackID(aId);
|
||||
if (stackID.Failed()) {
|
||||
*aSuccess = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
*aSuccess = npn->removeproperty(instance->GetNPP(), mObject,
|
||||
id->ToNPIdentifier());
|
||||
stackID.ToNPIdentifier());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
PluginScriptableObjectParent::AnswerEnumerate(InfallibleTArray<PPluginIdentifierParent*>* aProperties,
|
||||
PluginScriptableObjectParent::AnswerEnumerate(InfallibleTArray<PluginIdentifier>* aProperties,
|
||||
bool* aSuccess)
|
||||
{
|
||||
if (!mObject) {
|
||||
|
@ -1044,21 +1167,12 @@ PluginScriptableObjectParent::AnswerEnumerate(InfallibleTArray<PPluginIdentifier
|
|||
|
||||
aProperties->SetCapacity(idCount);
|
||||
|
||||
mozilla::AutoSafeJSContext cx;
|
||||
for (uint32_t index = 0; index < idCount; index++) {
|
||||
// Because of GC hazards, all identifiers returned from enumerate
|
||||
// must be made permanent.
|
||||
if (_identifierisstring(ids[index])) {
|
||||
JS::Rooted<JSString*> str(cx, NPIdentifierToString(ids[index]));
|
||||
if (!JS_StringHasBeenInterned(cx, str)) {
|
||||
DebugOnly<JSString*> str2 = JS_InternJSString(cx, str);
|
||||
NS_ASSERTION(str2 == str, "Interning a JS string which is currently an ID should return itself.");
|
||||
}
|
||||
PluginIdentifier id;
|
||||
if (!FromNPIdentifier(ids[index], &id)) {
|
||||
return false;
|
||||
}
|
||||
PluginIdentifierParent* id =
|
||||
instance->Module()->GetIdentifierForNPIdentifier(instance->GetNPP(), ids[index]);
|
||||
aProperties->AppendElement(id);
|
||||
NS_ASSERTION(!id->IsTemporary(), "Should only have permanent identifiers!");
|
||||
}
|
||||
|
||||
npn->memfree(ids);
|
||||
|
@ -1229,8 +1343,8 @@ PluginScriptableObjectParent::GetPropertyHelper(NPIdentifier aName,
|
|||
return false;
|
||||
}
|
||||
|
||||
PluginIdentifierParent::StackIdentifier identifier(GetInstance(), aName);
|
||||
if (!identifier) {
|
||||
PluginIdentifier identifier;
|
||||
if (!FromNPIdentifier(aName, &identifier)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@ namespace plugins {
|
|||
|
||||
class PluginInstanceParent;
|
||||
class PluginScriptableObjectParent;
|
||||
class PPluginIdentifierParent;
|
||||
|
||||
struct ParentNPObject : NPObject
|
||||
{
|
||||
|
@ -49,11 +48,11 @@ public:
|
|||
ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool
|
||||
AnswerHasMethod(PPluginIdentifierParent* aId,
|
||||
AnswerHasMethod(const PluginIdentifier& aId,
|
||||
bool* aHasMethod) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool
|
||||
AnswerInvoke(PPluginIdentifierParent* aId,
|
||||
AnswerInvoke(const PluginIdentifier& aId,
|
||||
const InfallibleTArray<Variant>& aArgs,
|
||||
Variant* aResult,
|
||||
bool* aSuccess) MOZ_OVERRIDE;
|
||||
|
@ -64,25 +63,25 @@ public:
|
|||
bool* aSuccess) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool
|
||||
AnswerHasProperty(PPluginIdentifierParent* aId,
|
||||
AnswerHasProperty(const PluginIdentifier& aId,
|
||||
bool* aHasProperty) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool
|
||||
AnswerGetParentProperty(PPluginIdentifierParent* aId,
|
||||
AnswerGetParentProperty(const PluginIdentifier& aId,
|
||||
Variant* aResult,
|
||||
bool* aSuccess) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool
|
||||
AnswerSetProperty(PPluginIdentifierParent* aId,
|
||||
AnswerSetProperty(const PluginIdentifier& aId,
|
||||
const Variant& aValue,
|
||||
bool* aSuccess) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool
|
||||
AnswerRemoveProperty(PPluginIdentifierParent* aId,
|
||||
AnswerRemoveProperty(const PluginIdentifier& aId,
|
||||
bool* aSuccess) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool
|
||||
AnswerEnumerate(InfallibleTArray<PPluginIdentifierParent*>* aProperties,
|
||||
AnswerEnumerate(InfallibleTArray<PluginIdentifier>* aProperties,
|
||||
bool* aSuccess) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
namespace mozilla {
|
||||
namespace plugins {
|
||||
|
||||
union PluginIdentifier
|
||||
{
|
||||
nsCString;
|
||||
int32_t;
|
||||
};
|
||||
|
||||
} // namespace plugins
|
||||
} // namespace mozilla
|
|
@ -21,8 +21,6 @@ EXPORTS.mozilla.plugins += [
|
|||
'NPEventOSX.h',
|
||||
'NPEventUnix.h',
|
||||
'NPEventWindows.h',
|
||||
'PluginIdentifierChild.h',
|
||||
'PluginIdentifierParent.h',
|
||||
'PluginInstanceChild.h',
|
||||
'PluginInstanceParent.h',
|
||||
'PluginMessageUtils.h',
|
||||
|
@ -79,8 +77,6 @@ UNIFIED_SOURCES += [
|
|||
'ChildAsyncCall.cpp',
|
||||
'ChildTimer.cpp',
|
||||
'PluginBackgroundDestroyer.cpp',
|
||||
'PluginIdentifierChild.cpp',
|
||||
'PluginIdentifierParent.cpp',
|
||||
'PluginInstanceParent.cpp',
|
||||
'PluginMessageUtils.cpp',
|
||||
'PluginModuleParent.cpp',
|
||||
|
@ -105,8 +101,8 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
|||
|
||||
IPDL_SOURCES += [
|
||||
'PBrowserStream.ipdl',
|
||||
'PluginTypes.ipdlh',
|
||||
'PPluginBackgroundDestroyer.ipdl',
|
||||
'PPluginIdentifier.ipdl',
|
||||
'PPluginInstance.ipdl',
|
||||
'PPluginModule.ipdl',
|
||||
'PPluginScriptableObject.ipdl',
|
||||
|
|
Загрузка…
Ссылка в новой задаче