Chromium Code Reviews| Index: third_party/WebKit/Source/bindings/core/v8/SerializedScriptValue.cpp |
| diff --git a/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValue.cpp b/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValue.cpp |
| index 1d7b0437c9ca67c6b15ccf9237442931c3473d05..9f0f6ec9d15013b65728abf7b68191f5442ef62b 100644 |
| --- a/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValue.cpp |
| +++ b/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValue.cpp |
| @@ -36,14 +36,16 @@ |
| #include "bindings/core/v8/ScriptState.h" |
| #include "bindings/core/v8/ScriptValueSerializer.h" |
| #include "bindings/core/v8/SerializedScriptValueFactory.h" |
| -#include "bindings/core/v8/TransferableArrayBuffer.h" |
| -#include "bindings/core/v8/TransferableImageBitmap.h" |
| -#include "bindings/core/v8/TransferableMessagePort.h" |
| +#include "bindings/core/v8/Transferables.h" |
| #include "bindings/core/v8/V8ArrayBuffer.h" |
| #include "bindings/core/v8/V8ImageBitmap.h" |
| #include "bindings/core/v8/V8MessagePort.h" |
| #include "bindings/core/v8/V8SharedArrayBuffer.h" |
| +#include "core/dom/DOMArrayBuffer.h" |
| +#include "core/dom/DOMSharedArrayBuffer.h" |
| #include "core/dom/ExceptionCode.h" |
| +#include "core/dom/MessagePort.h" |
| +#include "core/frame/ImageBitmap.h" |
| #include "platform/SharedBuffer.h" |
| #include "platform/blob/BlobData.h" |
| #include "platform/heap/Handle.h" |
| @@ -55,6 +57,22 @@ |
| namespace blink { |
| +SerializedScriptValue::SerializedScriptValue() |
| + : m_externallyAllocatedMemory(0) |
| +{ |
| +} |
| + |
| +SerializedScriptValue::~SerializedScriptValue() |
| +{ |
| + // If the allocated memory was not registered before, then this class is likely |
| + // used in a context other then Worker's onmessage environment and the presence of |
|
haraken
2016/04/17 23:57:21
than
sof
2016/04/18 06:41:56
reworded
|
| + // current v8 context is not guaranteed. Avoid calling v8 then. |
| + if (m_externallyAllocatedMemory) { |
| + ASSERT(v8::Isolate::GetCurrent()); |
| + v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-m_externallyAllocatedMemory); |
| + } |
| +} |
| + |
| PassRefPtr<SerializedScriptValue> SerializedScriptValue::nullValue() |
| { |
| SerializedScriptValueWriter writer; |
| @@ -82,11 +100,6 @@ void SerializedScriptValue::toWireBytes(Vector<char>& result) const |
| } |
| } |
| -SerializedScriptValue::SerializedScriptValue() |
| - : m_externallyAllocatedMemory(0) |
| -{ |
| -} |
| - |
| static void acculumateArrayBuffersForAllWorlds(v8::Isolate* isolate, DOMArrayBuffer* object, Vector<v8::Local<v8::ArrayBuffer>, 4>& buffers) |
| { |
| if (isMainThread()) { |
| @@ -104,62 +117,62 @@ static void acculumateArrayBuffersForAllWorlds(v8::Isolate* isolate, DOMArrayBuf |
| } |
| } |
| -PassOwnPtr<SerializedScriptValue::ImageBitmapContentsArray> SerializedScriptValue::createImageBitmaps(v8::Isolate* isolate, TransferableImageBitmap* transferableImageBitmaps, ExceptionState& exceptionState) |
| +void SerializedScriptValue::transferImageBitmaps(v8::Isolate* isolate, const ImageBitmapArray& imageBitmaps, ExceptionState& exceptionState) |
| { |
| - HeapVector<Member<ImageBitmap>, 1> imageBitmaps = transferableImageBitmaps->getArray(); |
| - ASSERT(imageBitmaps.size()); |
| + if (!imageBitmaps.size()) |
| + return; |
| - for (size_t i = 0; i < imageBitmaps.size(); i++) { |
| + for (size_t i = 0; i < imageBitmaps.size(); ++i) { |
| if (imageBitmaps[i]->isNeutered()) { |
| exceptionState.throwDOMException(DataCloneError, "ImageBitmap at index " + String::number(i) + " is already neutered."); |
| - return nullptr; |
| + return; |
| } |
| } |
| OwnPtr<ImageBitmapContentsArray> contents = adoptPtr(new ImageBitmapContentsArray); |
| HeapHashSet<Member<ImageBitmap>> visited; |
| - for (size_t i = 0; i < imageBitmaps.size(); i++) { |
| - if (visited.contains(imageBitmaps[i].get())) |
| + for (size_t i = 0; i < imageBitmaps.size(); ++i) { |
| + if (visited.contains(imageBitmaps[i])) |
| continue; |
| - visited.add(imageBitmaps[i].get()); |
| + visited.add(imageBitmaps[i]); |
| contents->append(imageBitmaps[i]->transfer()); |
| } |
| - return contents.release(); |
| + m_imageBitmapContentsArray = contents.release(); |
| } |
| -PassOwnPtr<SerializedScriptValue::ArrayBufferContentsArray> SerializedScriptValue::createArrayBuffers(v8::Isolate* isolate, TransferableArrayBuffer* transferableArrayBuffers, ExceptionState& exceptionState) |
| +void SerializedScriptValue::transferArrayBuffers(v8::Isolate* isolate, const ArrayBufferArray& arrayBuffers, ExceptionState& exceptionState) |
| { |
| - HeapVector<Member<DOMArrayBufferBase>, 1> arrayBuffers = transferableArrayBuffers->getArray(); |
| - ASSERT(arrayBuffers.size()); |
| + if (!arrayBuffers.size()) |
| + return; |
| - for (size_t i = 0; i < arrayBuffers.size(); i++) { |
| + for (size_t i = 0; i < arrayBuffers.size(); ++i) { |
| if (arrayBuffers[i]->isNeutered()) { |
| exceptionState.throwDOMException(DataCloneError, "ArrayBuffer at index " + String::number(i) + " is already neutered."); |
| - return nullptr; |
| + return; |
| } |
| } |
| OwnPtr<ArrayBufferContentsArray> contents = adoptPtr(new ArrayBufferContentsArray(arrayBuffers.size())); |
| HeapHashSet<Member<DOMArrayBufferBase>> visited; |
| - for (size_t i = 0; i < arrayBuffers.size(); i++) { |
| - if (visited.contains(arrayBuffers[i].get())) |
| + for (size_t i = 0; i < arrayBuffers.size(); ++i) { |
| + if (visited.contains(arrayBuffers[i])) |
| continue; |
| - visited.add(arrayBuffers[i].get()); |
| + visited.add(arrayBuffers[i]); |
| if (arrayBuffers[i]->isShared()) { |
| bool result = arrayBuffers[i]->shareContentsWith(contents->at(i)); |
| if (!result) { |
| exceptionState.throwDOMException(DataCloneError, "SharedArrayBuffer at index " + String::number(i) + " could not be transferred."); |
| - return nullptr; |
| + return; |
| } |
| } else { |
| Vector<v8::Local<v8::ArrayBuffer>, 4> bufferHandles; |
| v8::HandleScope handleScope(isolate); |
| acculumateArrayBuffersForAllWorlds(isolate, static_cast<DOMArrayBuffer*>(arrayBuffers[i].get()), bufferHandles); |
| bool isNeuterable = true; |
| - for (size_t j = 0; j < bufferHandles.size(); j++) |
| + for (size_t j = 0; j < bufferHandles.size(); ++j) |
| isNeuterable &= bufferHandles[j]->IsNeuterable(); |
| DOMArrayBufferBase* toTransfer = arrayBuffers[i]; |
| @@ -168,17 +181,16 @@ PassOwnPtr<SerializedScriptValue::ArrayBufferContentsArray> SerializedScriptValu |
| bool result = toTransfer->transfer(contents->at(i)); |
| if (!result) { |
| exceptionState.throwDOMException(DataCloneError, "ArrayBuffer at index " + String::number(i) + " could not be transferred."); |
| - return nullptr; |
| + return; |
| } |
| if (isNeuterable) |
| - for (size_t j = 0; j < bufferHandles.size(); j++) |
| + for (size_t j = 0; j < bufferHandles.size(); ++j) |
| bufferHandles[j]->Neuter(); |
| } |
| } |
| - |
| - return contents.release(); |
| + m_arrayBufferContentsArray = contents.release(); |
| } |
| SerializedScriptValue::SerializedScriptValue(const String& wireData) |
| @@ -197,12 +209,10 @@ v8::Local<v8::Value> SerializedScriptValue::deserialize(v8::Isolate* isolate, Me |
| return SerializedScriptValueFactory::instance().deserialize(this, isolate, messagePorts, blobInfo); |
| } |
| -bool SerializedScriptValue::extractTransferables(v8::Isolate* isolate, v8::Local<v8::Value> value, int argumentIndex, TransferableArray& transferables, ExceptionState& exceptionState) |
| +bool SerializedScriptValue::extractTransferables(v8::Isolate* isolate, v8::Local<v8::Value> value, int argumentIndex, Transferables& transferables, ExceptionState& exceptionState) |
| { |
| - if (isUndefinedOrNull(value)) { |
| - transferables.resize(0); |
| + if (isUndefinedOrNull(value)) |
| return true; |
| - } |
| uint32_t length = 0; |
| if (value->IsArray()) { |
| @@ -214,52 +224,48 @@ bool SerializedScriptValue::extractTransferables(v8::Isolate* isolate, v8::Local |
| return false; |
| } |
| - v8::Local<v8::Object> transferrables = v8::Local<v8::Object>::Cast(value); |
| + v8::Local<v8::Object> transferableArray = v8::Local<v8::Object>::Cast(value); |
| - // Validate the passed array of transferrables. |
| + // Validate the passed array of transferables. |
| for (unsigned i = 0; i < length; ++i) { |
| - v8::Local<v8::Value> transferrable; |
| - if (!transferrables->Get(isolate->GetCurrentContext(), i).ToLocal(&transferrable)) |
| + v8::Local<v8::Value> transferableObject; |
| + if (!transferableArray->Get(isolate->GetCurrentContext(), i).ToLocal(&transferableObject)) |
| return false; |
| // Validation of non-null objects, per HTML5 spec 10.3.3. |
| - if (isUndefinedOrNull(transferrable)) { |
| - exceptionState.throwTypeError("Value at index " + String::number(i) + " is an untransferable " + (transferrable->IsUndefined() ? "'undefined'" : "'null'") + " value."); |
| + if (isUndefinedOrNull(transferableObject)) { |
| + exceptionState.throwTypeError("Value at index " + String::number(i) + " is an untransferable " + (transferableObject->IsUndefined() ? "'undefined'" : "'null'") + " value."); |
| return false; |
| } |
| // Validation of Objects implementing an interface, per WebIDL spec 4.1.15. |
| - if (V8MessagePort::hasInstance(transferrable, isolate)) { |
| - MessagePort* port = V8MessagePort::toImpl(v8::Local<v8::Object>::Cast(transferrable)); |
| - TransferableMessagePort* ports = TransferableMessagePort::ensure(transferables); |
| + if (V8MessagePort::hasInstance(transferableObject, isolate)) { |
| + MessagePort* port = V8MessagePort::toImpl(v8::Local<v8::Object>::Cast(transferableObject)); |
| // Check for duplicate MessagePorts. |
| - if (ports->contains(port)) { |
| + if (transferables.messagePorts.contains(port)) { |
| exceptionState.throwDOMException(DataCloneError, "Message port at index " + String::number(i) + " is a duplicate of an earlier port."); |
| return false; |
| } |
| - ports->append(port); |
| - } else if (V8ArrayBuffer::hasInstance(transferrable, isolate)) { |
| - DOMArrayBuffer* arrayBuffer = V8ArrayBuffer::toImpl(v8::Local<v8::Object>::Cast(transferrable)); |
| - TransferableArrayBuffer* arrayBuffers = TransferableArrayBuffer::ensure(transferables); |
| - if (arrayBuffers->contains(arrayBuffer)) { |
| + transferables.messagePorts.append(port); |
| + } else if (V8ArrayBuffer::hasInstance(transferableObject, isolate)) { |
| + DOMArrayBuffer* arrayBuffer = V8ArrayBuffer::toImpl(v8::Local<v8::Object>::Cast(transferableObject)); |
| + if (transferables.arrayBuffers.contains(arrayBuffer)) { |
| exceptionState.throwDOMException(DataCloneError, "ArrayBuffer at index " + String::number(i) + " is a duplicate of an earlier ArrayBuffer."); |
| return false; |
| } |
| - arrayBuffers->append(arrayBuffer); |
| - } else if (V8SharedArrayBuffer::hasInstance(transferrable, isolate)) { |
| - DOMSharedArrayBuffer* sharedArrayBuffer = V8SharedArrayBuffer::toImpl(v8::Local<v8::Object>::Cast(transferrable)); |
| - TransferableArrayBuffer* arrayBuffers = TransferableArrayBuffer::ensure(transferables); |
| - if (arrayBuffers->contains(sharedArrayBuffer)) { |
| + transferables.arrayBuffers.append(arrayBuffer); |
| + } else if (V8SharedArrayBuffer::hasInstance(transferableObject, isolate)) { |
| + DOMSharedArrayBuffer* sharedArrayBuffer = V8SharedArrayBuffer::toImpl(v8::Local<v8::Object>::Cast(transferableObject)); |
| + if (transferables.arrayBuffers.contains(sharedArrayBuffer)) { |
| exceptionState.throwDOMException(DataCloneError, "SharedArrayBuffer at index " + String::number(i) + " is a duplicate of an earlier SharedArrayBuffer."); |
| return false; |
| } |
| - arrayBuffers->append(sharedArrayBuffer); |
| - } else if (V8ImageBitmap::hasInstance(transferrable, isolate)) { |
| - ImageBitmap* imageBitmap = V8ImageBitmap::toImpl(v8::Local<v8::Object>::Cast(transferrable)); |
| - TransferableImageBitmap* imageBitmaps = TransferableImageBitmap::ensure(transferables); |
| - if (imageBitmaps->contains(imageBitmap)) { |
| + transferables.arrayBuffers.append(sharedArrayBuffer); |
| + } else if (V8ImageBitmap::hasInstance(transferableObject, isolate)) { |
| + ImageBitmap* imageBitmap = V8ImageBitmap::toImpl(v8::Local<v8::Object>::Cast(transferableObject)); |
| + if (transferables.imageBitmaps.contains(imageBitmap)) { |
| exceptionState.throwDOMException(DataCloneError, "ImageBitmap at index " + String::number(i) + " is a duplicate of an earlier ImageBitmap."); |
| return false; |
| } |
| - imageBitmaps->append(imageBitmap); |
| + transferables.imageBitmaps.append(imageBitmap); |
| } else { |
| exceptionState.throwTypeError("Value at index " + String::number(i) + " does not have a transferable type."); |
| return false; |
| @@ -281,25 +287,4 @@ bool SerializedScriptValue::containsTransferableArrayBuffer() const |
| return m_arrayBufferContentsArray && !m_arrayBufferContentsArray->isEmpty(); |
| } |
| -SerializedScriptValue::~SerializedScriptValue() |
| -{ |
| - // If the allocated memory was not registered before, then this class is likely |
| - // used in a context other then Worker's onmessage environment and the presence of |
| - // current v8 context is not guaranteed. Avoid calling v8 then. |
| - if (m_externallyAllocatedMemory) { |
| - ASSERT(v8::Isolate::GetCurrent()); |
| - v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-m_externallyAllocatedMemory); |
| - } |
| -} |
| - |
| -void SerializedScriptValue::transferArrayBuffers(v8::Isolate* isolate, TransferableArrayBuffer* transferableArrayBuffers, ExceptionState& exceptionState) |
| -{ |
| - m_arrayBufferContentsArray = createArrayBuffers(isolate, transferableArrayBuffers, exceptionState); |
| -} |
| - |
| -void SerializedScriptValue::transferImageBitmaps(v8::Isolate* isolate, TransferableImageBitmap* transferableImageBitmaps, ExceptionState& exceptionState) |
| -{ |
| - m_imageBitmapContentsArray = createImageBitmaps(isolate, transferableImageBitmaps, exceptionState); |
| -} |
| - |
| } // namespace blink |