diff options
Diffstat (limited to 'dom/base/nsContentUtils.cpp')
-rw-r--r-- | dom/base/nsContentUtils.cpp | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index 990e1bc589..86e52984af 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -47,6 +47,7 @@ #include "mozilla/dom/HTMLTemplateElement.h" #include "mozilla/dom/ipc/BlobChild.h" #include "mozilla/dom/ipc/BlobParent.h" +#include "mozilla/dom/MessagePort.h" #include "mozilla/dom/Promise.h" #include "mozilla/dom/ScriptSettings.h" #include "mozilla/dom/TabParent.h" @@ -9991,3 +9992,71 @@ nsContentUtils::GetClosestNonNativeAnonymousAncestor(Element* aElement) } return e; } + +/* static */ nsresult +nsContentUtils::CreateJSValueFromSequenceOfObject(JSContext* aCx, + const Sequence<JSObject*>& aTransfer, + JS::MutableHandle<JS::Value> aValue) +{ + if (aTransfer.IsEmpty()) { + return NS_OK; + } + + JS::Rooted<JSObject*> array(aCx, JS_NewArrayObject(aCx, aTransfer.Length())); + if (!array) { + return NS_ERROR_OUT_OF_MEMORY; + } + + for (uint32_t i = 0; i < aTransfer.Length(); ++i) { + JS::Rooted<JSObject*> object(aCx, aTransfer[i]); + if (!object) { + continue; + } + + if (NS_WARN_IF(!JS_DefineElement(aCx, array, i, object, + JSPROP_ENUMERATE))) { + return NS_ERROR_OUT_OF_MEMORY; + } + } + + aValue.setObject(*array); + return NS_OK; +} + +/* static */ +void nsContentUtils::StructuredClone(JSContext* aCx, + nsIGlobalObject* aGlobal, + JS::Handle<JS::Value> aValue, + const StructuredSerializeOptions& aOptions, + JS::MutableHandle<JS::Value> aRv, + ErrorResult& aError) { + JS::Rooted<JS::Value> transferArray(aCx, JS::UndefinedValue()); + aError = nsContentUtils::CreateJSValueFromSequenceOfObject( + aCx, aOptions.mTransfer, &transferArray); + if (NS_WARN_IF(aError.Failed())) { + return; + } + + JS::CloneDataPolicy clonePolicy; + // FIXME: Uncomment once bug 1609990 and bug 1611855 lands. + //clonePolicy.allowIntraClusterClonableSharedObjects(); + //clonePolicy.allowSharedMemoryObjects(); + + StructuredCloneHolder holder(StructuredCloneHolder::CloningSupported, + StructuredCloneHolder::TransferringSupported, + JS::StructuredCloneScope::SameProcessDifferentThread); + holder.Write(aCx, aValue, transferArray, clonePolicy, aError); + if (NS_WARN_IF(aError.Failed())) { + return; + } + + // TODO: Pass clonePolicy. + //holder.Read(this, aCx, aRv, clonePolicy, aError); + holder.Read(aGlobal, aCx, aRv, aError); + if (NS_WARN_IF(aError.Failed())) { + return; + } + + nsTArray<RefPtr<MessagePort>> ports = holder.TakeTransferredPorts(); + Unused << ports; +} |