| 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
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..e9cc6004379947a93fbd686d9120d4e16139dae5
|
| --- /dev/null
|
| +++ b/third_party/WebKit/Source/bindings/core/v8/serialization/V8ScriptValueSerializer.cpp
|
| @@ -0,0 +1,88 @@
|
| +// Copyright 2016 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "bindings/core/v8/serialization/V8ScriptValueSerializer.h"
|
| +
|
| +#include "bindings/core/v8/ToV8.h"
|
| +#include "core/dom/DOMArrayBufferBase.h"
|
| +#include "platform/RuntimeEnabledFeatures.h"
|
| +
|
| +namespace blink {
|
| +
|
| +V8ScriptValueSerializer::V8ScriptValueSerializer(RefPtr<ScriptState> scriptState)
|
| + : m_scriptState(std::move(scriptState))
|
| + , m_serializedScriptValue(SerializedScriptValue::create())
|
| + , m_serializer(m_scriptState->isolate())
|
| +{
|
| + DCHECK(RuntimeEnabledFeatures::v8BasedStructuredCloneEnabled());
|
| +}
|
| +
|
| +RefPtr<SerializedScriptValue> V8ScriptValueSerializer::serialize(v8::Local<v8::Value> value, Transferables* transferables, ExceptionState& exceptionState)
|
| +{
|
| +#if DCHECK_IS_ON()
|
| + DCHECK(!m_serializeInvoked);
|
| + m_serializeInvoked = true;
|
| +#endif
|
| + DCHECK(m_serializedScriptValue);
|
| + ScriptState::Scope scope(m_scriptState.get());
|
| +
|
| + // Prepare to transfer the provided transferables.
|
| + transfer(transferables, exceptionState);
|
| + if (exceptionState.hadException()) {
|
| + return nullptr;
|
| + }
|
| +
|
| + // Serialize the value and handle errors.
|
| + v8::TryCatch tryCatch(m_scriptState->isolate());
|
| + m_serializer.WriteHeader();
|
| + bool wroteValue;
|
| + if (!m_serializer.WriteValue(m_scriptState->context(), value).To(&wroteValue)) {
|
| + DCHECK(tryCatch.HasCaught());
|
| + exceptionState.rethrowV8Exception(tryCatch.Exception());
|
| + return nullptr;
|
| + }
|
| + if (!wroteValue) {
|
| + DCHECK(!tryCatch.HasCaught());
|
| + exceptionState.throwDOMException(DataCloneError, "An object could not be cloned.");
|
| + return nullptr;
|
| + }
|
| +
|
| + // Finalize the results.
|
| + std::vector<uint8_t> buffer = m_serializer.ReleaseBuffer();
|
| + // Currently, the output must be padded to a multiple of two bytes.
|
| + // TODO(jbroman): Remove this old conversion to WTF::String.
|
| + if (buffer.size() % 2)
|
| + buffer.push_back(0);
|
| + m_serializedScriptValue->setData(
|
| + String(reinterpret_cast<const UChar*>(&buffer[0]), buffer.size() / 2));
|
| + return std::move(m_serializedScriptValue);
|
| +}
|
| +
|
| +void V8ScriptValueSerializer::transfer(Transferables* transferables, ExceptionState& exceptionState)
|
| +{
|
| + if (!transferables)
|
| + return;
|
| + v8::Isolate* isolate = m_scriptState->isolate();
|
| + v8::Local<v8::Context> context = m_scriptState->context();
|
| +
|
| + // Transfer array buffers.
|
| + m_serializedScriptValue->transferArrayBuffers(isolate, transferables->arrayBuffers, exceptionState);
|
| + if (exceptionState.hadException())
|
| + return;
|
| + for (uint32_t i = 0; i < transferables->arrayBuffers.size(); i++) {
|
| + DOMArrayBufferBase* arrayBuffer = transferables->arrayBuffers[i].get();
|
| + v8::Local<v8::Value> wrapper = toV8(arrayBuffer, context->Global(), isolate);
|
| + if (wrapper->IsArrayBuffer()) {
|
| + 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.";
|
| + }
|
| + }
|
| +}
|
| +
|
| +} // namespace blink
|
|
|