| Index: third_party/WebKit/Source/bindings/core/v8/serialization/V8ScriptValueSerializer.cpp
|
| diff --git a/third_party/WebKit/Source/bindings/core/v8/serialization/V8ScriptValueSerializer.cpp b/third_party/WebKit/Source/bindings/core/v8/serialization/V8ScriptValueSerializer.cpp
|
| index 73467e8317664329fb8f28710fb802f7267796d3..817d36ef6f26ed2ff76b92ce8b3d7923ad10e8c8 100644
|
| --- a/third_party/WebKit/Source/bindings/core/v8/serialization/V8ScriptValueSerializer.cpp
|
| +++ b/third_party/WebKit/Source/bindings/core/v8/serialization/V8ScriptValueSerializer.cpp
|
| @@ -13,6 +13,7 @@
|
| #include "bindings/core/v8/V8ImageData.h"
|
| #include "bindings/core/v8/V8MessagePort.h"
|
| #include "bindings/core/v8/V8OffscreenCanvas.h"
|
| +#include "bindings/core/v8/V8SharedArrayBuffer.h"
|
| #include "core/dom/DOMArrayBufferBase.h"
|
| #include "core/html/ImageData.h"
|
| #include "platform/RuntimeEnabledFeatures.h"
|
| @@ -44,7 +45,9 @@ RefPtr<SerializedScriptValue> V8ScriptValueSerializer::serialize(
|
| AutoReset<const ExceptionState*> reset(&m_exceptionState, &exceptionState);
|
|
|
| // Prepare to transfer the provided transferables.
|
| - prepareTransfer(transferables);
|
| + prepareTransfer(transferables, exceptionState);
|
| + if (exceptionState.hadException())
|
| + return nullptr;
|
|
|
| // Serialize the value and handle errors.
|
| v8::TryCatch tryCatch(m_scriptState->isolate());
|
| @@ -70,7 +73,8 @@ RefPtr<SerializedScriptValue> V8ScriptValueSerializer::serialize(
|
| return std::move(m_serializedScriptValue);
|
| }
|
|
|
| -void V8ScriptValueSerializer::prepareTransfer(Transferables* transferables) {
|
| +void V8ScriptValueSerializer::prepareTransfer(Transferables* transferables,
|
| + ExceptionState& exceptionState) {
|
| if (!transferables)
|
| return;
|
| m_transferables = transferables;
|
| @@ -78,30 +82,33 @@ void V8ScriptValueSerializer::prepareTransfer(Transferables* transferables) {
|
| // Transfer array buffers.
|
| for (uint32_t i = 0; i < transferables->arrayBuffers.size(); i++) {
|
| DOMArrayBufferBase* arrayBuffer = transferables->arrayBuffers[i].get();
|
| - v8::Local<v8::Value> wrapper = ToV8(arrayBuffer, m_scriptState.get());
|
| - if (wrapper->IsArrayBuffer()) {
|
| + if (!arrayBuffer->isShared()) {
|
| + v8::Local<v8::Value> wrapper = ToV8(arrayBuffer, m_scriptState.get());
|
| m_serializer.TransferArrayBuffer(
|
| i, v8::Local<v8::ArrayBuffer>::Cast(wrapper));
|
| - } else if (wrapper->IsSharedArrayBuffer()) {
|
| - m_serializer.TransferSharedArrayBuffer(
|
| - i, v8::Local<v8::SharedArrayBuffer>::Cast(wrapper));
|
| } else {
|
| - NOTREACHED() << "Unknown type of array buffer in transfer list.";
|
| + exceptionState.throwDOMException(
|
| + DataCloneError, "SharedArrayBuffer can not be in transfer list.");
|
| + return;
|
| }
|
| }
|
| }
|
|
|
| void V8ScriptValueSerializer::finalizeTransfer(ExceptionState& exceptionState) {
|
| - if (!m_transferables)
|
| + if (!m_transferables && m_sharedArrayBuffers.isEmpty())
|
| return;
|
|
|
| // TODO(jbroman): Strictly speaking, this is not correct; transfer should
|
| // occur in the order of the transfer list.
|
| // https://html.spec.whatwg.org/multipage/infrastructure.html#structuredclonewithtransfer
|
|
|
| + ArrayBufferArray arrayBuffers;
|
| + arrayBuffers.appendVector(m_transferables->arrayBuffers);
|
| + arrayBuffers.appendVector(m_sharedArrayBuffers);
|
| +
|
| v8::Isolate* isolate = m_scriptState->isolate();
|
| - m_serializedScriptValue->transferArrayBuffers(
|
| - isolate, m_transferables->arrayBuffers, exceptionState);
|
| + m_serializedScriptValue->transferArrayBuffers(isolate, arrayBuffers,
|
| + exceptionState);
|
| if (exceptionState.hadException())
|
| return;
|
|
|
| @@ -366,6 +373,34 @@ v8::Maybe<bool> V8ScriptValueSerializer::WriteHostObject(
|
| return v8::Nothing<bool>();
|
| }
|
|
|
| +v8::Maybe<uint32_t> V8ScriptValueSerializer::GetSharedArrayBufferId(
|
| + v8::Isolate* isolate,
|
| + v8::Local<v8::SharedArrayBuffer> v8SharedArrayBuffer) {
|
| + DOMSharedArrayBuffer* sharedArrayBuffer =
|
| + V8SharedArrayBuffer::toImpl(v8SharedArrayBuffer);
|
| +
|
| + // The index returned from this function will be serialized into the data
|
| + // stream. When deserializing, this will be used to index into the
|
| + // arrayBufferContents array of the SerializedScriptValue.
|
| + //
|
| + // The v8::ValueSerializer will use the same index space for transferred
|
| + // ArrayBuffers, but those will all occur first, because their indexes are
|
| + // generated in order via v8::ValueSerializer::TransferArrayBuffer (see
|
| + // prepareTransfer above).
|
| + //
|
| + // So we offset all SharedArrayBuffer indexes by the number of transferred
|
| + // ArrayBuffers.
|
| + size_t index = m_sharedArrayBuffers.find(sharedArrayBuffer);
|
| + if (index == kNotFound) {
|
| + m_sharedArrayBuffers.append(sharedArrayBuffer);
|
| + index = m_sharedArrayBuffers.size() - 1;
|
| + }
|
| + if (m_transferables) {
|
| + index += m_transferables->arrayBuffers.size();
|
| + }
|
| + return v8::Just<uint32_t>(index);
|
| +}
|
| +
|
| void* V8ScriptValueSerializer::ReallocateBufferMemory(void* oldBuffer,
|
| size_t size,
|
| size_t* actualSize) {
|
|
|