blob: ab73504600c4e1904e6e32165d97ed9929e207b2 [file] [log] [blame]
// 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.
#ifndef THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SERIALIZATION_V8_SCRIPT_VALUE_SERIALIZER_H_
#define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SERIALIZATION_V8_SCRIPT_VALUE_SERIALIZER_H_
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialization_tag.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_color_params.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
#include "v8/include/v8.h"
namespace blink {
class File;
class Transferables;
// Serializes V8 values according to the HTML structured clone algorithm:
// https://html.spec.whatwg.org/C/#structured-clone
//
// Supports only basic JavaScript objects and core DOM types. Support for
// modules types is implemented in a subclass.
//
// A serializer cannot be used multiple times; it is expected that its serialize
// method will be invoked exactly once.
class CORE_EXPORT V8ScriptValueSerializer
: public v8::ValueSerializer::Delegate {
STACK_ALLOCATED();
public:
using Options = SerializedScriptValue::SerializeOptions;
explicit V8ScriptValueSerializer(ScriptState*, const Options& = Options());
scoped_refptr<SerializedScriptValue> Serialize(v8::Local<v8::Value>,
ExceptionState&);
protected:
// Returns true if the DOM object was successfully written.
// If false is returned and no more specific exception is thrown, a generic
// DataCloneError message will be used.
virtual bool WriteDOMObject(ScriptWrappable*, ExceptionState&);
ScriptState* GetScriptState() const { return script_state_; }
void WriteTag(SerializationTag tag) {
uint8_t tag_byte = tag;
serializer_.WriteRawBytes(&tag_byte, 1);
}
void WriteUint32(uint32_t value) { serializer_.WriteUint32(value); }
void WriteUint64(uint64_t value) { serializer_.WriteUint64(value); }
void WriteDouble(double value) { serializer_.WriteDouble(value); }
void WriteRawBytes(const void* data, size_t size) {
serializer_.WriteRawBytes(data, size);
}
void WriteUTF8String(const String&);
template <typename E>
void WriteUint32Enum(E value) {
static_assert(
std::is_enum<E>::value &&
std::is_same<uint32_t,
typename std::underlying_type<E>::type>::value,
"Only enums backed by uint32_t are accepted.");
WriteUint32(static_cast<uint32_t>(value));
}
SerializedScriptValue* GetSerializedScriptValue() {
return serialized_script_value_.get();
}
bool IsForStorage() const { return for_storage_; }
private:
// Transfer is split into two phases: scanning the transferables so that we
// don't have to serialize the data (just an index), and finalizing (to
// neuter objects in the source context).
// This separation is required by the spec (it prevents neutering from
// happening if there's a failure earlier in serialization).
void PrepareTransfer(ExceptionState&);
void FinalizeTransfer(ExceptionState&);
// Shared between File and FileList logic; does not write a leading tag.
bool WriteFile(File*, ExceptionState&);
// v8::ValueSerializer::Delegate
void ThrowDataCloneError(v8::Local<v8::String> message) override;
v8::Maybe<bool> WriteHostObject(v8::Isolate*,
v8::Local<v8::Object> message) override;
v8::Maybe<uint32_t> GetSharedArrayBufferId(
v8::Isolate*,
v8::Local<v8::SharedArrayBuffer>) override;
v8::Maybe<uint32_t> GetWasmModuleTransferId(
v8::Isolate*,
v8::Local<v8::WasmModuleObject>) override;
// Reallocates memory at |ptr| to the new size and returns the new pointer or
// nullptr on failure. |actual_size| will hold the actual size of allocation
// requested.
void* ReallocateBufferMemory(void* old_buffer,
size_t,
size_t* actual_size) override;
void FreeBufferMemory(void* buffer) override;
bool TransferableStreamsEnabled() const;
ScriptState* script_state_;
scoped_refptr<SerializedScriptValue> serialized_script_value_;
v8::ValueSerializer serializer_;
const Transferables* transferables_ = nullptr;
const ExceptionState* exception_state_ = nullptr;
WebBlobInfoArray* blob_info_array_ = nullptr;
SharedArrayBufferArray shared_array_buffers_;
Options::WasmSerializationPolicy wasm_policy_;
bool for_storage_ = false;
#if DCHECK_IS_ON()
bool serialize_invoked_ = false;
#endif
DISALLOW_COPY_AND_ASSIGN(V8ScriptValueSerializer);
};
// For code testing V8ScriptValueSerializer
scoped_refptr<SerializedScriptValue> SerializedValue(
const Vector<uint8_t>& bytes);
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SERIALIZATION_V8_SCRIPT_VALUE_SERIALIZER_H_