chromium/v8/src/objects/value-serializer.cc

// Copyright 2016 the V8 project 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 "src/objects/value-serializer.h"

#include <type_traits>

#include "include/v8-maybe.h"
#include "include/v8-value-serializer-version.h"
#include "include/v8-value-serializer.h"
#include "include/v8-wasm.h"
#include "src/api/api-inl.h"
#include "src/base/logging.h"
#include "src/base/platform/memory.h"
#include "src/execution/isolate.h"
#include "src/flags/flags.h"
#include "src/handles/global-handles-inl.h"
#include "src/handles/handles-inl.h"
#include "src/handles/maybe-handles-inl.h"
#include "src/handles/shared-object-conveyor-handles.h"
#include "src/heap/factory.h"
#include "src/numbers/conversions.h"
#include "src/objects/heap-number-inl.h"
#include "src/objects/js-array-buffer-inl.h"
#include "src/objects/js-array-buffer.h"
#include "src/objects/js-array-inl.h"
#include "src/objects/js-collection-inl.h"
#include "src/objects/js-regexp-inl.h"
#include "src/objects/js-shared-array-inl.h"
#include "src/objects/js-struct-inl.h"
#include "src/objects/map-updater.h"
#include "src/objects/objects-inl.h"
#include "src/objects/objects.h"
#include "src/objects/oddball-inl.h"
#include "src/objects/ordered-hash-table-inl.h"
#include "src/objects/property-descriptor.h"
#include "src/objects/property-details.h"
#include "src/objects/smi.h"
#include "src/objects/transitions-inl.h"
#include "src/regexp/regexp.h"
#include "src/snapshot/code-serializer.h"

#if V8_ENABLE_WEBASSEMBLY
#include "src/wasm/wasm-objects-inl.h"
#endif  // V8_ENABLE_WEBASSEMBLY

