// 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.

#ifndef V8_VALUE_SERIALIZER_H_
#define V8_VALUE_SERIALIZER_H_

#include <cstdint>
#include <vector>

#include "include/v8.h"
#include "src/base/compiler-specific.h"
#include "src/base/macros.h"
#include "src/execution/message-template.h"
#include "src/utils/identity-map.h"
#include "src/utils/vector.h"
#include "src/handles/maybe-handles.h"
#include "src/zone/zone.h"

namespace v8 {
namespace internal {

class BigInt;
class HeapNumber;
class Isolate;
class JSArrayBuffer;
class JSArrayBufferView;
class JSDate;
class JSMap;
class JSRegExp;
class JSSet;
class JSValue;
class MutableHeapNumber;
class Object;
class Oddball;
class Smi;
class WasmMemoryObject;
class WasmModuleObject;

enum class SerializationTag : uint8_t;

/**
 * Writes V8 objects in a binary format that allows the objects to be cloned
 * according to the HTML structured clone algorithm.
 *
 * Format is based on Blink's previous serialization logic.
 */
class ValueSerializer {
 public:
  ValueSerializer(Isolate* isolate, v8::ValueSerializer::Delegate* delegate);
  ~ValueSerializer();

  /*
   * Writes out a header, which includes the format version.
   */
  void WriteHeader();

  /*
   * Serializes a V8 object into the buffer.
   */
  Maybe<bool> WriteObject(Handle<Object> object) V8_WARN_UNUSED_RESULT;

  /*
   * Returns the buffer, allocated via the delegate, and its size.
   * Caller assumes ownership of the buffer.
   */
  std::pair<uint8_t*, size_t> Release();

  /*
   * Marks an ArrayBuffer as havings its contents transferred out of band.
   * Pass the corresponding JSArrayBuffer in the deserializing context to
   * ValueDeserializer::TransferArrayBuffer.
   */
  void TransferArrayBuffer(uint32_t transfer_id,
                           Handle<JSArrayBuffer> array_buffer);

  /*
   * Publicly exposed wire format writing methods.
   * These are intended for use within the delegate's WriteHostObject method.
   */
  void WriteUint32(uint32_t value);
  void WriteUint64(uint64_t value);
  void WriteRawBytes(const void* source, size_t length);
  void WriteDouble(double value);

  /*
   * Indicate whether to treat ArrayBufferView objects as host objects,
   * i.e. pass them to Delegate::WriteHostObject. This should not be
   * called when no Delegate was passed.
   *
   * The default is not to treat ArrayBufferViews as host objects.
   */
  void SetTreatArrayBufferViewsAsHostObjects(bool mode);

 private:
  // Managing allocations of the internal buffer.
  Maybe<bool> ExpandBuffer(size_t required_capacity);

  // Writing the wire format.
  void WriteTag(SerializationTag tag);
  template <typename T>
  void WriteVarint(T value);
  template <typename T>
  void WriteZigZag(T value);
  void WriteOneByteString(Vector<const uint8_t> chars);
  void WriteTwoByteString(Vector<const uc16> chars);
  void WriteBigIntContents(BigInt bigint);
  Maybe<uint8_t*> ReserveRawBytes(size_t bytes);

  // Writing V8 objects of various kinds.
  void WriteOddball(Oddball oddball);
  void WriteSmi(Smi smi);
  void WriteHeapNumber(HeapNumber number);
  void WriteMutableHeapNumber(MutableHeapNumber number);
  void WriteBigInt(BigInt bigint);
  void WriteString(Handle<String> string);
  Maybe<bool> WriteJSReceiver(Handle<JSReceiver> receiver)
      V8_WARN_UNUSED_RESULT;
  Maybe<bool> WriteJSObject(Handle<JSObject> object) V8_WARN_UNUSED_RESULT;
  Maybe<bool> WriteJSObjectSlow(Handle<JSObject> object) V8_WARN_UNUSED_RESULT;
  Maybe<bool> WriteJSArray(Handle<JSArray> array) V8_WARN_UNUSED_RESULT;
  void WriteJSDate(JSDate date);
  Maybe<bool> WriteJSValue(Handle<JSValue> value) V8_WARN_UNUSED_RESULT;
  void WriteJSRegExp(JSRegExp regexp);
  Maybe<bool> WriteJSMap(Handle<JSMap> map) V8_WARN_UNUSED_RESULT;
  Maybe<bool> WriteJSSet(Handle<JSSet> map) V8_WARN_UNUSED_RESULT;
  Maybe<bool> WriteJSArrayBuffer(Handle<JSArrayBuffer> array_buffer)
      V8_WARN_UNUSED_RESULT;
  Maybe<bool> WriteJSArrayBufferView(JSArrayBufferView array_buffer);
  Maybe<bool> WriteWasmModule(Handle<WasmModuleObject> object)
      V8_WARN_UNUSED_RESULT;
  Maybe<bool> WriteWasmMemory(Handle<WasmMemoryObject> object)
      V8_WARN_UNUSED_RESULT;
  Maybe<bool> WriteHostObject(Handle<JSObject> object) V8_WARN_UNUSED_RESULT;

