| 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
|
| deleted file mode 100644
|
| index 249ac584b9ee231221f07daa6537ff2e10b2421c..0000000000000000000000000000000000000000
|
| --- a/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValue.cpp
|
| +++ /dev/null
|
| @@ -1,537 +0,0 @@
|
| -/*
|
| - * Copyright (C) 2010 Google Inc. All rights reserved.
|
| - *
|
| - * Redistribution and use in source and binary forms, with or without
|
| - * modification, are permitted provided that the following conditions are
|
| - * met:
|
| - *
|
| - * * Redistributions of source code must retain the above copyright
|
| - * notice, this list of conditions and the following disclaimer.
|
| - * * Redistributions in binary form must reproduce the above
|
| - * copyright notice, this list of conditions and the following disclaimer
|
| - * in the documentation and/or other materials provided with the
|
| - * distribution.
|
| - * * Neither the name of Google Inc. nor the names of its
|
| - * contributors may be used to endorse or promote products derived from
|
| - * this software without specific prior written permission.
|
| - *
|
| - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
| - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
| - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
| - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
| - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
| - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
| - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
| - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
| - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
| - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
| - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
| - */
|
| -
|
| -#include "bindings/core/v8/SerializedScriptValue.h"
|
| -
|
| -#include <memory>
|
| -#include "bindings/core/v8/ExceptionState.h"
|
| -#include "bindings/core/v8/IDLTypes.h"
|
| -#include "bindings/core/v8/NativeValueTraitsImpl.h"
|
| -#include "bindings/core/v8/SerializationTag.h"
|
| -#include "bindings/core/v8/SerializedScriptValueFactory.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/V8OffscreenCanvas.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/bindings/DOMDataStore.h"
|
| -#include "platform/bindings/DOMWrapperWorld.h"
|
| -#include "platform/bindings/ScriptState.h"
|
| -#include "platform/blob/BlobData.h"
|
| -#include "platform/heap/Handle.h"
|
| -#include "platform/wtf/Assertions.h"
|
| -#include "platform/wtf/ByteOrder.h"
|
| -#include "platform/wtf/PtrUtil.h"
|
| -#include "platform/wtf/Vector.h"
|
| -#include "platform/wtf/dtoa/utils.h"
|
| -#include "platform/wtf/text/StringBuffer.h"
|
| -#include "platform/wtf/text/StringHash.h"
|
| -
|
| -namespace blink {
|
| -
|
| -PassRefPtr<SerializedScriptValue> SerializedScriptValue::Serialize(
|
| - v8::Isolate* isolate,
|
| - v8::Local<v8::Value> value,
|
| - const SerializeOptions& options,
|
| - ExceptionState& exception) {
|
| - return SerializedScriptValueFactory::Instance().Create(isolate, value,
|
| - options, exception);
|
| -}
|
| -
|
| -PassRefPtr<SerializedScriptValue>
|
| -SerializedScriptValue::SerializeAndSwallowExceptions(
|
| - v8::Isolate* isolate,
|
| - v8::Local<v8::Value> value) {
|
| - DummyExceptionStateForTesting exception_state;
|
| - RefPtr<SerializedScriptValue> serialized =
|
| - Serialize(isolate, value, SerializeOptions(), exception_state);
|
| - if (exception_state.HadException())
|
| - return NullValue();
|
| - return serialized.Release();
|
| -}
|
| -
|
| -PassRefPtr<SerializedScriptValue> SerializedScriptValue::Create() {
|
| - return AdoptRef(new SerializedScriptValue);
|
| -}
|
| -
|
| -PassRefPtr<SerializedScriptValue> SerializedScriptValue::Create(
|
| - const String& data) {
|
| - return AdoptRef(new SerializedScriptValue(data));
|
| -}
|
| -
|
| -// Versions 16 and below (prior to April 2017) used ntohs() to byte-swap SSV
|
| -// data when converting it to the wire format. This was a historical accient.
|
| -//
|
| -// As IndexedDB stores SSVs to disk indefinitely, we still need to keep around
|
| -// the code needed to deserialize the old format.
|
| -inline static bool IsByteSwappedWiredData(const char* data, size_t length) {
|
| - // TODO(pwnall): Return false early if we're on big-endian hardware. Chromium
|
| - // doesn't currently support big-endian hardware, and there's no header
|
| - // exposing endianness to Blink yet. ARCH_CPU_LITTLE_ENDIAN seems promising,
|
| - // but Blink is not currently allowed to include files from build/.
|
| -
|
| - // The first SSV version without byte-swapping has two envelopes (Blink, V8),
|
| - // each of which is at least 2 bytes long.
|
| - if (length < 4)
|
| - return true;
|
| -
|
| - // This code handles the following cases:
|
| - //
|
| - // v0 (byte-swapped) - [d, t, ...], t = tag byte, d = first data byte
|
| - // v1-16 (byte-swapped) - [v, 0xFF, ...], v = version (1 <= v <= 16)
|
| - // v17+ - [0xFF, v, ...], v = first byte of version varint
|
| -
|
| - if (static_cast<uint8_t>(data[0]) == kVersionTag) {
|
| - // The only case where byte-swapped data can have 0xFF in byte zero is
|
| - // version 0. This can only happen if byte one is a tag (supported in
|
| - // version 0) that takes in extra data, and the first byte of extra data is
|
| - // 0xFF. There are 13 such tags, listed below. These tags cannot be used as
|
| - // version numbers in the Blink-side SSV envelope.
|
| - //
|
| - // 35 - 0x23 - # - ImageDataTag
|
| - // 64 - 0x40 - @ - SparseArrayTag
|
| - // 68 - 0x44 - D - DateTag
|
| - // 73 - 0x49 - I - Int32Tag
|
| - // 78 - 0x4E - N - NumberTag
|
| - // 82 - 0x52 - R - RegExpTag
|
| - // 83 - 0x53 - S - StringTag
|
| - // 85 - 0x55 - U - Uint32Tag
|
| - // 91 - 0x5B - [ - ArrayTag
|
| - // 98 - 0x62 - b - BlobTag
|
| - // 102 - 0x66 - f - FileTag
|
| - // 108 - 0x6C - l - FileListTag
|
| - // 123 - 0x7B - { - ObjectTag
|
| - //
|
| - // Why we care about version 0:
|
| - //
|
| - // IndexedDB stores values using the SSV format. Currently, IndexedDB does
|
| - // not do any sort of migration, so a value written with a SSV version will
|
| - // be stored with that version until it is removed via an update or delete.
|
| - //
|
| - // IndexedDB was shipped in Chrome 11, which was released on April 27, 2011.
|
| - // SSV version 1 was added in WebKit r91698, which was shipped in Chrome 14,
|
| - // which was released on September 16, 2011.
|
| - static_assert(
|
| - SerializedScriptValue::kWireFormatVersion != 35 &&
|
| - SerializedScriptValue::kWireFormatVersion != 64 &&
|
| - SerializedScriptValue::kWireFormatVersion != 68 &&
|
| - SerializedScriptValue::kWireFormatVersion != 73 &&
|
| - SerializedScriptValue::kWireFormatVersion != 78 &&
|
| - SerializedScriptValue::kWireFormatVersion != 82 &&
|
| - SerializedScriptValue::kWireFormatVersion != 83 &&
|
| - SerializedScriptValue::kWireFormatVersion != 85 &&
|
| - SerializedScriptValue::kWireFormatVersion != 91 &&
|
| - SerializedScriptValue::kWireFormatVersion != 98 &&
|
| - SerializedScriptValue::kWireFormatVersion != 102 &&
|
| - SerializedScriptValue::kWireFormatVersion != 108 &&
|
| - SerializedScriptValue::kWireFormatVersion != 123,
|
| - "Using a burned version will prevent us from reading SSV version 0");
|
| -
|
| - // Fast path until the Blink-side SSV envelope reaches version 35.
|
| - if (SerializedScriptValue::kWireFormatVersion < 35) {
|
| - if (static_cast<uint8_t>(data[1]) < 35)
|
| - return false;
|
| -
|
| - // TODO(pwnall): Add UMA metric here.
|
| - return true;
|
| - }
|
| -
|
| - // Slower path that would kick in after version 35, assuming we don't remove
|
| - // support for SSV version 0 by then.
|
| - static constexpr uint8_t version0Tags[] = {35, 64, 68, 73, 78, 82, 83,
|
| - 85, 91, 98, 102, 108, 123};
|
| - return std::find(std::begin(version0Tags), std::end(version0Tags),
|
| - data[1]) != std::end(version0Tags);
|
| - }
|
| -
|
| - if (static_cast<uint8_t>(data[1]) == kVersionTag) {
|
| - // The last SSV format that used byte-swapping was version 16. The version
|
| - // number is stored (before byte-swapping) after a serialization tag, which
|
| - // is 0xFF.
|
| - return static_cast<uint8_t>(data[0]) != kVersionTag;
|
| - }
|
| -
|
| - // If kVersionTag isn't in any of the first two bytes, this is SSV version 0,
|
| - // which was byte-swapped.
|
| - return true;
|
| -}
|
| -
|
| -PassRefPtr<SerializedScriptValue> SerializedScriptValue::Create(
|
| - const char* data,
|
| - size_t length) {
|
| - if (!data)
|
| - return Create();
|
| -
|
| - DCHECK(!(length % sizeof(UChar)));
|
| - const UChar* src = reinterpret_cast<const UChar*>(data);
|
| - size_t string_length = length / sizeof(UChar);
|
| -
|
| - if (IsByteSwappedWiredData(data, length)) {
|
| - // Decode wire data from big endian to host byte order.
|
| - StringBuffer<UChar> buffer(string_length);
|
| - UChar* dst = buffer.Characters();
|
| - for (size_t i = 0; i < string_length; ++i)
|
| - dst[i] = ntohs(src[i]);
|
| -
|
| - return AdoptRef(new SerializedScriptValue(String::Adopt(buffer)));
|
| - }
|
| -
|
| - return AdoptRef(new SerializedScriptValue(String(src, string_length)));
|
| -}
|
| -
|
| -SerializedScriptValue::SerializedScriptValue()
|
| - : has_registered_external_allocation_(false),
|
| - transferables_need_external_allocation_registration_(false) {}
|
| -
|
| -SerializedScriptValue::SerializedScriptValue(const String& wire_data)
|
| - : has_registered_external_allocation_(false),
|
| - transferables_need_external_allocation_registration_(false) {
|
| - size_t byte_length = wire_data.length() * 2;
|
| - data_buffer_.reset(static_cast<uint8_t*>(WTF::Partitions::BufferMalloc(
|
| - byte_length, "SerializedScriptValue buffer")));
|
| - data_buffer_size_ = byte_length;
|
| - wire_data.CopyTo(reinterpret_cast<UChar*>(data_buffer_.get()), 0,
|
| - wire_data.length());
|
| -}
|
| -
|
| -SerializedScriptValue::~SerializedScriptValue() {
|
| - // If the allocated memory was not registered before, then this class is
|
| - // likely used in a context other than Worker's onmessage environment and the
|
| - // presence of current v8 context is not guaranteed. Avoid calling v8 then.
|
| - if (has_registered_external_allocation_) {
|
| - DCHECK(v8::Isolate::GetCurrent());
|
| - v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(
|
| - -static_cast<int64_t>(DataLengthInBytes()));
|
| - }
|
| -}
|
| -
|
| -PassRefPtr<SerializedScriptValue> SerializedScriptValue::NullValue() {
|
| - // The format here may fall a bit out of date, because we support
|
| - // deserializing SSVs written by old browser versions.
|
| - static const uint8_t kNullData[] = {0xFF, 17, 0xFF, 13, '0', 0x00};
|
| - return Create(reinterpret_cast<const char*>(kNullData), sizeof(kNullData));
|
| -}
|
| -
|
| -String SerializedScriptValue::ToWireString() const {
|
| - // Add the padding '\0', but don't put it in |m_dataBuffer|.
|
| - // This requires direct use of uninitialized strings, though.
|
| - UChar* destination;
|
| - size_t string_size_bytes = (data_buffer_size_ + 1) & ~1;
|
| - String wire_string =
|
| - String::CreateUninitialized(string_size_bytes / 2, destination);
|
| - memcpy(destination, data_buffer_.get(), data_buffer_size_);
|
| - if (string_size_bytes > data_buffer_size_)
|
| - reinterpret_cast<char*>(destination)[string_size_bytes - 1] = '\0';
|
| - return wire_string;
|
| -}
|
| -
|
| -void SerializedScriptValue::ToWireBytes(Vector<char>& result) const {
|
| - DCHECK(result.IsEmpty());
|
| -
|
| - size_t result_size = (data_buffer_size_ + 1) & ~1;
|
| - result.resize(result_size);
|
| - memcpy(result.data(), data_buffer_.get(), data_buffer_size_);
|
| -
|
| - if (result_size > data_buffer_size_) {
|
| - DCHECK_EQ(result_size, data_buffer_size_ + 1);
|
| - result[data_buffer_size_] = 0;
|
| - }
|
| -}
|
| -
|
| -std::unique_ptr<SerializedScriptValue::ImageBitmapContentsArray>
|
| -SerializedScriptValue::TransferImageBitmapContents(
|
| - v8::Isolate* isolate,
|
| - const ImageBitmapArray& image_bitmaps,
|
| - ExceptionState& exception_state) {
|
| - if (!image_bitmaps.size())
|
| - return nullptr;
|
| -
|
| - for (size_t i = 0; i < image_bitmaps.size(); ++i) {
|
| - if (image_bitmaps[i]->IsNeutered()) {
|
| - exception_state.ThrowDOMException(
|
| - kDataCloneError, "ImageBitmap at index " + String::Number(i) +
|
| - " is already detached.");
|
| - return nullptr;
|
| - }
|
| - }
|
| -
|
| - std::unique_ptr<ImageBitmapContentsArray> contents =
|
| - WTF::WrapUnique(new ImageBitmapContentsArray);
|
| - HeapHashSet<Member<ImageBitmap>> visited;
|
| - for (size_t i = 0; i < image_bitmaps.size(); ++i) {
|
| - if (visited.Contains(image_bitmaps[i]))
|
| - continue;
|
| - visited.insert(image_bitmaps[i]);
|
| - contents->push_back(image_bitmaps[i]->Transfer());
|
| - }
|
| - return contents;
|
| -}
|
| -
|
| -void SerializedScriptValue::TransferImageBitmaps(
|
| - v8::Isolate* isolate,
|
| - const ImageBitmapArray& image_bitmaps,
|
| - ExceptionState& exception_state) {
|
| - std::unique_ptr<ImageBitmapContentsArray> contents =
|
| - TransferImageBitmapContents(isolate, image_bitmaps, exception_state);
|
| - image_bitmap_contents_array_ = std::move(contents);
|
| -}
|
| -
|
| -void SerializedScriptValue::TransferOffscreenCanvas(
|
| - v8::Isolate* isolate,
|
| - const OffscreenCanvasArray& offscreen_canvases,
|
| - ExceptionState& exception_state) {
|
| - if (!offscreen_canvases.size())
|
| - return;
|
| -
|
| - HeapHashSet<Member<OffscreenCanvas>> visited;
|
| - for (size_t i = 0; i < offscreen_canvases.size(); i++) {
|
| - if (visited.Contains(offscreen_canvases[i].Get()))
|
| - continue;
|
| - if (offscreen_canvases[i]->IsNeutered()) {
|
| - exception_state.ThrowDOMException(
|
| - kDataCloneError, "OffscreenCanvas at index " + String::Number(i) +
|
| - " is already detached.");
|
| - return;
|
| - }
|
| - if (offscreen_canvases[i]->RenderingContext()) {
|
| - exception_state.ThrowDOMException(
|
| - kDataCloneError, "OffscreenCanvas at index " + String::Number(i) +
|
| - " has an associated context.");
|
| - return;
|
| - }
|
| - visited.insert(offscreen_canvases[i].Get());
|
| - offscreen_canvases[i].Get()->SetNeutered();
|
| - }
|
| -}
|
| -
|
| -void SerializedScriptValue::TransferArrayBuffers(
|
| - v8::Isolate* isolate,
|
| - const ArrayBufferArray& array_buffers,
|
| - ExceptionState& exception_state) {
|
| - array_buffer_contents_array_ =
|
| - TransferArrayBufferContents(isolate, array_buffers, exception_state);
|
| -}
|
| -
|
| -v8::Local<v8::Value> SerializedScriptValue::Deserialize(
|
| - v8::Isolate* isolate,
|
| - const DeserializeOptions& options) {
|
| - return SerializedScriptValueFactory::Instance().Deserialize(this, isolate,
|
| - options);
|
| -}
|
| -
|
| -bool SerializedScriptValue::ExtractTransferables(
|
| - v8::Isolate* isolate,
|
| - v8::Local<v8::Value> value,
|
| - int argument_index,
|
| - Transferables& transferables,
|
| - ExceptionState& exception_state) {
|
| - if (value.IsEmpty() || value->IsUndefined())
|
| - return true;
|
| -
|
| - Vector<v8::Local<v8::Value>> transferable_array =
|
| - NativeValueTraits<IDLSequence<v8::Local<v8::Value>>>::NativeValue(
|
| - isolate, value, exception_state);
|
| - if (exception_state.HadException())
|
| - return false;
|
| -
|
| - // Validate the passed array of transferables.
|
| - uint32_t i = 0;
|
| - for (const auto& transferable_object : transferable_array) {
|
| - // Validation of non-null objects, per HTML5 spec 10.3.3.
|
| - if (IsUndefinedOrNull(transferable_object)) {
|
| - exception_state.ThrowTypeError(
|
| - "Value at index " + String::Number(i) + " is an untransferable " +
|
| - (transferable_object->IsUndefined() ? "'undefined'" : "'null'") +
|
| - " value.");
|
| - return false;
|
| - }
|
| - // Validation of Objects implementing an interface, per WebIDL spec 4.1.15.
|
| - if (V8MessagePort::hasInstance(transferable_object, isolate)) {
|
| - MessagePort* port = V8MessagePort::toImpl(
|
| - v8::Local<v8::Object>::Cast(transferable_object));
|
| - // Check for duplicate MessagePorts.
|
| - if (transferables.message_ports.Contains(port)) {
|
| - exception_state.ThrowDOMException(
|
| - kDataCloneError, "Message port at index " + String::Number(i) +
|
| - " is a duplicate of an earlier port.");
|
| - return false;
|
| - }
|
| - transferables.message_ports.push_back(port);
|
| - } else if (transferable_object->IsArrayBuffer()) {
|
| - DOMArrayBuffer* array_buffer = V8ArrayBuffer::toImpl(
|
| - v8::Local<v8::Object>::Cast(transferable_object));
|
| - if (transferables.array_buffers.Contains(array_buffer)) {
|
| - exception_state.ThrowDOMException(
|
| - kDataCloneError, "ArrayBuffer at index " + String::Number(i) +
|
| - " is a duplicate of an earlier ArrayBuffer.");
|
| - return false;
|
| - }
|
| - transferables.array_buffers.push_back(array_buffer);
|
| - } else if (transferable_object->IsSharedArrayBuffer()) {
|
| - DOMSharedArrayBuffer* shared_array_buffer = V8SharedArrayBuffer::toImpl(
|
| - v8::Local<v8::Object>::Cast(transferable_object));
|
| - if (transferables.array_buffers.Contains(shared_array_buffer)) {
|
| - exception_state.ThrowDOMException(
|
| - kDataCloneError,
|
| - "SharedArrayBuffer at index " + String::Number(i) +
|
| - " is a duplicate of an earlier SharedArrayBuffer.");
|
| - return false;
|
| - }
|
| - transferables.array_buffers.push_back(shared_array_buffer);
|
| - } else if (V8ImageBitmap::hasInstance(transferable_object, isolate)) {
|
| - ImageBitmap* image_bitmap = V8ImageBitmap::toImpl(
|
| - v8::Local<v8::Object>::Cast(transferable_object));
|
| - if (transferables.image_bitmaps.Contains(image_bitmap)) {
|
| - exception_state.ThrowDOMException(
|
| - kDataCloneError, "ImageBitmap at index " + String::Number(i) +
|
| - " is a duplicate of an earlier ImageBitmap.");
|
| - return false;
|
| - }
|
| - transferables.image_bitmaps.push_back(image_bitmap);
|
| - } else if (V8OffscreenCanvas::hasInstance(transferable_object, isolate)) {
|
| - OffscreenCanvas* offscreen_canvas = V8OffscreenCanvas::toImpl(
|
| - v8::Local<v8::Object>::Cast(transferable_object));
|
| - if (transferables.offscreen_canvases.Contains(offscreen_canvas)) {
|
| - exception_state.ThrowDOMException(
|
| - kDataCloneError,
|
| - "OffscreenCanvas at index " + String::Number(i) +
|
| - " is a duplicate of an earlier OffscreenCanvas.");
|
| - return false;
|
| - }
|
| - transferables.offscreen_canvases.push_back(offscreen_canvas);
|
| - } else {
|
| - exception_state.ThrowTypeError("Value at index " + String::Number(i) +
|
| - " does not have a transferable type.");
|
| - return false;
|
| - }
|
| - i++;
|
| - }
|
| - return true;
|
| -}
|
| -
|
| -std::unique_ptr<SerializedScriptValue::ArrayBufferContentsArray>
|
| -SerializedScriptValue::TransferArrayBufferContents(
|
| - v8::Isolate* isolate,
|
| - const ArrayBufferArray& array_buffers,
|
| - ExceptionState& exception_state) {
|
| - if (!array_buffers.size())
|
| - return nullptr;
|
| -
|
| - for (auto it = array_buffers.begin(); it != array_buffers.end(); ++it) {
|
| - DOMArrayBufferBase* array_buffer = *it;
|
| - if (array_buffer->IsNeutered()) {
|
| - size_t index = std::distance(array_buffers.begin(), it);
|
| - exception_state.ThrowDOMException(
|
| - kDataCloneError, "ArrayBuffer at index " + String::Number(index) +
|
| - " is already neutered.");
|
| - return nullptr;
|
| - }
|
| - }
|
| -
|
| - std::unique_ptr<ArrayBufferContentsArray> contents =
|
| - WTF::WrapUnique(new ArrayBufferContentsArray(array_buffers.size()));
|
| -
|
| - HeapHashSet<Member<DOMArrayBufferBase>> visited;
|
| - for (auto it = array_buffers.begin(); it != array_buffers.end(); ++it) {
|
| - DOMArrayBufferBase* array_buffer_base = *it;
|
| - if (visited.Contains(array_buffer_base))
|
| - continue;
|
| - visited.insert(array_buffer_base);
|
| -
|
| - size_t index = std::distance(array_buffers.begin(), it);
|
| - if (array_buffer_base->IsShared()) {
|
| - DOMSharedArrayBuffer* shared_array_buffer =
|
| - static_cast<DOMSharedArrayBuffer*>(array_buffer_base);
|
| - if (!shared_array_buffer->ShareContentsWith(contents->at(index))) {
|
| - exception_state.ThrowDOMException(kDataCloneError,
|
| - "SharedArrayBuffer at index " +
|
| - String::Number(index) +
|
| - " could not be transferred.");
|
| - return nullptr;
|
| - }
|
| - } else {
|
| - DOMArrayBuffer* array_buffer =
|
| - static_cast<DOMArrayBuffer*>(array_buffer_base);
|
| -
|
| - if (!array_buffer->Transfer(isolate, contents->at(index))) {
|
| - exception_state.ThrowDOMException(
|
| - kDataCloneError, "ArrayBuffer at index " + String::Number(index) +
|
| - " could not be transferred.");
|
| - return nullptr;
|
| - }
|
| - }
|
| - }
|
| - return contents;
|
| -}
|
| -
|
| -void SerializedScriptValue::
|
| - UnregisterMemoryAllocatedWithCurrentScriptContext() {
|
| - if (has_registered_external_allocation_) {
|
| - v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(
|
| - -static_cast<int64_t>(DataLengthInBytes()));
|
| - has_registered_external_allocation_ = false;
|
| - }
|
| -
|
| - // TODO: if other transferables start accounting for their external
|
| - // allocations with V8, extend this with corresponding cases.
|
| - if (array_buffer_contents_array_ &&
|
| - !transferables_need_external_allocation_registration_) {
|
| - for (auto& buffer : *array_buffer_contents_array_)
|
| - buffer.UnregisterExternalAllocationWithCurrentContext();
|
| - transferables_need_external_allocation_registration_ = true;
|
| - }
|
| -}
|
| -
|
| -void SerializedScriptValue::RegisterMemoryAllocatedWithCurrentScriptContext() {
|
| - if (has_registered_external_allocation_)
|
| - return;
|
| -
|
| - has_registered_external_allocation_ = true;
|
| - int64_t diff = static_cast<int64_t>(DataLengthInBytes());
|
| - DCHECK_GE(diff, 0);
|
| - v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(diff);
|
| -
|
| - // Only (re)register allocation cost for transferables if this
|
| - // SerializedScriptValue has explicitly unregistered them before.
|
| - if (array_buffer_contents_array_ &&
|
| - transferables_need_external_allocation_registration_) {
|
| - for (auto& buffer : *array_buffer_contents_array_)
|
| - buffer.RegisterExternalAllocationWithCurrentContext();
|
| - }
|
| -}
|
| -
|
| -} // namespace blink
|
|
|