namespace v8 {
namespace internal {

// WARNING: This serialization format MUST remain backward compatible!
//
// This format is used by APIs to persist values to disk, e.g. IndexedDB.
//
// Backward compatibility means that when the format changes, deserializing
// valid values in the older format must behave identically as before the
// change. To maintain compatibility, either a format change does not affect the
// deserializing behavior of valid values in the older format, or the
// kLatestVersion constant is bumped.
//
// Adding a new tag is backwards compatible because no valid serialized value in
// older formats would contain the new object tag.
//
// On the other hand, changing the format of a particular tag is backwards
// incompatible and the version must be bumped. For example, a JSArrayBufferView
// tag prior to version 14 was followed by the sub-tag, the byte offset, and the
// byte length. Starting with version 14, a JSArrayBufferView tag is followed by
// the sub-tag, the byte offset, the byte length, and flags. Due the addition of
// flags, older valid serialized values for JSArrayBufferViews would be
// misinterpreted by newer deserializers. This requires the version to be bumped
// and the deserializer to handle both the old and new formats depending on the
// version.

// Version 9: (imported from Blink)
// Version 10: one-byte (Latin-1) strings
// Version 11: properly separate undefined from the hole in arrays
// Version 12: regexp and string objects share normal string encoding
// Version 13: host objects have an explicit tag (rather than handling all
//             unknown tags)
// Version 14: flags for JSArrayBufferViews
// Version 15: support for shared objects with an explicit tag
//
// WARNING: Increasing this value is a change which cannot safely be rolled
// back without breaking compatibility with data stored on disk. It is
// strongly recommended that you do not make such changes near a release
// milestone branch point.
//
// Recent changes are routinely reverted in preparation for branch, and this
// has been the cause of at least one bug in the past.
static const uint32_t kLatestVersion =;
static_assert;

namespace {
// For serializing JSArrayBufferView flags. Instead of serializing /
// deserializing the flags directly, we serialize them bit by bit. This is for
// ensuring backwards compatibility in the case where the representation
// changes. Note that the ValueSerializer data can be stored on disk.
using JSArrayBufferViewIsLengthTracking = base::BitField<bool, 0, 1>;
using JSArrayBufferViewIsBackedByRab =
    JSArrayBufferViewIsLengthTracking::Next<bool, 1>;

}  // namespace

template <typename T>
static size_t BytesNeededForVarint(T value) {}

enum class SerializationTag : uint8_t {};

namespace {

enum class ArrayBufferViewTag : uint8_t {};

// Sub-tags only meaningful for error serialization.
enum class ErrorTag : uint8_t {};

}  // namespace

ValueSerializer::ValueSerializer(Isolate* isolate,
                                 v8::ValueSerializer::Delegate* delegate)
    :{}

ValueSerializer::~ValueSerializer() {}

void ValueSerializer::WriteHeader() {}

void ValueSerializer::SetTreatArrayBufferViewsAsHostObjects(bool mode) {}

void ValueSerializer::WriteTag(SerializationTag tag) {}

template <typename T>
void ValueSerializer::WriteVarint(T value) {}

template <typename T>
void ValueSerializer::WriteZigZag(T value) {}

template EXPORT_TEMPLATE_DEFINE() void ValueSerializer::WriteZigZag(int32_t value);

void ValueSerializer::WriteDouble(double value) {}

void ValueSerializer::WriteOneByteString(base::Vector<const uint8_t> chars) {}

void ValueSerializer::WriteTwoByteString(base::Vector<const base::uc16> chars) {}

void ValueSerializer::WriteBigIntContents(Tagged<BigInt> bigint) {}

void ValueSerializer::WriteRawBytes(const void* source, size_t length) {}

Maybe<uint8_t*> ValueSerializer::ReserveRawBytes(size_t bytes) {}

Maybe<bool> ValueSerializer::ExpandBuffer(size_t required_capacity) {}

void ValueSerializer::WriteByte(uint8_t value) {}

void ValueSerializer::WriteUint32(uint32_t value) {}

void ValueSerializer::WriteUint64(uint64_t value) {}

std::pair<uint8_t*, size_t> ValueSerializer::Release() {}

void ValueSerializer::TransferArrayBuffer(
    uint32_t transfer_id, DirectHandle<JSArrayBuffer> array_buffer) {}

Maybe<bool> ValueSerializer::WriteObject(Handle<Object> object) {}

void ValueSerializer::WriteOddball(Tagged<Oddball> oddball) {}

void ValueSerializer::WriteSmi(Tagged<Smi> smi) {}

void ValueSerializer::WriteHeapNumber(Tagged<HeapNumber> number) {}

void ValueSerializer::WriteBigInt(Tagged<BigInt> bigint) {}

void ValueSerializer::WriteString(Handle<String> string) {}

Maybe<bool> ValueSerializer::WriteJSReceiver(Handle<JSReceiver> receiver) {}

Maybe<bool> ValueSerializer::WriteJSObject(Handle<JSObject> object) {}

Maybe<bool> ValueSerializer::WriteJSObjectSlow(Handle<JSObject> object) {}

Maybe<bool> ValueSerializer::WriteJSArray(Handle<JSArray> array) {}

void ValueSerializer::WriteJSDate(Tagged<JSDate> date) {}

Maybe<bool> ValueSerializer::WriteJSPrimitiveWrapper(
    DirectHandle<JSPrimitiveWrapper> value) {}

void ValueSerializer::WriteJSRegExp(DirectHandle<JSRegExp> regexp) {}

Maybe<bool> ValueSerializer::WriteJSMap(DirectHandle<JSMap> js_map) {}

Maybe<bool> ValueSerializer::WriteJSSet(DirectHandle<JSSet> js_set) {}

Maybe<bool> ValueSerializer::WriteJSArrayBuffer(
    Handle<JSArrayBuffer> array_buffer) {}

Maybe<bool> ValueSerializer::WriteJSArrayBufferView(
    Tagged<JSArrayBufferView> view) {}

Maybe<bool> ValueSerializer::WriteJSError(Handle<JSObject> error) {}

Maybe<bool> ValueSerializer::WriteJSSharedStruct(
    DirectHandle<JSSharedStruct> shared_struct) {}

Maybe<bool> ValueSerializer::WriteJSSharedArray(
    DirectHandle<JSSharedArray> shared_array) {}

#if V8_ENABLE_WEBASSEMBLY
Maybe<bool> ValueSerializer::WriteWasmModule(Handle<WasmModuleObject> object) {}

Maybe<bool> ValueSerializer::WriteWasmMemory(
    DirectHandle<WasmMemoryObject> object) {}
#endif  // V8_ENABLE_WEBASSEMBLY

Maybe<bool> ValueSerializer::WriteSharedObject(
    DirectHandle<HeapObject> object) {}

Maybe<bool> ValueSerializer::WriteHostObject(Handle<JSObject> object) {}

Maybe<uint32_t> ValueSerializer::WriteJSObjectPropertiesSlow(
    Handle<JSObject> object, DirectHandle<FixedArray> keys) {}

Maybe<bool> ValueSerializer::IsHostObject(Handle<JSObject> js_object) {}

Maybe<bool> ValueSerializer::ThrowIfOutOfMemory() {}

Maybe<bool> ValueSerializer::ThrowDataCloneError(
    MessageTemplate template_index) {}

Maybe<bool> ValueSerializer::ThrowDataCloneError(MessageTemplate index,
                                                 DirectHandle<Object> arg0) {}

ValueDeserializer::ValueDeserializer(Isolate* isolate,
                                     base::Vector<const uint8_t> data,
                                     v8::ValueDeserializer::Delegate* delegate)
    :{}

ValueDeserializer::ValueDeserializer(Isolate* isolate, const uint8_t* data,
                                     size_t size)
    :{}

ValueDeserializer::~ValueDeserializer() {}

Maybe<bool> ValueDeserializer::ReadHeader() {}

Maybe<SerializationTag> ValueDeserializer::PeekTag() const {}

void ValueDeserializer::ConsumeTag(SerializationTag peeked_tag) {}

Maybe<SerializationTag> ValueDeserializer::ReadTag() {}

template <typename T>
Maybe<T> ValueDeserializer::ReadVarint() {}

template <typename T>
Maybe<T> ValueDeserializer::ReadVarintLoop() {}

template <typename T>
Maybe<T> ValueDeserializer::ReadZigZag() {}

template EXPORT_TEMPLATE_DEFINE() Maybe<int32_t> ValueDeserializer::ReadZigZag();

Maybe<double> ValueDeserializer::ReadDouble() {}

Maybe<base::Vector<const uint8_t>> ValueDeserializer::ReadRawBytes(
    size_t size) {}

bool ValueDeserializer::ReadByte(uint8_t* value) {}

bool ValueDeserializer::ReadUint32(uint32_t* value) {}

bool ValueDeserializer::ReadUint64(uint64_t* value) {}

bool ValueDeserializer::ReadDouble(double* value) {}

bool ValueDeserializer::ReadRawBytes(size_t length, const void** data) {}

void ValueDeserializer::TransferArrayBuffer(
    uint32_t transfer_id, Handle<JSArrayBuffer> array_buffer) {}

MaybeHandle<Object> ValueDeserializer::ReadObjectWrapper() {}

MaybeHandle<Object> ValueDeserializer::ReadObject() {}

MaybeHandle<Object> ValueDeserializer::ReadObjectInternal() {}

MaybeHandle<String> ValueDeserializer::ReadString() {}

MaybeHandle<BigInt> ValueDeserializer::ReadBigInt() {}

MaybeHandle<String> ValueDeserializer::ReadUtf8String(
    AllocationType allocation) {}

MaybeHandle<String> ValueDeserializer::ReadOneByteString(
    AllocationType allocation) {}

MaybeHandle<String> ValueDeserializer::ReadTwoByteString(
    AllocationType allocation) {}

MaybeHandle<JSObject> ValueDeserializer::ReadJSObject() {}

MaybeHandle<JSArray> ValueDeserializer::ReadSparseJSArray() {}

MaybeHandle<JSArray> ValueDeserializer::ReadDenseJSArray() {}

MaybeHandle<JSDate> ValueDeserializer::ReadJSDate() {}

MaybeHandle<JSPrimitiveWrapper> ValueDeserializer::ReadJSPrimitiveWrapper(
    SerializationTag tag) {}

MaybeHandle<JSRegExp> ValueDeserializer::ReadJSRegExp() {}

MaybeHandle<JSMap> ValueDeserializer::ReadJSMap() {}

MaybeHandle<JSSet> ValueDeserializer::ReadJSSet() {}

MaybeHandle<JSArrayBuffer> ValueDeserializer::ReadJSArrayBuffer(
    bool is_shared, bool is_resizable) {}

MaybeHandle<JSArrayBuffer> ValueDeserializer::ReadTransferredJSArrayBuffer() {}

MaybeHandle<JSArrayBufferView> ValueDeserializer::ReadJSArrayBufferView(
    DirectHandle<JSArrayBuffer> buffer) {}

bool ValueDeserializer::ValidateJSArrayBufferViewFlags(
    Tagged<JSArrayBuffer> buffer, uint32_t serialized_flags,
    bool& is_length_tracking, bool& is_backed_by_rab) {}

MaybeHandle<Object> ValueDeserializer::ReadJSError() {}

#if V8_ENABLE_WEBASSEMBLY
MaybeHandle<JSObject> ValueDeserializer::ReadWasmModuleTransfer() {}

MaybeHandle<WasmMemoryObject> ValueDeserializer::ReadWasmMemory() {}
#endif  // V8_ENABLE_WEBASSEMBLY

namespace {

// Throws a generic "deserialization failed" exception by default, unless a more
// specific exception has already been thrown.
void ThrowDeserializationExceptionIfNonePending(Isolate* isolate) {}

}  // namespace

MaybeHandle<HeapObject> ValueDeserializer::ReadSharedObject() {}

MaybeHandle<JSObject> ValueDeserializer::ReadHostObject() {}

// Copies a vector of property values into an object, given the map that should
// be used.
static void CommitProperties(Handle<JSObject> object, Handle<Map> map,
                             const std::vector<Handle<Object>>& properties) {}

static bool IsValidObjectKey(Tagged<Object> value, Isolate* isolate) {}

Maybe<uint32_t> ValueDeserializer::ReadJSObjectProperties(
    Handle<JSObject> object, SerializationTag end_tag,
    bool can_use_transitions) {}

bool ValueDeserializer::HasObjectWithID(uint32_t id) {}

MaybeHandle<JSReceiver> ValueDeserializer::GetObjectWithID(uint32_t id) {}

void ValueDeserializer::AddObjectWithID(uint32_t id,
                                        DirectHandle<JSReceiver> object) {}

static Maybe<bool> SetPropertiesFromKeyValuePairs(Isolate* isolate,
                                                  Handle<JSObject> object,
                                                  Handle<Object>* data,
                                                  uint32_t num_properties) {}

MaybeHandle<Object>
ValueDeserializer::ReadObjectUsingEntireBufferForLegacyFormat() {}

}  // namespace internal
}  // namespace v8