diff --git a/dom/ipc/StructuredCloneData.cpp b/dom/ipc/StructuredCloneData.cpp index aa70b329bbc8..a6241c2b66fb 100644 --- a/dom/ipc/StructuredCloneData.cpp +++ b/dom/ipc/StructuredCloneData.cpp @@ -47,6 +47,19 @@ StructuredCloneData::StructuredCloneData( mExternalData(JS::StructuredCloneScope::DifferentProcess), mInitialized(false) {} +StructuredCloneData::StructuredCloneData( + StructuredCloneHolder::StructuredCloneScope aScope) + : StructuredCloneHolder(StructuredCloneHolder::CloningSupported, + StructuredCloneHolder::TransferringSupported, + aScope), + mExternalData(JS::StructuredCloneScope::DifferentProcess), + mInitialized(false) { + MOZ_ASSERT( + aScope == StructuredCloneHolder::StructuredCloneScope::DifferentProcess || + aScope == + StructuredCloneHolder::StructuredCloneScope::UnknownDestination); +} + StructuredCloneData::~StructuredCloneData() {} StructuredCloneData& StructuredCloneData::operator=( diff --git a/dom/ipc/StructuredCloneData.h b/dom/ipc/StructuredCloneData.h index bac00e9aa473..37538a9dafe9 100644 --- a/dom/ipc/StructuredCloneData.h +++ b/dom/ipc/StructuredCloneData.h @@ -149,6 +149,9 @@ class StructuredCloneData : public StructuredCloneHolder { StructuredCloneData(StructuredCloneData&& aOther); + // Only DifferentProcess and UnknownDestination scopes are supported. + explicit StructuredCloneData(StructuredCloneScope aScope); + ~StructuredCloneData(); StructuredCloneData& operator=(const StructuredCloneData& aOther) = delete; diff --git a/dom/messagechannel/MessagePort.cpp b/dom/messagechannel/MessagePort.cpp index 909885e3bfe1..7ef4ce105ea0 100644 --- a/dom/messagechannel/MessagePort.cpp +++ b/dom/messagechannel/MessagePort.cpp @@ -387,7 +387,7 @@ void MessagePort::PostMessage(JSContext* aCx, JS::Handle aMessage, AutoTArray, 1> array; array.AppendElement(data); - AutoTArray messages; + AutoTArray messages; // note: `messages` will borrow the underlying buffer, but this is okay // because reverse destruction order means `messages` will be destroyed prior // to `array`/`data`. @@ -553,7 +553,7 @@ void MessagePort::SetOnmessage(EventHandlerNonNull* aCallback) { // another actor. It receives a list of messages to be dispatch. It can be that // we were waiting for this entangling step in order to disentangle the port or // to close it. -void MessagePort::Entangled(nsTArray& aMessages) { +void MessagePort::Entangled(nsTArray& aMessages) { MOZ_ASSERT(mState == eStateEntangling || mState == eStateEntanglingForDisentangle || mState == eStateEntanglingForClose); @@ -564,7 +564,7 @@ void MessagePort::Entangled(nsTArray& aMessages) { // If we have pending messages, these have to be sent. if (!mMessagesForTheOtherPort.IsEmpty()) { { - nsTArray messages; + nsTArray messages; SharedMessagePortMessage::FromSharedToMessagesChild( mActor, mMessagesForTheOtherPort, messages); mActor->SendPostMessages(messages); @@ -614,7 +614,7 @@ void MessagePort::StartDisentangling() { mActor->SendStopSendingData(); } -void MessagePort::MessagesReceived(nsTArray& aMessages) { +void MessagePort::MessagesReceived(nsTArray& aMessages) { MOZ_ASSERT(mState == eStateEntangled || mState == eStateDisentangling || // This last step can happen only if Close() has been called // manually. At this point SendClose() is sent but we can still @@ -652,13 +652,13 @@ void MessagePort::Disentangle() { mState = eStateDisentangled; { - nsTArray messages; + nsTArray messages; SharedMessagePortMessage::FromSharedToMessagesChild(mActor, mMessages, messages); mActor->SendDisentangle(messages); } - // Only clear mMessages after the ClonedMessageData instances have gone out of - // scope because they borrow mMessages' underlying JSStructuredCloneDatas. + // Only clear mMessages after the MessageData instances have gone out of scope + // because they borrow mMessages' underlying JSStructuredCloneDatas. mMessages.Clear(); mActor->SetPort(nullptr); diff --git a/dom/messagechannel/MessagePort.h b/dom/messagechannel/MessagePort.h index 22e95833b5e3..21e44bc43f1c 100644 --- a/dom/messagechannel/MessagePort.h +++ b/dom/messagechannel/MessagePort.h @@ -22,6 +22,7 @@ class nsIGlobalObject; namespace mozilla { namespace dom { +class MessageData; class MessagePortChild; struct PostMessageOptions; class PostMessageRunnable; @@ -118,8 +119,8 @@ class MessagePort final : public DOMEventTargetHelper { // These methods are useful for MessagePortChild - void Entangled(nsTArray& aMessages); - void MessagesReceived(nsTArray& aMessages); + void Entangled(nsTArray& aMessages); + void MessagesReceived(nsTArray& aMessages); void StopSendingDataConfirmed(); void Closed(); diff --git a/dom/messagechannel/MessagePortChild.cpp b/dom/messagechannel/MessagePortChild.cpp index 741bfbf30c29..9a681a403822 100644 --- a/dom/messagechannel/MessagePortChild.cpp +++ b/dom/messagechannel/MessagePortChild.cpp @@ -22,7 +22,7 @@ mozilla::ipc::IPCResult MessagePortChild::RecvStopSendingDataConfirmed() { } mozilla::ipc::IPCResult MessagePortChild::RecvEntangled( - nsTArray&& aMessages) { + nsTArray&& aMessages) { if (mPort) { mPort->Entangled(aMessages); } @@ -30,7 +30,7 @@ mozilla::ipc::IPCResult MessagePortChild::RecvEntangled( } mozilla::ipc::IPCResult MessagePortChild::RecvReceiveData( - nsTArray&& aMessages) { + nsTArray&& aMessages) { if (mPort) { mPort->MessagesReceived(aMessages); } diff --git a/dom/messagechannel/MessagePortChild.h b/dom/messagechannel/MessagePortChild.h index 4cdcc97bc195..e8ef71b885bb 100644 --- a/dom/messagechannel/MessagePortChild.h +++ b/dom/messagechannel/MessagePortChild.h @@ -29,11 +29,9 @@ class MessagePortChild final : public PMessagePortChild { private: ~MessagePortChild() { MOZ_ASSERT(!mPort); } - mozilla::ipc::IPCResult RecvEntangled( - nsTArray&& aMessages); + mozilla::ipc::IPCResult RecvEntangled(nsTArray&& aMessages); - mozilla::ipc::IPCResult RecvReceiveData( - nsTArray&& aMessages); + mozilla::ipc::IPCResult RecvReceiveData(nsTArray&& aMessages); mozilla::ipc::IPCResult RecvStopSendingDataConfirmed(); diff --git a/dom/messagechannel/MessagePortParent.cpp b/dom/messagechannel/MessagePortParent.cpp index 7ec0b6a72705..d5cac44b5243 100644 --- a/dom/messagechannel/MessagePortParent.cpp +++ b/dom/messagechannel/MessagePortParent.cpp @@ -38,7 +38,7 @@ bool MessagePortParent::Entangle(const nsID& aDestinationUUID, } mozilla::ipc::IPCResult MessagePortParent::RecvPostMessages( - nsTArray&& aMessages) { + nsTArray&& aMessages) { // This converts the object in a data struct where we have BlobImpls. FallibleTArray> messages; if (NS_WARN_IF(!SharedMessagePortMessage::FromMessagesToSharedParent( @@ -66,7 +66,7 @@ mozilla::ipc::IPCResult MessagePortParent::RecvPostMessages( } mozilla::ipc::IPCResult MessagePortParent::RecvDisentangle( - nsTArray&& aMessages) { + nsTArray&& aMessages) { // This converts the object in a data struct where we have BlobImpls. FallibleTArray> messages; if (NS_WARN_IF(!SharedMessagePortMessage::FromMessagesToSharedParent( @@ -127,8 +127,7 @@ void MessagePortParent::ActorDestroy(ActorDestroyReason aWhy) { } } -bool MessagePortParent::Entangled( - const nsTArray& aMessages) { +bool MessagePortParent::Entangled(const nsTArray& aMessages) { MOZ_ASSERT(!mEntangled); mEntangled = true; return SendEntangled(aMessages); diff --git a/dom/messagechannel/MessagePortParent.h b/dom/messagechannel/MessagePortParent.h index 685625b227d1..65cde4edc391 100644 --- a/dom/messagechannel/MessagePortParent.h +++ b/dom/messagechannel/MessagePortParent.h @@ -26,7 +26,7 @@ class MessagePortParent final bool Entangle(const nsID& aDestinationUUID, const uint32_t& aSequenceID); - bool Entangled(const nsTArray& aMessages); + bool Entangled(const nsTArray& aMessages); void Close(); void CloseAndDelete(); @@ -39,11 +39,9 @@ class MessagePortParent final const uint32_t& aSequenceID); private: - mozilla::ipc::IPCResult RecvPostMessages( - nsTArray&& aMessages); + mozilla::ipc::IPCResult RecvPostMessages(nsTArray&& aMessages); - mozilla::ipc::IPCResult RecvDisentangle( - nsTArray&& aMessages); + mozilla::ipc::IPCResult RecvDisentangle(nsTArray&& aMessages); mozilla::ipc::IPCResult RecvStopSendingData(); diff --git a/dom/messagechannel/MessagePortService.cpp b/dom/messagechannel/MessagePortService.cpp index c94219053649..7540b2b993d7 100644 --- a/dom/messagechannel/MessagePortService.cpp +++ b/dom/messagechannel/MessagePortService.cpp @@ -148,7 +148,7 @@ bool MessagePortService::RequestEntangling(MessagePortParent* aParent, // that reverse destruction order works for us. FallibleTArray> messages( std::move(data->mMessages)); - FallibleTArray array; + FallibleTArray array; if (!SharedMessagePortMessage::FromSharedToMessagesParent(aParent, messages, array)) { CloseAll(aParent->ID()); @@ -231,7 +231,7 @@ bool MessagePortService::DisentanglePort( data->mParent = nextParent; data->mNextParents.RemoveElementAt(index); - FallibleTArray array; + FallibleTArray array; if (!SharedMessagePortMessage::FromSharedToMessagesParent(data->mParent, aMessages, array)) { return false; @@ -348,7 +348,7 @@ bool MessagePortService::PostMessages( // If the parent can send data to the child, let's proceed. if (data->mParent && data->mParent->CanSendData()) { { - FallibleTArray messages; + FallibleTArray messages; if (!SharedMessagePortMessage::FromSharedToMessagesParent( data->mParent, data->mMessages, messages)) { return false; diff --git a/dom/messagechannel/PMessagePort.ipdl b/dom/messagechannel/PMessagePort.ipdl index 93c56d68c780..8950f8cee84b 100644 --- a/dom/messagechannel/PMessagePort.ipdl +++ b/dom/messagechannel/PMessagePort.ipdl @@ -9,6 +9,7 @@ include protocol PIPCBlobInputStream; // FIXME: bug 792908 include protocol PParentToChildStream; // FIXME: bug 792908 include DOMTypes; +include ProtocolTypes; using struct mozilla::SerializedStructuredCloneBuffer from "ipc/IPCMessageUtils.h"; @@ -16,6 +17,15 @@ using struct mozilla::SerializedStructuredCloneBuffer namespace mozilla { namespace dom { +struct RefMessageData { + nsID uuid; +}; + +union MessageData { + ClonedMessageData; + RefMessageData; +}; + // This protocol is used for the MessageChannel/MessagePort API protocol PMessagePort { @@ -35,14 +45,14 @@ protocol PMessagePort 4. Recv__delete__(); */ parent: - async PostMessages(ClonedMessageData[] messages); - async Disentangle(ClonedMessageData[] messages); + async PostMessages(MessageData[] messages); + async Disentangle(MessageData[] messages); async StopSendingData(); async Close(); child: - async Entangled(ClonedMessageData[] messages); - async ReceiveData(ClonedMessageData[] messages); + async Entangled(MessageData[] messages); + async ReceiveData(MessageData[] messages); async StopSendingDataConfirmed(); async __delete__(); diff --git a/dom/messagechannel/SharedMessagePortMessage.cpp b/dom/messagechannel/SharedMessagePortMessage.cpp index 4d0c7563a306..e7a5a750c425 100644 --- a/dom/messagechannel/SharedMessagePortMessage.cpp +++ b/dom/messagechannel/SharedMessagePortMessage.cpp @@ -23,7 +23,7 @@ namespace dom { void SharedMessagePortMessage::FromSharedToMessagesChild( MessagePortChild* aActor, const nsTArray>& aData, - nsTArray& aArray) { + nsTArray& aArray) { MOZ_ASSERT(aActor); MOZ_ASSERT(aArray.IsEmpty()); aArray.SetCapacity(aData.Length()); @@ -32,14 +32,26 @@ void SharedMessagePortMessage::FromSharedToMessagesChild( MOZ_ASSERT(backgroundManager); for (auto& data : aData) { - ClonedMessageData* message = aArray.AppendElement(); - data->BuildClonedMessageDataForBackgroundChild(backgroundManager, *message); + MessageData* message = aArray.AppendElement(); + + if (data->CloneScope() == + StructuredCloneHolder::StructuredCloneScope::DifferentProcess) { + ClonedMessageData clonedData; + data->BuildClonedMessageDataForBackgroundChild(backgroundManager, + clonedData); + *message = clonedData; + continue; + } + + MOZ_ASSERT(data->CloneScope() == + StructuredCloneHolder::StructuredCloneScope::SameProcess); + *message = RefMessageData(); // TODO } } /* static */ bool SharedMessagePortMessage::FromMessagesToSharedChild( - nsTArray& aArray, + nsTArray& aArray, FallibleTArray>& aData) { MOZ_ASSERT(aData.IsEmpty()); @@ -49,7 +61,13 @@ bool SharedMessagePortMessage::FromMessagesToSharedChild( for (auto& message : aArray) { RefPtr data = new SharedMessagePortMessage(); - data->StealFromClonedMessageDataForBackgroundChild(message); + + if (message.type() == MessageData::TClonedMessageData) { + data->StealFromClonedMessageDataForBackgroundChild(message); + } else { + MOZ_ASSERT(message.type() == MessageData::TRefMessageData); + // TODO + } if (!aData.AppendElement(data, mozilla::fallible)) { return false; @@ -63,7 +81,7 @@ bool SharedMessagePortMessage::FromMessagesToSharedChild( bool SharedMessagePortMessage::FromSharedToMessagesParent( MessagePortParent* aActor, const nsTArray>& aData, - FallibleTArray& aArray) { + FallibleTArray& aArray) { MOZ_ASSERT(aArray.IsEmpty()); if (NS_WARN_IF(!aArray.SetCapacity(aData.Length(), mozilla::fallible))) { @@ -74,9 +92,20 @@ bool SharedMessagePortMessage::FromSharedToMessagesParent( MOZ_ASSERT(backgroundManager); for (auto& data : aData) { - ClonedMessageData* message = aArray.AppendElement(mozilla::fallible); - data->BuildClonedMessageDataForBackgroundParent(backgroundManager, - *message); + MessageData* message = aArray.AppendElement(mozilla::fallible); + + if (data->CloneScope() == + StructuredCloneHolder::StructuredCloneScope::DifferentProcess) { + ClonedMessageData clonedData; + data->BuildClonedMessageDataForBackgroundParent(backgroundManager, + clonedData); + *message = clonedData; + continue; + } + + MOZ_ASSERT(data->CloneScope() == + StructuredCloneHolder::StructuredCloneScope::SameProcess); + *message = RefMessageData(); // TODO } return true; @@ -84,7 +113,7 @@ bool SharedMessagePortMessage::FromSharedToMessagesParent( /* static */ bool SharedMessagePortMessage::FromMessagesToSharedParent( - nsTArray& aArray, + nsTArray& aArray, FallibleTArray>& aData) { MOZ_ASSERT(aData.IsEmpty()); @@ -94,7 +123,13 @@ bool SharedMessagePortMessage::FromMessagesToSharedParent( for (auto& message : aArray) { RefPtr data = new SharedMessagePortMessage(); - data->StealFromClonedMessageDataForBackgroundParent(message); + + if (message.type() == MessageData::TClonedMessageData) { + data->StealFromClonedMessageDataForBackgroundParent(message); + } else { + MOZ_ASSERT(message.type() == MessageData::TRefMessageData); + // TODO + } if (!aData.AppendElement(data, mozilla::fallible)) { return false; diff --git a/dom/messagechannel/SharedMessagePortMessage.h b/dom/messagechannel/SharedMessagePortMessage.h index 8b668425488e..99e8017a3624 100644 --- a/dom/messagechannel/SharedMessagePortMessage.h +++ b/dom/messagechannel/SharedMessagePortMessage.h @@ -20,36 +20,37 @@ class SharedMessagePortMessage final : public ipc::StructuredCloneData { public: NS_INLINE_DECL_REFCOUNTING(SharedMessagePortMessage) - SharedMessagePortMessage() : ipc::StructuredCloneData() {} + SharedMessagePortMessage() + : ipc::StructuredCloneData(StructuredCloneScope::UnknownDestination) {} - // Note that the populated ClonedMessageData borrows the underlying + // Note that the populated MessageData borrows the underlying // JSStructuredCloneData from the SharedMessagePortMessage, so the caller is - // required to ensure that the ClonedMessageData instances are destroyed prior - // to the SharedMessagePortMessage instances. + // required to ensure that the MessageData instances are destroyed prior to + // the SharedMessagePortMessage instances. static void FromSharedToMessagesChild( MessagePortChild* aActor, const nsTArray>& aData, - nsTArray& aArray); + nsTArray& aArray); static bool FromMessagesToSharedChild( - nsTArray& aArray, + nsTArray& aArray, FallibleTArray>& aData); - // Note that the populated ClonedMessageData borrows the underlying + // Note that the populated MessageData borrows the underlying // JSStructuredCloneData from the SharedMessagePortMessage, so the caller is - // required to ensure that the ClonedMessageData instances are destroyed prior - // to the SharedMessagePortMessage instances. + // required to ensure that the MessageData instances are destroyed prior to + // the SharedMessagePortMessage instances. static bool FromSharedToMessagesParent( MessagePortParent* aActor, const nsTArray>& aData, - FallibleTArray& aArray); + FallibleTArray& aArray); static bool FromMessagesToSharedParent( - nsTArray& aArray, + nsTArray& aArray, FallibleTArray>& aData); private: - ~SharedMessagePortMessage() {} + ~SharedMessagePortMessage() = default; }; } // namespace dom diff --git a/xpcom/ds/nsTArray.h b/xpcom/ds/nsTArray.h index 10170812de6e..7daa70389d75 100644 --- a/xpcom/ds/nsTArray.h +++ b/xpcom/ds/nsTArray.h @@ -69,7 +69,8 @@ class StructuredCloneData; namespace mozilla { namespace dom { class ClonedMessageData; -class MessagePortMessage; +class MessageData; +class RefMessageData; namespace indexedDB { struct StructuredCloneReadInfo; class SerializedStructuredCloneReadInfo; @@ -721,7 +722,8 @@ DECLARE_USE_COPY_CONSTRUCTORS(mozilla::dom::indexedDB::IndexCursorResponse) DECLARE_USE_COPY_CONSTRUCTORS( mozilla::dom::indexedDB::SerializedStructuredCloneReadInfo); DECLARE_USE_COPY_CONSTRUCTORS(JSStructuredCloneData) -DECLARE_USE_COPY_CONSTRUCTORS(mozilla::dom::MessagePortMessage) +DECLARE_USE_COPY_CONSTRUCTORS(mozilla::dom::MessageData) +DECLARE_USE_COPY_CONSTRUCTORS(mozilla::dom::RefMessageData) DECLARE_USE_COPY_CONSTRUCTORS(mozilla::SourceBufferTask) //