  /*
   * Reads the specified keys from the object and writes key-value pairs to the
   * buffer. Returns the number of keys actually written, which may be smaller
   * if some keys are not own properties when accessed.
   */
  Maybe<uint32_t> WriteJSObjectPropertiesSlow(
      Handle<JSObject> object, Handle<FixedArray> keys) V8_WARN_UNUSED_RESULT;

  /*
   * Asks the delegate to handle an error that occurred during data cloning, by
   * throwing an exception appropriate for the host.
   */
  void ThrowDataCloneError(MessageTemplate template_index);
  V8_NOINLINE void ThrowDataCloneError(MessageTemplate template_index,
                                       Handle<Object> arg0);

  Maybe<bool> ThrowIfOutOfMemory();

  Isolate* const isolate_;
  v8::ValueSerializer::Delegate* const delegate_;
  uint8_t* buffer_ = nullptr;
  size_t buffer_size_ = 0;
  size_t buffer_capacity_ = 0;
  bool treat_array_buffer_views_as_host_objects_ = false;
  bool out_of_memory_ = false;
  Zone zone_;

  // To avoid extra lookups in the identity map, ID+1 is actually stored in the
  // map (checking if the used identity is zero is the fast way of checking if
  // the entry is new).
  IdentityMap<uint32_t, ZoneAllocationPolicy> id_map_;
  uint32_t next_id_ = 0;

  // A similar map, for transferred array buffers.
  IdentityMap<uint32_t, ZoneAllocationPolicy> array_buffer_transfer_map_;

  DISALLOW_COPY_AND_ASSIGN(ValueSerializer);
};

/*
 * Deserializes values from data written with ValueSerializer, or a compatible
 * implementation.
 */
class ValueDeserializer {
 public:
  ValueDeserializer(Isolate* isolate, Vector<const uint8_t> data,
                    v8::ValueDeserializer::Delegate* delegate);
  ~ValueDeserializer();

  /*
   * Runs version detection logic, which may fail if the format is invalid.
   */
  Maybe<bool> ReadHeader() V8_WARN_UNUSED_RESULT;

  /*
   * Reads the underlying wire format version. Likely mostly to be useful to
   * legacy code reading old wire format versions. Must be called after
   * ReadHeader.
   */
  uint32_t GetWireFormatVersion() const { return version_; }

  /*
   * Deserializes a V8 object from the buffer.
   */
  MaybeHandle<Object> ReadObject() V8_WARN_UNUSED_RESULT;

  /*
   * Reads an object, consuming the entire buffer.
   *
   * This is required for the legacy "version 0" format, which did not allow
   * reference deduplication, and instead relied on a "stack" model for
   * deserializing, with the contents of objects and arrays provided first.
   */
  MaybeHandle<Object> ReadObjectUsingEntireBufferForLegacyFormat()
      V8_WARN_UNUSED_RESULT;

  /*
   * Accepts the array buffer corresponding to the one passed previously to
   * ValueSerializer::TransferArrayBuffer.
   */
  void TransferArrayBuffer(uint32_t transfer_id,
                           Handle<JSArrayBuffer> array_buffer);

  /*
   * Publicly exposed wire format writing methods.
   * These are intended for use within the delegate's WriteHostObject method.
   */
  bool ReadUint32(uint32_t* value) V8_WARN_UNUSED_RESULT;
  bool ReadUint64(uint64_t* value) V8_WARN_UNUSED_RESULT;
  bool ReadDouble(double* value) V8_WARN_UNUSED_RESULT;
  bool ReadRawBytes(size_t length, const void** data) V8_WARN_UNUSED_RESULT;
  void set_expect_inline_wasm(bool expect_inline_wasm) {
    expect_inline_wasm_ = expect_inline_wasm;
  }

