Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(107)

Unified Diff: third_party/WebKit/Source/bindings/core/v8/SerializedScriptValue.cpp

Issue 2414333003: WebMessaging: Send transferable ArrayBuffers by copy-and-neuter semantics (Closed)
Patch Set: fix tests Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 55c8776877b810a98581050cde04171b953437c2..06c7575aa6c00319bba040d5281568a38eba5b7a 100644
--- a/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValue.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValue.cpp
@@ -149,7 +149,7 @@ void SerializedScriptValue::toWireBytes(Vector<char>& result) const {
}
}
-static void acculumateArrayBuffersForAllWorlds(
+static void accumulateArrayBuffersForAllWorlds(
v8::Isolate* isolate,
DOMArrayBuffer* object,
Vector<v8::Local<v8::ArrayBuffer>, 4>& buffers) {
@@ -230,64 +230,8 @@ void SerializedScriptValue::transferArrayBuffers(
v8::Isolate* isolate,
const ArrayBufferArray& arrayBuffers,
ExceptionState& exceptionState) {
- if (!arrayBuffers.size())
- return;
-
- 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;
- }
- }
-
- std::unique_ptr<ArrayBufferContentsArray> contents =
- wrapUnique(new ArrayBufferContentsArray(arrayBuffers.size()));
-
- HeapHashSet<Member<DOMArrayBufferBase>> visited;
- for (size_t i = 0; i < arrayBuffers.size(); ++i) {
- if (visited.contains(arrayBuffers[i]))
- continue;
- 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;
- }
- } 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)
- isNeuterable &= bufferHandles[j]->IsNeuterable();
-
- DOMArrayBufferBase* toTransfer = arrayBuffers[i];
- if (!isNeuterable)
- toTransfer =
- DOMArrayBuffer::create(arrayBuffers[i]->buffer()->data(),
- arrayBuffers[i]->buffer()->byteLength());
- bool result = toTransfer->transfer(contents->at(i));
- if (!result) {
- exceptionState.throwDOMException(
- DataCloneError, "ArrayBuffer at index " + String::number(i) +
- " could not be transferred.");
- return;
- }
-
- if (isNeuterable)
- for (size_t j = 0; j < bufferHandles.size(); ++j)
- bufferHandles[j]->Neuter();
- }
- }
- m_arrayBufferContentsArray = std::move(contents);
+ m_arrayBufferContentsArray =
+ transferArrayBufferContents(isolate, arrayBuffers, exceptionState);
}
v8::Local<v8::Value> SerializedScriptValue::deserialize(
@@ -402,6 +346,74 @@ bool SerializedScriptValue::extractTransferables(
return true;
}
+std::unique_ptr<ArrayBufferContentsArray>
+SerializedScriptValue::transferArrayBufferContents(
+ v8::Isolate* isolate,
+ const ArrayBufferArray& arrayBuffers,
+ ExceptionState& exceptionState) {
+ if (!arrayBuffers.size())
+ return nullptr;
+
+ for (auto it = arrayBuffers.begin(); it != arrayBuffers.end(); ++it) {
+ DOMArrayBufferBase* arrayBuffer = *it;
+ if (arrayBuffer->isNeutered()) {
+ size_t index = std::distance(arrayBuffers.begin(), it);
+ exceptionState.throwDOMException(
+ DataCloneError, "ArrayBuffer at index " + String::number(index) +
+ " is already neutered.");
+ return nullptr;
+ }
+ }
+
+ std::unique_ptr<ArrayBufferContentsArray> contents =
+ wrapUnique(new ArrayBufferContentsArray(arrayBuffers.size()));
+
+ HeapHashSet<Member<DOMArrayBufferBase>> visited;
+ for (auto it = arrayBuffers.begin(); it != arrayBuffers.end(); ++it) {
+ DOMArrayBufferBase* arrayBuffer = *it;
+ if (visited.contains(arrayBuffer))
+ continue;
+ visited.add(arrayBuffer);
+
+ size_t index = std::distance(arrayBuffers.begin(), it);
+ if (arrayBuffer->isShared()) {
+ if (!arrayBuffer->shareContentsWith(contents->at(index))) {
+ exceptionState.throwDOMException(DataCloneError,
+ "SharedArrayBuffer at index " +
+ String::number(index) +
+ " could not be transferred.");
+ return nullptr;
+ }
+ } else {
+ Vector<v8::Local<v8::ArrayBuffer>, 4> bufferHandles;
+ v8::HandleScope handleScope(isolate);
+ accumulateArrayBuffersForAllWorlds(
+ isolate, static_cast<DOMArrayBuffer*>(it->get()), bufferHandles);
+ bool isNeuterable = true;
+ for (const auto& bufferHandle : bufferHandles)
+ isNeuterable &= bufferHandle->IsNeuterable();
+
+ DOMArrayBufferBase* toTransfer = arrayBuffer;
+ if (!isNeuterable) {
+ toTransfer = DOMArrayBuffer::create(
+ arrayBuffer->buffer()->data(), arrayBuffer->buffer()->byteLength());
+ }
+ if (!toTransfer->transfer(contents->at(index))) {
+ exceptionState.throwDOMException(
+ DataCloneError, "ArrayBuffer at index " + String::number(index) +
+ " could not be transferred.");
+ return nullptr;
+ }
+
+ if (isNeuterable) {
+ for (const auto& bufferHandle : bufferHandles)
+ bufferHandle->Neuter();
+ }
+ }
+ }
+ return contents;
+}
+
void SerializedScriptValue::registerMemoryAllocatedWithCurrentScriptContext() {
if (m_externallyAllocatedMemory)
return;
@@ -410,8 +422,4 @@ void SerializedScriptValue::registerMemoryAllocatedWithCurrentScriptContext() {
m_externallyAllocatedMemory);
}
-bool SerializedScriptValue::containsTransferableArrayBuffer() const {
- return m_arrayBufferContentsArray && !m_arrayBufferContentsArray->isEmpty();
-}
-
} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698