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) { |