 private:
  // Reading the wire format.
  Maybe<SerializationTag> PeekTag() const V8_WARN_UNUSED_RESULT;
  void ConsumeTag(SerializationTag peeked_tag);
  Maybe<SerializationTag> ReadTag() V8_WARN_UNUSED_RESULT;
  template <typename T>
  Maybe<T> ReadVarint() V8_WARN_UNUSED_RESULT;
  template <typename T>
  Maybe<T> ReadZigZag() V8_WARN_UNUSED_RESULT;
  Maybe<double> ReadDouble() V8_WARN_UNUSED_RESULT;
  Maybe<Vector<const uint8_t>> ReadRawBytes(int size) V8_WARN_UNUSED_RESULT;
  bool expect_inline_wasm() const { return expect_inline_wasm_; }

  // Reads a string if it matches the one provided.
  // Returns true if this was the case. Otherwise, nothing is consumed.
  bool ReadExpectedString(Handle<String> expected) V8_WARN_UNUSED_RESULT;

  // Like ReadObject, but skips logic for special cases in simulating the
  // "stack machine".
  MaybeHandle<Object> ReadObjectInternal() V8_WARN_UNUSED_RESULT;

  // Reads a string intended to be part of a more complicated object.
  // Before v12, these are UTF-8 strings. After, they can be any encoding
  // permissible for a string (with the relevant tag).
  MaybeHandle<String> ReadString() V8_WARN_UNUSED_RESULT;

  // Reading V8 objects of specific kinds.
  // The tag is assumed to have already been read.
  MaybeHandle<BigInt> ReadBigInt() V8_WARN_UNUSED_RESULT;
  MaybeHandle<String> ReadUtf8String() V8_WARN_UNUSED_RESULT;
  MaybeHandle<String> ReadOneByteString() V8_WARN_UNUSED_RESULT;
  MaybeHandle<String> ReadTwoByteString() V8_WARN_UNUSED_RESULT;
  MaybeHandle<JSObject> ReadJSObject() V8_WARN_UNUSED_RESULT;
  MaybeHandle<JSArray> ReadSparseJSArray() V8_WARN_UNUSED_RESULT;
  MaybeHandle<JSArray> ReadDenseJSArray() V8_WARN_UNUSED_RESULT;
  MaybeHandle<JSDate> ReadJSDate() V8_WARN_UNUSED_RESULT;
  MaybeHandle<JSValue> ReadJSValue(SerializationTag tag) V8_WARN_UNUSED_RESULT;
  MaybeHandle<JSRegExp> ReadJSRegExp() V8_WARN_UNUSED_RESULT;
  MaybeHandle<JSMap> ReadJSMap() V8_WARN_UNUSED_RESULT;
  MaybeHandle<JSSet> ReadJSSet() V8_WARN_UNUSED_RESULT;
  MaybeHandle<JSArrayBuffer> ReadJSArrayBuffer(bool is_shared)
      V8_WARN_UNUSED_RESULT;
  MaybeHandle<JSArrayBuffer> ReadTransferredJSArrayBuffer()
      V8_WARN_UNUSED_RESULT;
  MaybeHandle<JSArrayBufferView> ReadJSArrayBufferView(
      Handle<JSArrayBuffer> buffer) V8_WARN_UNUSED_RESULT;
  MaybeHandle<JSObject> ReadWasmModule() V8_WARN_UNUSED_RESULT;
  MaybeHandle<JSObject> ReadWasmModuleTransfer() V8_WARN_UNUSED_RESULT;
  MaybeHandle<WasmMemoryObject> ReadWasmMemory() V8_WARN_UNUSED_RESULT;
  MaybeHandle<JSObject> ReadHostObject() V8_WARN_UNUSED_RESULT;

  /*
   * Reads key-value pairs into the object until the specified end tag is
   * encountered. If successful, returns the number of properties read.
   */
  Maybe<uint32_t> ReadJSObjectProperties(Handle<JSObject> object,
                                         SerializationTag end_tag,
                                         bool can_use_transitions);

  // Manipulating the map from IDs to reified objects.
  bool HasObjectWithID(uint32_t id);
  MaybeHandle<JSReceiver> GetObjectWithID(uint32_t id);
  void AddObjectWithID(uint32_t id, Handle<JSReceiver> object);

  Isolate* const isolate_;
  v8::ValueDeserializer::Delegate* const delegate_;
  const uint8_t* position_;
  const uint8_t* const end_;
  AllocationType allocation_;
  uint32_t version_ = 0;
  uint32_t next_id_ = 0;
  bool expect_inline_wasm_ = false;

  // Always global handles.
  Handle<FixedArray> id_map_;
  MaybeHandle<SimpleNumberDictionary> array_buffer_transfer_map_;

  DISALLOW_COPY_AND_ASSIGN(ValueDeserializer);
};

}  // namespace internal
}  // namespace v8

#endif  // V8_VALUE_SERIALIZER_H_
