зеркало из https://github.com/mozilla/gecko-dev.git
Implement CPOW support in MessageManager (bug 870180, r=smaug,billm).
This commit is contained in:
Родитель
614d2bf88c
Коммит
5f0258f3c3
|
@ -162,9 +162,8 @@ interface nsIMessageListener : nsISupports
|
|||
* sync: %true or false%.
|
||||
* data: %structured clone of the sent message data%,
|
||||
* json: %same as .data, deprecated%,
|
||||
* objects: %array of handles or null, always null if sync is false%
|
||||
* objects: %named table of jsvals/objects, or null%
|
||||
* }
|
||||
* @note objects property isn't implemented yet.
|
||||
*
|
||||
* Each listener is invoked with its own copy of the message
|
||||
* parameter.
|
||||
|
@ -232,7 +231,8 @@ interface nsIMessageSender : nsIMessageListenerManager
|
|||
*/
|
||||
[implicit_jscontext, optional_argc]
|
||||
void sendAsyncMessage([optional] in AString messageName,
|
||||
[optional] in jsval obj);
|
||||
[optional] in jsval obj,
|
||||
[optional] in jsval objects);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -255,7 +255,8 @@ interface nsIMessageBroadcaster : nsIMessageListenerManager
|
|||
*/
|
||||
[implicit_jscontext, optional_argc]
|
||||
void broadcastAsyncMessage([optional] in AString messageName,
|
||||
[optional] in jsval obj);
|
||||
[optional] in jsval obj,
|
||||
[optional] in jsval objects);
|
||||
|
||||
/**
|
||||
* Number of subordinate message managers.
|
||||
|
@ -278,7 +279,8 @@ interface nsISyncMessageSender : nsIMessageSender
|
|||
*/
|
||||
[implicit_jscontext, optional_argc]
|
||||
jsval sendSyncMessage([optional] in AString messageName,
|
||||
[optional] in jsval obj);
|
||||
[optional] in jsval obj,
|
||||
[optional] in jsval objects);
|
||||
};
|
||||
|
||||
[scriptable, builtinclass, uuid(894ff2d4-39a3-4df8-9d76-8ee329975488)]
|
||||
|
|
|
@ -50,6 +50,7 @@ LOCAL_INCLUDES += \
|
|||
-I$(topsrcdir)/content/xul/document/src \
|
||||
-I$(topsrcdir)/dom/base \
|
||||
-I$(topsrcdir)/dom/ipc \
|
||||
-I$(topsrcdir)/js/ipc \
|
||||
-I$(topsrcdir)/image/src \
|
||||
-I$(topsrcdir)/js/xpconnect/src \
|
||||
-I$(topsrcdir)/layout/base \
|
||||
|
|
|
@ -87,6 +87,7 @@
|
|||
#include "jsapi.h"
|
||||
#include "mozilla/dom/HTMLIFrameElement.h"
|
||||
#include "nsSandboxFlags.h"
|
||||
#include "JavaScriptParent.h"
|
||||
|
||||
#include "mozilla/dom/StructuredCloneUtils.h"
|
||||
|
||||
|
@ -2202,17 +2203,29 @@ nsFrameLoader::DoLoadFrameScript(const nsAString& aURL)
|
|||
class nsAsyncMessageToChild : public nsRunnable
|
||||
{
|
||||
public:
|
||||
nsAsyncMessageToChild(nsFrameLoader* aFrameLoader,
|
||||
nsAsyncMessageToChild(JSContext* aCx,
|
||||
nsFrameLoader* aFrameLoader,
|
||||
const nsAString& aMessage,
|
||||
const StructuredCloneData& aData)
|
||||
: mFrameLoader(aFrameLoader), mMessage(aMessage)
|
||||
const StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows)
|
||||
: mRuntime(js::GetRuntime(aCx)), mFrameLoader(aFrameLoader), mMessage(aMessage), mCpows(aCpows)
|
||||
{
|
||||
if (aData.mDataLength && !mData.copy(aData.mData, aData.mDataLength)) {
|
||||
NS_RUNTIMEABORT("OOM");
|
||||
}
|
||||
if (mCpows && !js_AddObjectRoot(mRuntime, &mCpows)) {
|
||||
NS_RUNTIMEABORT("OOM");
|
||||
}
|
||||
mClosure = aData.mClosure;
|
||||
}
|
||||
|
||||
~nsAsyncMessageToChild()
|
||||
{
|
||||
if (mCpows) {
|
||||
JS_RemoveObjectRootRT(mRuntime, &mCpows);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
nsInProcessTabChildGlobal* tabChild =
|
||||
|
@ -2224,21 +2237,27 @@ public:
|
|||
data.mDataLength = mData.nbytes();
|
||||
data.mClosure = mClosure;
|
||||
|
||||
SameProcessCpowHolder cpows(mRuntime, JS::Handle<JSObject *>::fromMarkedLocation(&mCpows));
|
||||
|
||||
nsRefPtr<nsFrameMessageManager> mm = tabChild->GetInnerManager();
|
||||
mm->ReceiveMessage(static_cast<EventTarget*>(tabChild), mMessage,
|
||||
false, &data, JS::NullPtr(), nullptr);
|
||||
false, &data, &cpows, nullptr);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
JSRuntime* mRuntime;
|
||||
nsRefPtr<nsFrameLoader> mFrameLoader;
|
||||
nsString mMessage;
|
||||
JSAutoStructuredCloneBuffer mData;
|
||||
StructuredCloneClosure mClosure;
|
||||
JSObject* mCpows;
|
||||
};
|
||||
|
||||
bool
|
||||
nsFrameLoader::DoSendAsyncMessage(const nsAString& aMessage,
|
||||
const StructuredCloneData& aData)
|
||||
nsFrameLoader::DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows)
|
||||
{
|
||||
TabParent* tabParent = mRemoteBrowser;
|
||||
if (tabParent) {
|
||||
|
@ -2247,11 +2266,15 @@ nsFrameLoader::DoSendAsyncMessage(const nsAString& aMessage,
|
|||
if (!BuildClonedMessageDataForParent(cp, aData, data)) {
|
||||
return false;
|
||||
}
|
||||
return tabParent->SendAsyncMessage(nsString(aMessage), data);
|
||||
InfallibleTArray<mozilla::jsipc::CpowEntry> cpows;
|
||||
if (aCpows && !cp->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
|
||||
return false;
|
||||
}
|
||||
return tabParent->SendAsyncMessage(nsString(aMessage), data, cpows);
|
||||
}
|
||||
|
||||
if (mChildMessageManager) {
|
||||
nsRefPtr<nsIRunnable> ev = new nsAsyncMessageToChild(this, aMessage, aData);
|
||||
nsRefPtr<nsIRunnable> ev = new nsAsyncMessageToChild(aCx, this, aMessage, aData, aCpows);
|
||||
NS_DispatchToCurrentThread(ev);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -186,8 +186,10 @@ public:
|
|||
* MessageManagerCallback methods that we override.
|
||||
*/
|
||||
virtual bool DoLoadFrameScript(const nsAString& aURL) MOZ_OVERRIDE;
|
||||
virtual bool DoSendAsyncMessage(const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData) MOZ_OVERRIDE;
|
||||
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows);
|
||||
virtual bool CheckPermission(const nsAString& aPermission) MOZ_OVERRIDE;
|
||||
virtual bool CheckManifestURL(const nsAString& aManifestURL) MOZ_OVERRIDE;
|
||||
virtual bool CheckAppHasPermission(const nsAString& aPermission) MOZ_OVERRIDE;
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
#include "xpcpublic.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/dom/StructuredCloneUtils.h"
|
||||
#include "JavaScriptChild.h"
|
||||
#include "JavaScriptParent.h"
|
||||
#include <algorithm>
|
||||
|
||||
#ifdef ANDROID
|
||||
|
@ -220,6 +222,18 @@ mozilla::dom::ipc::UnpackClonedMessageDataForChild(const ClonedMessageData& aDat
|
|||
return UnpackClonedMessageData<Child>(aData);
|
||||
}
|
||||
|
||||
bool
|
||||
SameProcessCpowHolder::ToObject(JSContext* aCx, JSObject** aObjp)
|
||||
{
|
||||
*aObjp = mObj;
|
||||
|
||||
if (!mObj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return JS_WrapObject(aCx, aObjp);
|
||||
}
|
||||
|
||||
// nsIMessageListenerManager
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -311,11 +325,11 @@ JSONCreator(const jschar* aBuf, uint32_t aLen, void* aData)
|
|||
|
||||
static bool
|
||||
GetParamsForMessage(JSContext* aCx,
|
||||
const JS::Value& aObject,
|
||||
const JS::Value& aJSON,
|
||||
JSAutoStructuredCloneBuffer& aBuffer,
|
||||
StructuredCloneClosure& aClosure)
|
||||
{
|
||||
if (WriteStructuredClone(aCx, aObject, aBuffer, aClosure)) {
|
||||
if (WriteStructuredClone(aCx, aJSON, aBuffer, aClosure)) {
|
||||
return true;
|
||||
}
|
||||
JS_ClearPendingException(aCx);
|
||||
|
@ -325,7 +339,7 @@ GetParamsForMessage(JSContext* aCx,
|
|||
// properly cases when interface is implemented in JS and used
|
||||
// as a dictionary.
|
||||
nsAutoString json;
|
||||
JS::Rooted<JS::Value> v(aCx, aObject);
|
||||
JS::Rooted<JS::Value> v(aCx, aJSON);
|
||||
NS_ENSURE_TRUE(JS_Stringify(aCx, v.address(), nullptr, JSVAL_NULL,
|
||||
JSONCreator, &json), false);
|
||||
NS_ENSURE_TRUE(!json.IsEmpty(), false);
|
||||
|
@ -342,7 +356,8 @@ GetParamsForMessage(JSContext* aCx,
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsFrameMessageManager::SendSyncMessage(const nsAString& aMessageName,
|
||||
const JS::Value& aObject,
|
||||
const JS::Value& aJSON,
|
||||
const JS::Value& aObjects,
|
||||
JSContext* aCx,
|
||||
uint8_t aArgc,
|
||||
JS::Value* aRetval)
|
||||
|
@ -357,14 +372,19 @@ nsFrameMessageManager::SendSyncMessage(const nsAString& aMessageName,
|
|||
StructuredCloneData data;
|
||||
JSAutoStructuredCloneBuffer buffer;
|
||||
if (aArgc >= 2 &&
|
||||
!GetParamsForMessage(aCx, aObject, buffer, data.mClosure)) {
|
||||
!GetParamsForMessage(aCx, aJSON, buffer, data.mClosure)) {
|
||||
return NS_ERROR_DOM_DATA_CLONE_ERR;
|
||||
}
|
||||
data.mData = buffer.data();
|
||||
data.mDataLength = buffer.nbytes();
|
||||
|
||||
JS::RootedObject objects(aCx);
|
||||
if (aArgc >= 3 && aObjects.isObject()) {
|
||||
objects = &aObjects.toObject();
|
||||
}
|
||||
|
||||
InfallibleTArray<nsString> retval;
|
||||
if (mCallback->DoSendSyncMessage(aMessageName, data, &retval)) {
|
||||
if (mCallback->DoSendSyncMessage(aCx, aMessageName, data, objects, &retval)) {
|
||||
uint32_t len = retval.Length();
|
||||
JS::Rooted<JSObject*> dataArray(aCx, JS_NewArrayObject(aCx, len, nullptr));
|
||||
NS_ENSURE_TRUE(dataArray, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
@ -389,20 +409,22 @@ nsFrameMessageManager::SendSyncMessage(const nsAString& aMessageName,
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsFrameMessageManager::DispatchAsyncMessageInternal(const nsAString& aMessage,
|
||||
const StructuredCloneData& aData)
|
||||
nsFrameMessageManager::DispatchAsyncMessageInternal(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows)
|
||||
{
|
||||
if (mIsBroadcaster) {
|
||||
int32_t len = mChildManagers.Count();
|
||||
for (int32_t i = 0; i < len; ++i) {
|
||||
static_cast<nsFrameMessageManager*>(mChildManagers[i])->
|
||||
DispatchAsyncMessageInternal(aMessage, aData);
|
||||
DispatchAsyncMessageInternal(aCx, aMessage, aData, aCpows);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_ENSURE_TRUE(mCallback, NS_ERROR_NOT_INITIALIZED);
|
||||
if (!mCallback->DoSendAsyncMessage(aMessage, aData)) {
|
||||
if (!mCallback->DoSendAsyncMessage(aCx, aMessage, aData, aCpows)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return NS_OK;
|
||||
|
@ -410,7 +432,8 @@ nsFrameMessageManager::DispatchAsyncMessageInternal(const nsAString& aMessage,
|
|||
|
||||
nsresult
|
||||
nsFrameMessageManager::DispatchAsyncMessage(const nsAString& aMessageName,
|
||||
const JS::Value& aObject,
|
||||
const JS::Value& aJSON,
|
||||
const JS::Value& aObjects,
|
||||
JSContext* aCx,
|
||||
uint8_t aArgc)
|
||||
{
|
||||
|
@ -418,14 +441,19 @@ nsFrameMessageManager::DispatchAsyncMessage(const nsAString& aMessageName,
|
|||
JSAutoStructuredCloneBuffer buffer;
|
||||
|
||||
if (aArgc >= 2 &&
|
||||
!GetParamsForMessage(aCx, aObject, buffer, data.mClosure)) {
|
||||
!GetParamsForMessage(aCx, aJSON, buffer, data.mClosure)) {
|
||||
return NS_ERROR_DOM_DATA_CLONE_ERR;
|
||||
}
|
||||
|
||||
JS::RootedObject objects(aCx);
|
||||
if (aArgc >= 3 && aObjects.isObject()) {
|
||||
objects = &aObjects.toObject();
|
||||
}
|
||||
|
||||
data.mData = buffer.data();
|
||||
data.mDataLength = buffer.nbytes();
|
||||
|
||||
return DispatchAsyncMessageInternal(aMessageName, data);
|
||||
return DispatchAsyncMessageInternal(aCx, aMessageName, data, objects);
|
||||
}
|
||||
|
||||
|
||||
|
@ -433,11 +461,12 @@ nsFrameMessageManager::DispatchAsyncMessage(const nsAString& aMessageName,
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsFrameMessageManager::SendAsyncMessage(const nsAString& aMessageName,
|
||||
const JS::Value& aObject,
|
||||
const JS::Value& aJSON,
|
||||
const JS::Value& aObjects,
|
||||
JSContext* aCx,
|
||||
uint8_t aArgc)
|
||||
{
|
||||
return DispatchAsyncMessage(aMessageName, aObject, aCx, aArgc);
|
||||
return DispatchAsyncMessage(aMessageName, aJSON, aObjects, aCx, aArgc);
|
||||
}
|
||||
|
||||
|
||||
|
@ -445,11 +474,12 @@ nsFrameMessageManager::SendAsyncMessage(const nsAString& aMessageName,
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsFrameMessageManager::BroadcastAsyncMessage(const nsAString& aMessageName,
|
||||
const JS::Value& aObject,
|
||||
const JS::Value& aJSON,
|
||||
const JS::Value& aObjects,
|
||||
JSContext* aCx,
|
||||
uint8_t aArgc)
|
||||
{
|
||||
return DispatchAsyncMessage(aMessageName, aObject, aCx, aArgc);
|
||||
return DispatchAsyncMessage(aMessageName, aJSON, aObjects, aCx, aArgc);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -631,11 +661,10 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
|
|||
const nsAString& aMessage,
|
||||
bool aSync,
|
||||
const StructuredCloneData* aCloneData,
|
||||
JS::Handle<JSObject*> aObjectsArray,
|
||||
CpowHolder* aCpows,
|
||||
InfallibleTArray<nsString>* aJSONRetVal)
|
||||
{
|
||||
AutoSafeJSContext ctx;
|
||||
JS::Rooted<JSObject*> objectsArray(ctx, aObjectsArray);
|
||||
if (mListeners.Length()) {
|
||||
nsCOMPtr<nsIAtom> name = do_GetAtom(aMessage);
|
||||
MMListenerRemover lr(this);
|
||||
|
@ -663,20 +692,21 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
|
|||
nsContentUtils::WrapNative(ctx, global, aTarget, targetv.address(),
|
||||
nullptr, true);
|
||||
|
||||
// To keep compatibility with e10s message manager,
|
||||
// define empty objects array.
|
||||
if (!objectsArray) {
|
||||
// Because we want JS messages to have always the same properties,
|
||||
// create array even if len == 0.
|
||||
objectsArray = JS_NewArrayObject(ctx, 0, nullptr);
|
||||
if (!objectsArray) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
JS::RootedObject cpows(ctx);
|
||||
if (aCpows) {
|
||||
if (!aCpows->ToObject(ctx, cpows.address())) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
}
|
||||
|
||||
JS::Rooted<JS::Value> objectsv(ctx, JS::ObjectValue(*objectsArray));
|
||||
if (!JS_WrapValue(ctx, objectsv.address()))
|
||||
if (!cpows) {
|
||||
cpows = JS_NewObject(ctx, nullptr, nullptr, nullptr);
|
||||
if (!cpows) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
}
|
||||
|
||||
JS::RootedValue cpowsv(ctx, JS::ObjectValue(*cpows));
|
||||
|
||||
JS::Rooted<JS::Value> json(ctx, JS::NullValue());
|
||||
if (aCloneData && aCloneData->mDataLength &&
|
||||
|
@ -696,7 +726,7 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
|
|||
BOOLEAN_TO_JSVAL(aSync), nullptr, nullptr, JSPROP_ENUMERATE);
|
||||
JS_DefineProperty(ctx, param, "json", json, nullptr, nullptr, JSPROP_ENUMERATE); // deprecated
|
||||
JS_DefineProperty(ctx, param, "data", json, nullptr, nullptr, JSPROP_ENUMERATE);
|
||||
JS_DefineProperty(ctx, param, "objects", objectsv, nullptr, nullptr, JSPROP_ENUMERATE);
|
||||
JS_DefineProperty(ctx, param, "objects", cpowsv, nullptr, nullptr, JSPROP_ENUMERATE);
|
||||
|
||||
JS::Rooted<JS::Value> thisValue(ctx, JS::UndefinedValue());
|
||||
|
||||
|
@ -754,7 +784,7 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
|
|||
nsRefPtr<nsFrameMessageManager> kungfuDeathGrip = mParentManager;
|
||||
return mParentManager ? mParentManager->ReceiveMessage(aTarget, aMessage,
|
||||
aSync, aCloneData,
|
||||
objectsArray,
|
||||
aCpows,
|
||||
aJSONRetVal) : NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1040,20 +1070,33 @@ nsFrameMessageManager* nsFrameMessageManager::sParentProcessManager = nullptr;
|
|||
nsFrameMessageManager* nsFrameMessageManager::sSameProcessParentManager = nullptr;
|
||||
nsTArray<nsCOMPtr<nsIRunnable> >* nsFrameMessageManager::sPendingSameProcessAsyncMessages = nullptr;
|
||||
|
||||
|
||||
class nsAsyncMessageToSameProcessChild : public nsRunnable
|
||||
{
|
||||
public:
|
||||
nsAsyncMessageToSameProcessChild(const nsAString& aMessage,
|
||||
const StructuredCloneData& aData)
|
||||
: mMessage(aMessage)
|
||||
nsAsyncMessageToSameProcessChild(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows)
|
||||
: mRuntime(js::GetRuntime(aCx)),
|
||||
mMessage(aMessage),
|
||||
mCpows(aCpows)
|
||||
{
|
||||
if (aData.mDataLength && !mData.copy(aData.mData, aData.mDataLength)) {
|
||||
NS_RUNTIMEABORT("OOM");
|
||||
}
|
||||
if (mCpows && !js_AddObjectRoot(mRuntime, &mCpows)) {
|
||||
NS_RUNTIMEABORT("OOM");
|
||||
}
|
||||
mClosure = aData.mClosure;
|
||||
}
|
||||
|
||||
~nsAsyncMessageToSameProcessChild()
|
||||
{
|
||||
if (mCpows) {
|
||||
JS_RemoveObjectRootRT(mRuntime, &mCpows);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
if (nsFrameMessageManager::sChildProcessManager) {
|
||||
|
@ -1062,15 +1105,19 @@ public:
|
|||
data.mDataLength = mData.nbytes();
|
||||
data.mClosure = mClosure;
|
||||
|
||||
SameProcessCpowHolder cpows(mRuntime, JS::Handle<JSObject *>::fromMarkedLocation(&mCpows));
|
||||
|
||||
nsRefPtr<nsFrameMessageManager> ppm = nsFrameMessageManager::sChildProcessManager;
|
||||
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()), mMessage,
|
||||
false, &data, JS::NullPtr(), nullptr);
|
||||
false, &data, &cpows, nullptr);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
JSRuntime* mRuntime;
|
||||
nsString mMessage;
|
||||
JSAutoStructuredCloneBuffer mData;
|
||||
StructuredCloneClosure mClosure;
|
||||
JSObject* mCpows;
|
||||
};
|
||||
|
||||
|
||||
|
@ -1089,11 +1136,13 @@ public:
|
|||
MOZ_COUNT_DTOR(SameParentProcessMessageManagerCallback);
|
||||
}
|
||||
|
||||
virtual bool DoSendAsyncMessage(const nsAString& aMessage,
|
||||
const StructuredCloneData& aData)
|
||||
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows)
|
||||
{
|
||||
nsRefPtr<nsIRunnable> ev =
|
||||
new nsAsyncMessageToSameProcessChild(aMessage, aData);
|
||||
new nsAsyncMessageToSameProcessChild(aCx, aMessage, aData, aCpows);
|
||||
NS_DispatchToCurrentThread(ev);
|
||||
return true;
|
||||
}
|
||||
|
@ -1133,8 +1182,10 @@ public:
|
|||
MOZ_COUNT_DTOR(ChildProcessMessageManagerCallback);
|
||||
}
|
||||
|
||||
virtual bool DoSendSyncMessage(const nsAString& aMessage,
|
||||
virtual bool DoSendSyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
InfallibleTArray<nsString>* aJSONRetVal)
|
||||
{
|
||||
mozilla::dom::ContentChild* cc =
|
||||
|
@ -1146,11 +1197,17 @@ public:
|
|||
if (!BuildClonedMessageDataForChild(cc, aData, data)) {
|
||||
return false;
|
||||
}
|
||||
return cc->SendSyncMessage(nsString(aMessage), data, aJSONRetVal);
|
||||
InfallibleTArray<mozilla::jsipc::CpowEntry> cpows;
|
||||
if (!cc->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
|
||||
return false;
|
||||
}
|
||||
return cc->SendSyncMessage(nsString(aMessage), data, cpows, aJSONRetVal);
|
||||
}
|
||||
|
||||
virtual bool DoSendAsyncMessage(const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData)
|
||||
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows)
|
||||
{
|
||||
mozilla::dom::ContentChild* cc =
|
||||
mozilla::dom::ContentChild::GetSingleton();
|
||||
|
@ -1161,7 +1218,11 @@ public:
|
|||
if (!BuildClonedMessageDataForChild(cc, aData, data)) {
|
||||
return false;
|
||||
}
|
||||
return cc->SendAsyncMessage(nsString(aMessage), data);
|
||||
InfallibleTArray<mozilla::jsipc::CpowEntry> cpows;
|
||||
if (!cc->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
|
||||
return false;
|
||||
}
|
||||
return cc->SendAsyncMessage(nsString(aMessage), data, cpows);
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -1170,16 +1231,30 @@ public:
|
|||
class nsAsyncMessageToSameProcessParent : public nsRunnable
|
||||
{
|
||||
public:
|
||||
nsAsyncMessageToSameProcessParent(const nsAString& aMessage,
|
||||
const StructuredCloneData& aData)
|
||||
: mMessage(aMessage)
|
||||
nsAsyncMessageToSameProcessParent(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows)
|
||||
: mRuntime(js::GetRuntime(aCx)),
|
||||
mMessage(aMessage),
|
||||
mCpows(aCpows)
|
||||
{
|
||||
if (aData.mDataLength && !mData.copy(aData.mData, aData.mDataLength)) {
|
||||
NS_RUNTIMEABORT("OOM");
|
||||
}
|
||||
if (mCpows && !js_AddObjectRoot(mRuntime, &mCpows)) {
|
||||
NS_RUNTIMEABORT("OOM");
|
||||
}
|
||||
mClosure = aData.mClosure;
|
||||
}
|
||||
|
||||
~nsAsyncMessageToSameProcessParent()
|
||||
{
|
||||
if (mCpows) {
|
||||
JS_RemoveObjectRootRT(mRuntime, &mCpows);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
if (nsFrameMessageManager::sPendingSameProcessAsyncMessages) {
|
||||
|
@ -1191,16 +1266,20 @@ public:
|
|||
data.mDataLength = mData.nbytes();
|
||||
data.mClosure = mClosure;
|
||||
|
||||
SameProcessCpowHolder cpows(mRuntime, JS::Handle<JSObject *>::fromMarkedLocation(&mCpows));
|
||||
|
||||
nsRefPtr<nsFrameMessageManager> ppm =
|
||||
nsFrameMessageManager::sSameProcessParentManager;
|
||||
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
|
||||
mMessage, false, &data, JS::NullPtr(), nullptr);
|
||||
mMessage, false, &data, &cpows, nullptr);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
JSRuntime* mRuntime;
|
||||
nsString mMessage;
|
||||
JSAutoStructuredCloneBuffer mData;
|
||||
StructuredCloneClosure mClosure;
|
||||
JSObject* mCpows;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1218,8 +1297,10 @@ public:
|
|||
MOZ_COUNT_DTOR(SameChildProcessMessageManagerCallback);
|
||||
}
|
||||
|
||||
virtual bool DoSendSyncMessage(const nsAString& aMessage,
|
||||
virtual bool DoSendSyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
InfallibleTArray<nsString>* aJSONRetVal)
|
||||
{
|
||||
nsTArray<nsCOMPtr<nsIRunnable> > asyncMessages;
|
||||
|
@ -1232,21 +1313,24 @@ public:
|
|||
}
|
||||
}
|
||||
if (nsFrameMessageManager::sSameProcessParentManager) {
|
||||
SameProcessCpowHolder cpows(js::GetRuntime(aCx), aCpows);
|
||||
nsRefPtr<nsFrameMessageManager> ppm = nsFrameMessageManager::sSameProcessParentManager;
|
||||
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()), aMessage,
|
||||
true, &aData, JS::NullPtr(), aJSONRetVal);
|
||||
true, &aData, &cpows, aJSONRetVal);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool DoSendAsyncMessage(const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData)
|
||||
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows)
|
||||
{
|
||||
if (!nsFrameMessageManager::sPendingSameProcessAsyncMessages) {
|
||||
nsFrameMessageManager::sPendingSameProcessAsyncMessages = new nsTArray<nsCOMPtr<nsIRunnable> >;
|
||||
}
|
||||
nsCOMPtr<nsIRunnable> ev =
|
||||
new nsAsyncMessageToSameProcessParent(aMessage, aData);
|
||||
new nsAsyncMessageToSameProcessParent(aCx, aMessage, aData, aCpows);
|
||||
nsFrameMessageManager::sPendingSameProcessAsyncMessages->AppendElement(ev);
|
||||
NS_DispatchToCurrentThread(ev);
|
||||
return true;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=4 sw=4 tw=99 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/. */
|
||||
|
@ -51,15 +52,19 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
virtual bool DoSendSyncMessage(const nsAString& aMessage,
|
||||
virtual bool DoSendSyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
InfallibleTArray<nsString>* aJSONRetVal)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool DoSendAsyncMessage(const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData)
|
||||
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -110,6 +115,25 @@ struct nsMessageListenerInfo
|
|||
nsCOMPtr<nsIAtom> mMessage;
|
||||
};
|
||||
|
||||
class CpowHolder
|
||||
{
|
||||
public:
|
||||
virtual bool ToObject(JSContext* cx, JSObject** objp) = 0;
|
||||
};
|
||||
|
||||
class MOZ_STACK_CLASS SameProcessCpowHolder : public CpowHolder
|
||||
{
|
||||
public:
|
||||
SameProcessCpowHolder(JSRuntime *aRuntime, JS::Handle<JSObject *> aObj)
|
||||
: mObj(aRuntime, aObj)
|
||||
{
|
||||
}
|
||||
|
||||
bool ToObject(JSContext* aCx, JSObject** aObjp);
|
||||
|
||||
private:
|
||||
JS::RootedObject mObj;
|
||||
};
|
||||
|
||||
class nsFrameMessageManager MOZ_FINAL : public nsIContentFrameMessageManager,
|
||||
public nsIMessageBroadcaster,
|
||||
|
@ -183,7 +207,7 @@ public:
|
|||
|
||||
nsresult ReceiveMessage(nsISupports* aTarget, const nsAString& aMessage,
|
||||
bool aSync, const StructuredCloneData* aCloneData,
|
||||
JS::Handle<JSObject*> aObjectsArray,
|
||||
CpowHolder* aCpows,
|
||||
InfallibleTArray<nsString>* aJSONRetVal);
|
||||
|
||||
void AddChildManager(nsFrameMessageManager* aManager,
|
||||
|
@ -202,11 +226,14 @@ public:
|
|||
}
|
||||
|
||||
nsresult DispatchAsyncMessage(const nsAString& aMessageName,
|
||||
const JS::Value& aObject,
|
||||
const JS::Value& aJSON,
|
||||
const JS::Value& aObjects,
|
||||
JSContext* aCx,
|
||||
uint8_t aArgc);
|
||||
nsresult DispatchAsyncMessageInternal(const nsAString& aMessage,
|
||||
const StructuredCloneData& aData);
|
||||
nsresult DispatchAsyncMessageInternal(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows);
|
||||
void RemoveFromParent();
|
||||
nsFrameMessageManager* GetParentManager() { return mParentManager; }
|
||||
void SetParentManager(nsFrameMessageManager* aParent)
|
||||
|
|
|
@ -25,8 +25,10 @@ using mozilla::dom::StructuredCloneData;
|
|||
using mozilla::dom::StructuredCloneClosure;
|
||||
|
||||
bool
|
||||
nsInProcessTabChildGlobal::DoSendSyncMessage(const nsAString& aMessage,
|
||||
const StructuredCloneData& aData,
|
||||
nsInProcessTabChildGlobal::DoSendSyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
InfallibleTArray<nsString>* aJSONRetVal)
|
||||
{
|
||||
nsTArray<nsCOMPtr<nsIRunnable> > asyncMessages;
|
||||
|
@ -37,9 +39,9 @@ nsInProcessTabChildGlobal::DoSendSyncMessage(const nsAString& aMessage,
|
|||
async->Run();
|
||||
}
|
||||
if (mChromeMessageManager) {
|
||||
SameProcessCpowHolder cpows(js::GetRuntime(aCx), aCpows);
|
||||
nsRefPtr<nsFrameMessageManager> mm = mChromeMessageManager;
|
||||
mm->ReceiveMessage(mOwner, aMessage, true, &aData, JS::NullPtr(),
|
||||
aJSONRetVal);
|
||||
mm->ReceiveMessage(mOwner, aMessage, true, &aData, &cpows, aJSONRetVal);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -47,17 +49,33 @@ nsInProcessTabChildGlobal::DoSendSyncMessage(const nsAString& aMessage,
|
|||
class nsAsyncMessageToParent : public nsRunnable
|
||||
{
|
||||
public:
|
||||
nsAsyncMessageToParent(nsInProcessTabChildGlobal* aTabChild,
|
||||
nsAsyncMessageToParent(JSContext* aCx,
|
||||
nsInProcessTabChildGlobal* aTabChild,
|
||||
const nsAString& aMessage,
|
||||
const StructuredCloneData& aData)
|
||||
: mTabChild(aTabChild), mMessage(aMessage), mRun(false)
|
||||
const StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows)
|
||||
: mRuntime(js::GetRuntime(aCx)),
|
||||
mTabChild(aTabChild),
|
||||
mMessage(aMessage),
|
||||
mCpows(aCpows),
|
||||
mRun(false)
|
||||
{
|
||||
if (aData.mDataLength && !mData.copy(aData.mData, aData.mDataLength)) {
|
||||
NS_RUNTIMEABORT("OOM");
|
||||
}
|
||||
if (mCpows && !js_AddObjectRoot(mRuntime, &mCpows)) {
|
||||
NS_RUNTIMEABORT("OOM");
|
||||
}
|
||||
mClosure = aData.mClosure;
|
||||
}
|
||||
|
||||
~nsAsyncMessageToParent()
|
||||
{
|
||||
if (mCpows) {
|
||||
JS_RemoveObjectRootRT(mRuntime, &mCpows);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
if (mRun) {
|
||||
|
@ -72,27 +90,32 @@ public:
|
|||
data.mDataLength = mData.nbytes();
|
||||
data.mClosure = mClosure;
|
||||
|
||||
SameProcessCpowHolder cpows(mRuntime, JS::Handle<JSObject *>::fromMarkedLocation(&mCpows));
|
||||
|
||||
nsRefPtr<nsFrameMessageManager> mm = mTabChild->mChromeMessageManager;
|
||||
mm->ReceiveMessage(mTabChild->mOwner, mMessage, false, &data,
|
||||
JS::NullPtr(), nullptr);
|
||||
mm->ReceiveMessage(mTabChild->mOwner, mMessage, false, &data, &cpows, nullptr);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
JSRuntime* mRuntime;
|
||||
nsRefPtr<nsInProcessTabChildGlobal> mTabChild;
|
||||
nsString mMessage;
|
||||
JSAutoStructuredCloneBuffer mData;
|
||||
StructuredCloneClosure mClosure;
|
||||
JSObject* mCpows;
|
||||
// True if this runnable has already been called. This can happen if DoSendSyncMessage
|
||||
// is called while waiting for an asynchronous message send.
|
||||
bool mRun;
|
||||
};
|
||||
|
||||
bool
|
||||
nsInProcessTabChildGlobal::DoSendAsyncMessage(const nsAString& aMessage,
|
||||
const StructuredCloneData& aData)
|
||||
nsInProcessTabChildGlobal::DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows)
|
||||
{
|
||||
nsCOMPtr<nsIRunnable> ev =
|
||||
new nsAsyncMessageToParent(this, aMessage, aData);
|
||||
new nsAsyncMessageToParent(aCx, this, aMessage, aData, aCpows);
|
||||
mASyncMessages.AppendElement(ev);
|
||||
NS_DispatchToCurrentThread(ev);
|
||||
return true;
|
||||
|
|
|
@ -41,12 +41,13 @@ public:
|
|||
NS_FORWARD_SAFE_NSIMESSAGESENDER(mMessageManager)
|
||||
NS_IMETHOD SendSyncMessage(const nsAString& aMessageName,
|
||||
const JS::Value& aObject,
|
||||
const JS::Value& aRemote,
|
||||
JSContext* aCx,
|
||||
uint8_t aArgc,
|
||||
JS::Value* aRetval)
|
||||
{
|
||||
return mMessageManager
|
||||
? mMessageManager->SendSyncMessage(aMessageName, aObject, aCx, aArgc, aRetval)
|
||||
? mMessageManager->SendSyncMessage(aMessageName, aObject, aRemote, aCx, aArgc, aRetval)
|
||||
: NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
NS_IMETHOD GetContent(nsIDOMWindow** aContent) MOZ_OVERRIDE;
|
||||
|
@ -66,11 +67,15 @@ public:
|
|||
/**
|
||||
* MessageManagerCallback methods that we override.
|
||||
*/
|
||||
virtual bool DoSendSyncMessage(const nsAString& aMessage,
|
||||
virtual bool DoSendSyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
InfallibleTArray<nsString>* aJSONRetVal) MOZ_OVERRIDE;
|
||||
virtual bool DoSendAsyncMessage(const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData) MOZ_OVERRIDE;
|
||||
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows);
|
||||
|
||||
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor) MOZ_OVERRIDE;
|
||||
NS_IMETHOD AddEventListener(const nsAString& aType,
|
||||
|
|
|
@ -61,6 +61,9 @@ MOCHITEST_CHROME_FILES = \
|
|||
host_bug814638.xul \
|
||||
test_document_register.xul \
|
||||
frame_bug814638.xul \
|
||||
test_cpows.xul \
|
||||
cpows_parent.xul \
|
||||
cpows_child.js \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
dump('loaded child cpow test\n');
|
||||
|
||||
content.document.title = "Hello, Kitty";
|
||||
|
||||
(function start() {
|
||||
sync_test();
|
||||
async_test();
|
||||
sendAsyncMessage("cpows:done", {});
|
||||
}
|
||||
)();
|
||||
|
||||
function ok(condition, message) {
|
||||
dump('condition: ' + condition + ', ' + message + '\n');
|
||||
if (!condition) {
|
||||
sendAsyncMessage("cpows:fail", { message: message });
|
||||
throw 'failed check: ' + message;
|
||||
}
|
||||
}
|
||||
|
||||
var sync_obj;
|
||||
var async_obj;
|
||||
|
||||
function make_object()
|
||||
{
|
||||
let o = { };
|
||||
o.i = 5;
|
||||
o.b = true;
|
||||
o.s = "hello";
|
||||
o.x = { i: 10 };
|
||||
o.f = function () { return 99; }
|
||||
return { "data": o,
|
||||
"document": content.document
|
||||
};
|
||||
}
|
||||
|
||||
function make_json()
|
||||
{
|
||||
return { check: "ok" };
|
||||
}
|
||||
|
||||
function sync_test()
|
||||
{
|
||||
dump('beginning cpow sync test\n');
|
||||
sync_obj = make_object();
|
||||
sendSyncMessage("cpows:sync",
|
||||
make_json(),
|
||||
make_object());
|
||||
}
|
||||
|
||||
function async_test()
|
||||
{
|
||||
dump('beginning cpow async test\n');
|
||||
async_obj = make_object();
|
||||
sendAsyncMessage("cpows:async",
|
||||
make_json(),
|
||||
async_obj);
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||
type="text/css"?>
|
||||
<window title="MessageManager CPOW tests"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="start()">
|
||||
|
||||
<!-- test results are displayed in the html:body -->
|
||||
<label value="CPOWs"/>
|
||||
|
||||
<script type="application/javascript"><![CDATA[
|
||||
var test_state = "remote";
|
||||
var test_node = null;
|
||||
|
||||
function ok(condition, message) {
|
||||
return opener.wrappedJSObject.ok(condition, message);
|
||||
}
|
||||
|
||||
function testCpowMessage(message) {
|
||||
ok(message.json.check == "ok", "correct json");
|
||||
|
||||
let data = message.objects.data;
|
||||
let document = message.objects.document;
|
||||
ok(data.i === 5, "integer property");
|
||||
ok(data.b === true, "boolean property");
|
||||
ok(data.s === "hello", "string property");
|
||||
ok(data.x.i === 10, "nested property");
|
||||
ok(data.f() === 99, "function call");
|
||||
ok(document.title === "Hello, Kitty", "document node");
|
||||
|
||||
data.i = 6;
|
||||
data.b = false;
|
||||
data.s = "bye";
|
||||
data.x = null;
|
||||
ok(data.i === 6, "integer property");
|
||||
ok(data.b === false, "boolean property");
|
||||
ok(data.s === "bye", "string property");
|
||||
ok(data.x === null, "nested property");
|
||||
}
|
||||
|
||||
function recvAsyncMessage(message) {
|
||||
testCpowMessage(message);
|
||||
}
|
||||
|
||||
function recvSyncMessage(message) {
|
||||
testCpowMessage(message);
|
||||
}
|
||||
|
||||
function recvFailMessage(message) {
|
||||
ok(false, message.json.message);
|
||||
}
|
||||
|
||||
function recvDoneMessage(message) {
|
||||
if (test_state == "remote") {
|
||||
test_node.parentNode.removeChild(test_node);
|
||||
run_tests("inprocess");
|
||||
return;
|
||||
}
|
||||
|
||||
finish();
|
||||
}
|
||||
|
||||
function run_tests(type) {
|
||||
var node = document.getElementById('cpowbrowser_' + type);
|
||||
|
||||
test_state = type;
|
||||
test_node = node;
|
||||
|
||||
var mm = node.messageManager;
|
||||
mm.addMessageListener("cpows:async", recvAsyncMessage);
|
||||
mm.addMessageListener("cpows:sync", recvSyncMessage);
|
||||
mm.addMessageListener("cpows:done", recvDoneMessage);
|
||||
mm.addMessageListener("cpows:fail", recvFailMessage);
|
||||
mm.loadFrameScript("chrome://mochitests/content/chrome/content/base/test/chrome/cpows_child.js", true);
|
||||
}
|
||||
|
||||
function start() {
|
||||
run_tests('remote');
|
||||
}
|
||||
|
||||
function finish() {
|
||||
opener.setTimeout("done()", 0);
|
||||
window.close();
|
||||
}
|
||||
]]></script>
|
||||
|
||||
<browser type="content" src="about:blank" id="cpowbrowser_remote" remote="true"/>
|
||||
<browser type="content" src="about:blank" id="cpowbrowser_inprocess"/>
|
||||
</window>
|
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||
type="text/css"?>
|
||||
<window title="Test CPOWs"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
|
||||
<!-- test results are displayed in the html:body -->
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
</body>
|
||||
|
||||
<!-- test code goes here -->
|
||||
<script type="application/javascript"><![CDATA[
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function done() {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
addLoadEvent(function() {
|
||||
window.open("cpows_parent.xul", "", "chrome");
|
||||
});
|
||||
]]></script>
|
||||
</window>
|
|
@ -321,6 +321,8 @@ ContentChild::Init(MessageLoop* aIOLoop,
|
|||
|
||||
SendGetProcessAttributes(&mID, &mIsForApp, &mIsForBrowser);
|
||||
|
||||
GetCPOWManager();
|
||||
|
||||
if (mIsForApp && !mIsForBrowser) {
|
||||
SetProcessName(NS_LITERAL_STRING("(Preallocated app)"));
|
||||
} else {
|
||||
|
@ -1059,13 +1061,15 @@ ContentChild::RecvNotifyVisited(const URIParams& aURI)
|
|||
|
||||
bool
|
||||
ContentChild::RecvAsyncMessage(const nsString& aMsg,
|
||||
const ClonedMessageData& aData)
|
||||
const ClonedMessageData& aData,
|
||||
const InfallibleTArray<CpowEntry>& aCpows)
|
||||
{
|
||||
nsRefPtr<nsFrameMessageManager> cpm = nsFrameMessageManager::sChildProcessManager;
|
||||
if (cpm) {
|
||||
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForChild(aData);
|
||||
CpowIdHolder cpows(GetCPOWManager(), aCpows);
|
||||
cpm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(cpm.get()),
|
||||
aMsg, false, &cloneData, JS::NullPtr(), nullptr);
|
||||
aMsg, false, &cloneData, &cpows, nullptr);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -178,7 +178,8 @@ public:
|
|||
virtual bool RecvNotifyAlertsObserver(const nsCString& aType, const nsString& aData);
|
||||
|
||||
virtual bool RecvAsyncMessage(const nsString& aMsg,
|
||||
const ClonedMessageData& aData);
|
||||
const ClonedMessageData& aData,
|
||||
const InfallibleTArray<CpowEntry>& aCpows);
|
||||
|
||||
virtual bool RecvGeolocationUpdate(const GeoPosition& somewhere);
|
||||
|
||||
|
|
|
@ -868,7 +868,7 @@ ContentParent::ActorDestroy(ActorDestroyReason why)
|
|||
if (ppm) {
|
||||
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
|
||||
CHILD_PROCESS_SHUTDOWN_MESSAGE, false,
|
||||
nullptr, JS::NullPtr(), nullptr);
|
||||
nullptr, nullptr, nullptr);
|
||||
}
|
||||
nsCOMPtr<nsIThreadObserver>
|
||||
kungFuDeathGrip(static_cast<nsIThreadObserver*>(this));
|
||||
|
@ -2308,26 +2308,30 @@ ContentParent::RecvTestPermissionFromPrincipal(const IPC::Principal& aPrincipal,
|
|||
bool
|
||||
ContentParent::RecvSyncMessage(const nsString& aMsg,
|
||||
const ClonedMessageData& aData,
|
||||
const InfallibleTArray<CpowEntry>& aCpows,
|
||||
InfallibleTArray<nsString>* aRetvals)
|
||||
{
|
||||
nsRefPtr<nsFrameMessageManager> ppm = mMessageManager;
|
||||
if (ppm) {
|
||||
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
|
||||
CpowIdHolder cpows(GetCPOWManager(), aCpows);
|
||||
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
|
||||
aMsg, true, &cloneData, JS::NullPtr(), aRetvals);
|
||||
aMsg, true, &cloneData, &cpows, aRetvals);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentParent::RecvAsyncMessage(const nsString& aMsg,
|
||||
const ClonedMessageData& aData)
|
||||
const ClonedMessageData& aData,
|
||||
const InfallibleTArray<CpowEntry>& aCpows)
|
||||
{
|
||||
nsRefPtr<nsFrameMessageManager> ppm = mMessageManager;
|
||||
if (ppm) {
|
||||
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
|
||||
CpowIdHolder cpows(GetCPOWManager(), aCpows);
|
||||
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
|
||||
aMsg, false, &cloneData, JS::NullPtr(), nullptr);
|
||||
aMsg, false, &cloneData, &cpows, nullptr);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -2531,14 +2535,20 @@ ContentParent::RecvPrivateDocShellsExist(const bool& aExist)
|
|||
}
|
||||
|
||||
bool
|
||||
ContentParent::DoSendAsyncMessage(const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData)
|
||||
ContentParent::DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows)
|
||||
{
|
||||
ClonedMessageData data;
|
||||
if (!BuildClonedMessageDataForParent(this, aData, data)) {
|
||||
return false;
|
||||
}
|
||||
return SendAsyncMessage(nsString(aMessage), data);
|
||||
InfallibleTArray<CpowEntry> cpows;
|
||||
if (!GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
|
||||
return false;
|
||||
}
|
||||
return SendAsyncMessage(nsString(aMessage), data, cpows);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -114,8 +114,10 @@ public:
|
|||
/**
|
||||
* MessageManagerCallback methods that we override.
|
||||
*/
|
||||
virtual bool DoSendAsyncMessage(const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData) MOZ_OVERRIDE;
|
||||
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows) MOZ_OVERRIDE;
|
||||
virtual bool CheckPermission(const nsAString& aPermission) MOZ_OVERRIDE;
|
||||
virtual bool CheckManifestURL(const nsAString& aManifestURL) MOZ_OVERRIDE;
|
||||
virtual bool CheckAppHasPermission(const nsAString& aPermission) MOZ_OVERRIDE;
|
||||
|
@ -199,7 +201,6 @@ private:
|
|||
// using them.
|
||||
using PContentParent::SendPBrowserConstructor;
|
||||
using PContentParent::SendPTestShellConstructor;
|
||||
using PContentParent::SendPJavaScriptConstructor;
|
||||
|
||||
// No more than one of !!aApp, aIsForBrowser, and aIsForPreallocated may be
|
||||
// true.
|
||||
|
@ -372,9 +373,11 @@ private:
|
|||
|
||||
virtual bool RecvSyncMessage(const nsString& aMsg,
|
||||
const ClonedMessageData& aData,
|
||||
const InfallibleTArray<CpowEntry>& aCpows,
|
||||
InfallibleTArray<nsString>* aRetvals);
|
||||
virtual bool RecvAsyncMessage(const nsString& aMsg,
|
||||
const ClonedMessageData& aData);
|
||||
const ClonedMessageData& aData,
|
||||
const InfallibleTArray<CpowEntry>& aCpows);
|
||||
|
||||
virtual bool RecvFilePathUpdateNotify(const nsString& aType,
|
||||
const nsString& aStorageName,
|
||||
|
|
|
@ -14,6 +14,7 @@ include protocol PRenderFrame;
|
|||
include protocol POfflineCacheUpdate;
|
||||
include protocol PIndexedDB;
|
||||
include DOMTypes;
|
||||
include JavaScriptTypes;
|
||||
include URIParams;
|
||||
|
||||
include "gfxMatrix.h";
|
||||
|
@ -67,7 +68,7 @@ rpc protocol PBrowser
|
|||
manages PIndexedDB;
|
||||
|
||||
both:
|
||||
AsyncMessage(nsString aMessage, ClonedMessageData aData);
|
||||
AsyncMessage(nsString aMessage, ClonedMessageData aData, CpowEntry[] aCpows);
|
||||
|
||||
parent:
|
||||
/**
|
||||
|
@ -80,7 +81,7 @@ parent:
|
|||
|
||||
rpc CreateWindow() returns (PBrowser window);
|
||||
|
||||
sync SyncMessage(nsString aMessage, ClonedMessageData aData)
|
||||
sync SyncMessage(nsString aMessage, ClonedMessageData aData, CpowEntry[] aCpows)
|
||||
returns (nsString[] retval);
|
||||
|
||||
/**
|
||||
|
|
|
@ -22,6 +22,7 @@ include protocol PStorage;
|
|||
include protocol PTestShell;
|
||||
include protocol PJavaScript;
|
||||
include DOMTypes;
|
||||
include JavaScriptTypes;
|
||||
include InputStreamParams;
|
||||
include PTabContext;
|
||||
include URIParams;
|
||||
|
@ -190,7 +191,7 @@ both:
|
|||
|
||||
async PBlob(BlobConstructorParams params);
|
||||
|
||||
PJavaScript();
|
||||
async PJavaScript();
|
||||
|
||||
child:
|
||||
/**
|
||||
|
@ -329,7 +330,7 @@ parent:
|
|||
|
||||
sync ReadFontList() returns (FontListEntry[] retValue);
|
||||
|
||||
sync SyncMessage(nsString aMessage, ClonedMessageData aData)
|
||||
sync SyncMessage(nsString aMessage, ClonedMessageData aData, CpowEntry[] aCpows)
|
||||
returns (nsString[] retval);
|
||||
|
||||
ShowAlertNotification(nsString imageUrl,
|
||||
|
@ -427,7 +428,7 @@ parent:
|
|||
async SetFakeVolumeState(nsString fsName, int32_t fsState);
|
||||
|
||||
both:
|
||||
AsyncMessage(nsString aMessage, ClonedMessageData aData);
|
||||
AsyncMessage(nsString aMessage, ClonedMessageData aData, CpowEntry[] aCpows);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -84,6 +84,7 @@
|
|||
#include "StructuredCloneUtils.h"
|
||||
#include "xpcpublic.h"
|
||||
#include "nsViewportInfo.h"
|
||||
#include "JavaScriptChild.h"
|
||||
|
||||
#define BROWSER_ELEMENT_CHILD_SCRIPT \
|
||||
NS_LITERAL_STRING("chrome://global/content/BrowserElementChild.js")
|
||||
|
@ -97,6 +98,7 @@ using namespace mozilla::layout;
|
|||
using namespace mozilla::docshell;
|
||||
using namespace mozilla::dom::indexedDB;
|
||||
using namespace mozilla::widget;
|
||||
using namespace mozilla::jsipc;
|
||||
|
||||
NS_IMPL_ISUPPORTS1(ContentListener, nsIDOMEventListener)
|
||||
|
||||
|
@ -1454,7 +1456,7 @@ TabChild::DispatchMessageManagerMessage(const nsAString& aMessageName,
|
|||
nsRefPtr<nsFrameMessageManager> mm =
|
||||
static_cast<nsFrameMessageManager*>(mTabChildGlobal->mMessageManager.get());
|
||||
mm->ReceiveMessage(static_cast<EventTarget*>(mTabChildGlobal),
|
||||
aMessageName, false, &cloneData, JS::NullPtr(), nullptr);
|
||||
aMessageName, false, &cloneData, nullptr, nullptr);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -2030,15 +2032,17 @@ TabChild::RecvLoadRemoteScript(const nsString& aURL)
|
|||
|
||||
bool
|
||||
TabChild::RecvAsyncMessage(const nsString& aMessage,
|
||||
const ClonedMessageData& aData)
|
||||
const ClonedMessageData& aData,
|
||||
const InfallibleTArray<CpowEntry>& aCpows)
|
||||
{
|
||||
if (mTabChildGlobal) {
|
||||
nsCOMPtr<nsIXPConnectJSObjectHolder> kungFuDeathGrip(GetGlobal());
|
||||
StructuredCloneData cloneData = UnpackClonedMessageDataForChild(aData);
|
||||
nsRefPtr<nsFrameMessageManager> mm =
|
||||
static_cast<nsFrameMessageManager*>(mTabChildGlobal->mMessageManager.get());
|
||||
CpowIdHolder cpows(static_cast<ContentChild*>(Manager())->GetCPOWManager(), aCpows);
|
||||
mm->ReceiveMessage(static_cast<EventTarget*>(mTabChildGlobal),
|
||||
aMessage, false, &cloneData, JS::NullPtr(), nullptr);
|
||||
aMessage, false, &cloneData, &cpows, nullptr);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -2332,8 +2336,10 @@ TabChild::DeallocPIndexedDBChild(PIndexedDBChild* aActor)
|
|||
}
|
||||
|
||||
bool
|
||||
TabChild::DoSendSyncMessage(const nsAString& aMessage,
|
||||
TabChild::DoSendSyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
InfallibleTArray<nsString>* aJSONRetVal)
|
||||
{
|
||||
ContentChild* cc = Manager();
|
||||
|
@ -2341,19 +2347,29 @@ TabChild::DoSendSyncMessage(const nsAString& aMessage,
|
|||
if (!BuildClonedMessageDataForChild(cc, aData, data)) {
|
||||
return false;
|
||||
}
|
||||
return SendSyncMessage(nsString(aMessage), data, aJSONRetVal);
|
||||
InfallibleTArray<CpowEntry> cpows;
|
||||
if (!cc->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
|
||||
return false;
|
||||
}
|
||||
return SendSyncMessage(nsString(aMessage), data, cpows, aJSONRetVal);
|
||||
}
|
||||
|
||||
bool
|
||||
TabChild::DoSendAsyncMessage(const nsAString& aMessage,
|
||||
const StructuredCloneData& aData)
|
||||
TabChild::DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows)
|
||||
{
|
||||
ContentChild* cc = Manager();
|
||||
ClonedMessageData data;
|
||||
if (!BuildClonedMessageDataForChild(cc, aData, data)) {
|
||||
return false;
|
||||
}
|
||||
return SendAsyncMessage(nsString(aMessage), data);
|
||||
InfallibleTArray<CpowEntry> cpows;
|
||||
if (!cc->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
|
||||
return false;
|
||||
}
|
||||
return SendAsyncMessage(nsString(aMessage), data, cpows);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -78,12 +78,13 @@ public:
|
|||
NS_FORWARD_SAFE_NSIMESSAGESENDER(mMessageManager)
|
||||
NS_IMETHOD SendSyncMessage(const nsAString& aMessageName,
|
||||
const JS::Value& aObject,
|
||||
const JS::Value& aRemote,
|
||||
JSContext* aCx,
|
||||
uint8_t aArgc,
|
||||
JS::Value* aRetval)
|
||||
{
|
||||
return mMessageManager
|
||||
? mMessageManager->SendSyncMessage(aMessageName, aObject, aCx, aArgc, aRetval)
|
||||
? mMessageManager->SendSyncMessage(aMessageName, aObject, aRemote, aCx, aArgc, aRetval)
|
||||
: NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
NS_IMETHOD GetContent(nsIDOMWindow** aContent) MOZ_OVERRIDE;
|
||||
|
@ -187,11 +188,15 @@ public:
|
|||
/**
|
||||
* MessageManagerCallback methods that we override.
|
||||
*/
|
||||
virtual bool DoSendSyncMessage(const nsAString& aMessage,
|
||||
virtual bool DoSendSyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
InfallibleTArray<nsString>* aJSONRetVal);
|
||||
virtual bool DoSendAsyncMessage(const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData);
|
||||
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows);
|
||||
|
||||
virtual bool RecvLoadURL(const nsCString& uri);
|
||||
virtual bool RecvCacheFileDescriptor(const nsString& aPath,
|
||||
|
@ -228,7 +233,8 @@ public:
|
|||
virtual bool RecvActivateFrameEvent(const nsString& aType, const bool& capture);
|
||||
virtual bool RecvLoadRemoteScript(const nsString& aURL);
|
||||
virtual bool RecvAsyncMessage(const nsString& aMessage,
|
||||
const ClonedMessageData& aData);
|
||||
const ClonedMessageData& aData,
|
||||
const InfallibleTArray<CpowEntry>& aCpows);
|
||||
|
||||
virtual PDocumentRendererChild*
|
||||
AllocPDocumentRendererChild(const nsRect& documentRect, const gfxMatrix& transform,
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include "nsThreadUtils.h"
|
||||
#include "private/pprio.h"
|
||||
#include "StructuredCloneUtils.h"
|
||||
#include "JavaScriptParent.h"
|
||||
#include "TabChild.h"
|
||||
#include <algorithm>
|
||||
|
||||
|
@ -62,6 +63,7 @@ using namespace mozilla::layout;
|
|||
using namespace mozilla::services;
|
||||
using namespace mozilla::widget;
|
||||
using namespace mozilla::dom::indexedDB;
|
||||
using namespace mozilla::jsipc;
|
||||
|
||||
// The flags passed by the webProgress notifications are 16 bits shifted
|
||||
// from the ones registered by webProgressListeners.
|
||||
|
@ -708,18 +710,22 @@ TabParent::TryCapture(const nsGUIEvent& aEvent)
|
|||
bool
|
||||
TabParent::RecvSyncMessage(const nsString& aMessage,
|
||||
const ClonedMessageData& aData,
|
||||
const InfallibleTArray<CpowEntry>& aCpows,
|
||||
InfallibleTArray<nsString>* aJSONRetVal)
|
||||
{
|
||||
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
|
||||
return ReceiveMessage(aMessage, true, &cloneData, aJSONRetVal);
|
||||
CpowIdHolder cpows(static_cast<ContentParent*>(Manager())->GetCPOWManager(), aCpows);
|
||||
return ReceiveMessage(aMessage, true, &cloneData, &cpows, aJSONRetVal);
|
||||
}
|
||||
|
||||
bool
|
||||
TabParent::RecvAsyncMessage(const nsString& aMessage,
|
||||
const ClonedMessageData& aData)
|
||||
const ClonedMessageData& aData,
|
||||
const InfallibleTArray<CpowEntry>& aCpows)
|
||||
{
|
||||
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
|
||||
return ReceiveMessage(aMessage, false, &cloneData, nullptr);
|
||||
CpowIdHolder cpows(static_cast<ContentParent*>(Manager())->GetCPOWManager(), aCpows);
|
||||
return ReceiveMessage(aMessage, false, &cloneData, &cpows, nullptr);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -1084,26 +1090,19 @@ bool
|
|||
TabParent::ReceiveMessage(const nsString& aMessage,
|
||||
bool aSync,
|
||||
const StructuredCloneData* aCloneData,
|
||||
CpowHolder* aCpows,
|
||||
InfallibleTArray<nsString>* aJSONRetVal)
|
||||
{
|
||||
nsRefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
|
||||
if (frameLoader && frameLoader->GetFrameMessageManager()) {
|
||||
nsRefPtr<nsFrameMessageManager> manager =
|
||||
frameLoader->GetFrameMessageManager();
|
||||
AutoSafeJSContext ctx;
|
||||
uint32_t len = 0; //TODO: obtain a real value in bug 572685
|
||||
// Because we want JS messages to have always the same properties,
|
||||
// create array even if len == 0.
|
||||
JS::Rooted<JSObject*> objectsArray(ctx, JS_NewArrayObject(ctx, len, NULL));
|
||||
if (!objectsArray) {
|
||||
return false;
|
||||
}
|
||||
|
||||
manager->ReceiveMessage(mFrameElement,
|
||||
aMessage,
|
||||
aSync,
|
||||
aCloneData,
|
||||
objectsArray,
|
||||
aCpows,
|
||||
aJSONRetVal);
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -30,6 +30,7 @@ class mozIApplication;
|
|||
class nsFrameLoader;
|
||||
class nsIDOMElement;
|
||||
class nsIURI;
|
||||
class CpowHolder;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
@ -122,9 +123,11 @@ public:
|
|||
virtual bool AnswerCreateWindow(PBrowserParent** retval);
|
||||
virtual bool RecvSyncMessage(const nsString& aMessage,
|
||||
const ClonedMessageData& aData,
|
||||
const InfallibleTArray<CpowEntry>& aCpows,
|
||||
InfallibleTArray<nsString>* aJSONRetVal);
|
||||
virtual bool RecvAsyncMessage(const nsString& aMessage,
|
||||
const ClonedMessageData& aData);
|
||||
const ClonedMessageData& aData,
|
||||
const InfallibleTArray<CpowEntry>& aCpows);
|
||||
virtual bool RecvNotifyIMEFocus(const bool& aFocus,
|
||||
nsIMEUpdatePreference* aPreference,
|
||||
uint32_t* aSeqno);
|
||||
|
@ -233,6 +236,7 @@ protected:
|
|||
bool ReceiveMessage(const nsString& aMessage,
|
||||
bool aSync,
|
||||
const StructuredCloneData* aCloneData,
|
||||
CpowHolder* aCpows,
|
||||
InfallibleTArray<nsString>* aJSONRetVal = nullptr);
|
||||
|
||||
virtual bool Recv__delete__() MOZ_OVERRIDE;
|
||||
|
|
|
@ -197,6 +197,10 @@ JavaScriptChild::AnswerGet(const ObjectId &objId, const ObjectId &receiverId,
|
|||
AutoSafeJSContext cx;
|
||||
JSAutoRequest request(cx);
|
||||
|
||||
// The outparam will be written to the buffer, so it must be set even if
|
||||
// the parent won't read it.
|
||||
*result = void_t();
|
||||
|
||||
RootedObject obj(cx, findObject(objId));
|
||||
if (!obj)
|
||||
return false;
|
||||
|
|
|
@ -455,14 +455,11 @@ CPOWProxyHandler::finalize(JSFreeOp *fop, JSObject *proxy)
|
|||
void
|
||||
JavaScriptParent::drop(JSObject *obj)
|
||||
{
|
||||
if (inactive_)
|
||||
return;
|
||||
|
||||
ObjectId objId = idOf(obj);
|
||||
|
||||
objects_.remove(objId);
|
||||
if (!SendDropObject(objId))
|
||||
MOZ_CRASH();
|
||||
if (!inactive_ && !SendDropObject(objId))
|
||||
(void)0;
|
||||
decref();
|
||||
}
|
||||
|
||||
|
|
|
@ -395,3 +395,78 @@ JavaScriptShared::toDescriptor(JSContext *cx, const PPropertyDescriptor &in, JSP
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CpowIdHolder::ToObject(JSContext *cx, JSObject **objp)
|
||||
{
|
||||
return js_->Unwrap(cx, cpows_, objp);
|
||||
}
|
||||
|
||||
bool
|
||||
JavaScriptShared::Unwrap(JSContext *cx, const InfallibleTArray<CpowEntry> &aCpows, JSObject **objp)
|
||||
{
|
||||
*objp = NULL;
|
||||
|
||||
if (!aCpows.Length())
|
||||
return true;
|
||||
|
||||
RootedObject obj(cx, JS_NewObject(cx, NULL, NULL, NULL));
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
RootedValue v(cx);
|
||||
RootedString str(cx);
|
||||
for (size_t i = 0; i < aCpows.Length(); i++) {
|
||||
const nsString &name = aCpows[i].name();
|
||||
|
||||
if (!toValue(cx, aCpows[i].value(), &v))
|
||||
return false;
|
||||
|
||||
if (!JS_DefineUCProperty(cx,
|
||||
obj,
|
||||
name.BeginReading(),
|
||||
name.Length(),
|
||||
v,
|
||||
NULL,
|
||||
NULL,
|
||||
JSPROP_ENUMERATE))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
*objp = obj;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
JavaScriptShared::Wrap(JSContext *cx, HandleObject aObj, InfallibleTArray<CpowEntry> *outCpows)
|
||||
{
|
||||
if (!aObj)
|
||||
return true;
|
||||
|
||||
AutoIdArray ids(cx, JS_Enumerate(cx, aObj));
|
||||
if (!ids)
|
||||
return false;
|
||||
|
||||
RootedId id(cx);
|
||||
RootedValue v(cx);
|
||||
for (size_t i = 0; i < ids.length(); i++) {
|
||||
id = ids[i];
|
||||
|
||||
nsString str;
|
||||
if (!convertIdToGeckoString(cx, id, &str))
|
||||
return false;
|
||||
|
||||
if (!JS_GetPropertyById(cx, aObj, id, v.address()))
|
||||
return false;
|
||||
|
||||
JSVariant var;
|
||||
if (!toVariant(cx, v, &var))
|
||||
return false;
|
||||
|
||||
outCpows->AppendElement(CpowEntry(str, var));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,24 @@ namespace jsipc {
|
|||
|
||||
typedef uint64_t ObjectId;
|
||||
|
||||
class JavaScriptShared;
|
||||
|
||||
class CpowIdHolder : public CpowHolder
|
||||
{
|
||||
public:
|
||||
CpowIdHolder(JavaScriptShared *js, const InfallibleTArray<CpowEntry> &cpows)
|
||||
: js_(js),
|
||||
cpows_(cpows)
|
||||
{
|
||||
}
|
||||
|
||||
bool ToObject(JSContext *cx, JSObject **objp);
|
||||
|
||||
private:
|
||||
JavaScriptShared *js_;
|
||||
const InfallibleTArray<CpowEntry> &cpows_;
|
||||
};
|
||||
|
||||
// Map ids -> JSObjects
|
||||
class ObjectStore
|
||||
{
|
||||
|
@ -70,6 +88,9 @@ class JavaScriptShared
|
|||
static const uint32_t OBJECT_EXTRA_BITS = 1;
|
||||
static const uint32_t OBJECT_IS_CALLABLE = (1 << 0);
|
||||
|
||||
bool Unwrap(JSContext *cx, const InfallibleTArray<CpowEntry> &aCpows, JSObject **objp);
|
||||
bool Wrap(JSContext *cx, JS::HandleObject aObj, InfallibleTArray<CpowEntry> *outCpows);
|
||||
|
||||
protected:
|
||||
bool toVariant(JSContext *cx, jsval from, JSVariant *to);
|
||||
bool toValue(JSContext *cx, const JSVariant &from, JS::MutableHandleValue to);
|
||||
|
|
|
@ -139,6 +139,12 @@ js_ObjectClassIs(JSContext *cx, JS::HandleObject obj, js::ESClassValue classValu
|
|||
JS_FRIEND_API(const char *)
|
||||
js_ObjectClassName(JSContext *cx, JS::HandleObject obj);
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
js_AddObjectRoot(JSRuntime *rt, JSObject **objp);
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
js_RemoveObjectRoot(JSRuntime *rt, JSObject **objp);
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
/*
|
||||
|
|
|
@ -1084,6 +1084,18 @@ js::AddScriptRoot(JSContext *cx, JSScript **rp, const char *name)
|
|||
return AddRoot(cx, rp, name, JS_GC_ROOT_SCRIPT_PTR);
|
||||
}
|
||||
|
||||
extern JS_FRIEND_API(bool)
|
||||
js_AddObjectRoot(JSRuntime *rt, JSObject **objp)
|
||||
{
|
||||
return AddRoot(rt, objp, NULL, JS_GC_ROOT_OBJECT_PTR);
|
||||
}
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
js_RemoveObjectRoot(JSRuntime *rt, JSObject **objp)
|
||||
{
|
||||
js_RemoveRoot(rt, objp);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
js_RemoveRoot(JSRuntime *rt, void *rp)
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче