From 6137b7ed317aef42e36e0db2fc901570131961ba Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Fri, 1 Aug 2014 22:47:47 +0200 Subject: [PATCH] Bug 1043853 - Share the code for structured cloning of ImageData objects across main-thread and workers implementations; r=jst --- dom/base/nsJSEnvironment.cpp | 37 +++------------------ dom/bindings/StructuredClone.cpp | 56 ++++++++++++++++++++++++++++++++ dom/bindings/StructuredClone.h | 25 ++++++++++++++ dom/bindings/moz.build | 5 +++ dom/workers/WorkerPrivate.cpp | 33 ++----------------- 5 files changed, 94 insertions(+), 62 deletions(-) create mode 100644 dom/bindings/StructuredClone.cpp create mode 100644 dom/bindings/StructuredClone.h diff --git a/dom/base/nsJSEnvironment.cpp b/dom/base/nsJSEnvironment.cpp index 860b8602e5e..b277404b8cd 100644 --- a/dom/base/nsJSEnvironment.cpp +++ b/dom/base/nsJSEnvironment.cpp @@ -54,10 +54,11 @@ #include "nsScriptNameSpaceManager.h" #include "StructuredCloneTags.h" #include "mozilla/AutoRestore.h" -#include "mozilla/dom/ErrorEvent.h" -#include "mozilla/dom/ImageData.h" #include "mozilla/dom/CryptoKey.h" +#include "mozilla/dom/ErrorEvent.h" #include "mozilla/dom/ImageDataBinding.h" +#include "mozilla/dom/ImageData.h" +#include "mozilla/dom/StructuredClone.h" #include "mozilla/dom/SubtleCryptoBinding.h" #include "nsAXPCNativeCallContext.h" #include "mozilla/CycleCollectedJSRuntime.h" @@ -2811,25 +2812,7 @@ NS_DOMReadStructuredClone(JSContext* cx, void* closure) { if (tag == SCTAG_DOM_IMAGEDATA) { - // Read the information out of the stream. - uint32_t width, height; - JS::Rooted dataArray(cx); - if (!JS_ReadUint32Pair(reader, &width, &height) || - !JS_ReadTypedArray(reader, &dataArray)) { - return nullptr; - } - MOZ_ASSERT(dataArray.isObject()); - - // Protect the result from a moving GC in ~nsRefPtr. - JS::Rooted result(cx); - { - // Construct the ImageData. - nsRefPtr imageData = new ImageData(width, height, - dataArray.toObject()); - // Wrap it in a JS::Value. - result = imageData->WrapObject(cx); - } - return result; + return ReadStructuredCloneImageData(cx, reader); } else if (tag == SCTAG_DOM_WEBCRYPTO_KEY) { nsIGlobalObject *global = xpc::GetNativeForGlobal(JS::CurrentGlobalOrNull(cx)); if (!global) { @@ -2863,17 +2846,7 @@ NS_DOMWriteStructuredClone(JSContext* cx, // Handle ImageData cloning ImageData* imageData; if (NS_SUCCEEDED(UNWRAP_OBJECT(ImageData, obj, imageData))) { - // Prepare the ImageData internals. - uint32_t width = imageData->Width(); - uint32_t height = imageData->Height(); - JS::Rooted dataArray(cx, imageData->GetDataObject()); - - // Write the internals to the stream. - JSAutoCompartment ac(cx, dataArray); - JS::Rooted arrayValue(cx, JS::ObjectValue(*dataArray)); - return JS_WriteUint32Pair(writer, SCTAG_DOM_IMAGEDATA, 0) && - JS_WriteUint32Pair(writer, width, height) && - JS_WriteTypedArray(writer, arrayValue); + return WriteStructuredCloneImageData(cx, writer, imageData); } // Handle Key cloning diff --git a/dom/bindings/StructuredClone.cpp b/dom/bindings/StructuredClone.cpp new file mode 100644 index 00000000000..b191a1d472d --- /dev/null +++ b/dom/bindings/StructuredClone.cpp @@ -0,0 +1,56 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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 "mozilla/dom/StructuredClone.h" + +#include "js/StructuredClone.h" +#include "mozilla/dom/ImageData.h" +#include "mozilla/dom/StructuredCloneTags.h" + +namespace mozilla { +namespace dom { + +JSObject* +ReadStructuredCloneImageData(JSContext* aCx, JSStructuredCloneReader* aReader) +{ + // Read the information out of the stream. + uint32_t width, height; + JS::Rooted dataArray(aCx); + if (!JS_ReadUint32Pair(aReader, &width, &height) || + !JS_ReadTypedArray(aReader, &dataArray)) { + return nullptr; + } + MOZ_ASSERT(dataArray.isObject()); + + // Protect the result from a moving GC in ~nsRefPtr. + JS::Rooted result(aCx); + { + // Construct the ImageData. + nsRefPtr imageData = new ImageData(width, height, + dataArray.toObject()); + // Wrap it in a JS::Value. + result = imageData->WrapObject(aCx); + } + return result; +} + +bool +WriteStructuredCloneImageData(JSContext* aCx, JSStructuredCloneWriter* aWriter, + ImageData* aImageData) +{ + uint32_t width = aImageData->Width(); + uint32_t height = aImageData->Height(); + JS::Rooted dataArray(aCx, aImageData->GetDataObject()); + + JSAutoCompartment ac(aCx, dataArray); + JS::Rooted arrayValue(aCx, JS::ObjectValue(*dataArray)); + return JS_WriteUint32Pair(aWriter, SCTAG_DOM_IMAGEDATA, 0) && + JS_WriteUint32Pair(aWriter, width, height) && + JS_WriteTypedArray(aWriter, arrayValue); +} + +} // namespace dom +} // namespace mozilla diff --git a/dom/bindings/StructuredClone.h b/dom/bindings/StructuredClone.h new file mode 100644 index 00000000000..bfd7700c6d0 --- /dev/null +++ b/dom/bindings/StructuredClone.h @@ -0,0 +1,25 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +class JSObject; +struct JSContext; +struct JSStructuredCloneReader; +struct JSStructuredCloneWriter; + +namespace mozilla { +namespace dom { + +class ImageData; + +JSObject* +ReadStructuredCloneImageData(JSContext* aCx, JSStructuredCloneReader* aReader); + +bool +WriteStructuredCloneImageData(JSContext* aCx, JSStructuredCloneWriter* aWriter, + ImageData* aImageData); + +} // namespace dom +} // namespace mozilla diff --git a/dom/bindings/moz.build b/dom/bindings/moz.build index 874903c977a..261cce6bb5b 100644 --- a/dom/bindings/moz.build +++ b/dom/bindings/moz.build @@ -30,6 +30,7 @@ EXPORTS.mozilla.dom += [ 'OwningNonNull.h', 'PrimitiveConversions.h', 'RootedDictionary.h', + 'StructuredClone.h', 'ToJSValue.h', 'TypedArray.h', 'UnionMember.h', @@ -81,6 +82,10 @@ UNIFIED_SOURCES += [ 'ToJSValue.cpp', ] +SOURCES += [ + 'StructuredClone.cpp', +] + include('/ipc/chromium/chromium-config.mozbuild') if CONFIG['MOZ_AUDIO_CHANNEL_MANAGER']: diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp index 1a66a34e1f7..7e9f174f117 100644 --- a/dom/workers/WorkerPrivate.cpp +++ b/dom/workers/WorkerPrivate.cpp @@ -48,6 +48,7 @@ #include "mozilla/dom/MessageEventBinding.h" #include "mozilla/dom/MessagePortList.h" #include "mozilla/dom/ScriptSettings.h" +#include "mozilla/dom/StructuredClone.h" #include "mozilla/dom/WorkerBinding.h" #include "mozilla/Preferences.h" #include "nsAlgorithm.h" @@ -352,25 +353,7 @@ struct WorkerStructuredCloneCallbacks // See if the object is an ImageData. else if (aTag == SCTAG_DOM_IMAGEDATA) { MOZ_ASSERT(!aData); - - // Read the information out of the stream. - uint32_t width, height; - JS::Rooted dataArray(aCx); - if (!JS_ReadUint32Pair(aReader, &width, &height) || - !JS_ReadTypedArray(aReader, &dataArray)) - { - return nullptr; - } - MOZ_ASSERT(dataArray.isObject()); - - { - // Construct the ImageData. - nsRefPtr imageData = new ImageData(width, height, - dataArray.toObject()); - // Wrap it in a JS::Value, protected from a moving GC during ~nsRefPtr. - result = imageData->WrapObject(aCx); - } - return result; + return ReadStructuredCloneImageData(aCx, aReader); } Error(aCx, 0); @@ -418,17 +401,7 @@ struct WorkerStructuredCloneCallbacks { ImageData* imageData = nullptr; if (NS_SUCCEEDED(UNWRAP_OBJECT(ImageData, aObj, imageData))) { - // Prepare the ImageData internals. - uint32_t width = imageData->Width(); - uint32_t height = imageData->Height(); - JS::Rooted dataArray(aCx, imageData->GetDataObject()); - - // Write the internals to the stream. - JSAutoCompartment ac(aCx, dataArray); - JS::Rooted arrayValue(aCx, JS::ObjectValue(*dataArray)); - return JS_WriteUint32Pair(aWriter, SCTAG_DOM_IMAGEDATA, 0) && - JS_WriteUint32Pair(aWriter, width, height) && - JS_WriteTypedArray(aWriter, arrayValue); + return WriteStructuredCloneImageData(aCx, aWriter, imageData); } }