// Copyright 2020 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_SNAPSHOT_SERIALIZER_DESERIALIZER_H_
#define V8_SNAPSHOT_SERIALIZER_DESERIALIZER_H_

#include "src/common/assert-scope.h"
#include "src/objects/visitors.h"
#include "src/snapshot/references.h"

namespace v8 {
namespace internal {

class CallHandlerInfo;
class Isolate;

// The Serializer/Deserializer class is a common superclass for Serializer and
// Deserializer which is used to store common constants and methods used by
// both.
class SerializerDeserializer : public RootVisitor {
 public:
  static void Iterate(Isolate* isolate, RootVisitor* visitor);

 protected:
  static bool CanBeDeferred(HeapObject o);

  void RestoreExternalReferenceRedirector(Isolate* isolate,
                                          Handle<AccessorInfo> accessor_info);
  void RestoreExternalReferenceRedirector(
      Isolate* isolate, Handle<CallHandlerInfo> call_handler_info);

// clang-format off
#define UNUSED_SERIALIZER_BYTE_CODES(V)                           \
  /* Free range 0x1c..0x1f */                                     \
  V(0x1c) V(0x1d) V(0x1e) V(0x1f)                                 \
  /* Free range 0x20..0x2f */                                     \
  V(0x20) V(0x21) V(0x22) V(0x23) V(0x24) V(0x25) V(0x26) V(0x27) \
  V(0x28) V(0x29) V(0x2a) V(0x2b) V(0x2c) V(0x2d) V(0x2e) V(0x2f) \
  /* Free range 0x30..0x3f */                                     \
  V(0x30) V(0x31) V(0x32) V(0x33) V(0x34) V(0x35) V(0x36) V(0x37) \
  V(0x38) V(0x39) V(0x3a) V(0x3b) V(0x3c) V(0x3d) V(0x3e) V(0x3f) \
  /* Free range 0x97..0x9f */                                     \
  V(0x98) V(0x99) V(0x9a) V(0x9b) V(0x9c) V(0x9d) V(0x9e) V(0x9f) \
  /* Free range 0xa0..0xaf */                                     \
  V(0xa0) V(0xa1) V(0xa2) V(0xa3) V(0xa4) V(0xa5) V(0xa6) V(0xa7) \
  V(0xa8) V(0xa9) V(0xaa) V(0xab) V(0xac) V(0xad) V(0xae) V(0xaf) \
  /* Free range 0xb0..0xbf */                                     \
  V(0xb0) V(0xb1) V(0xb2) V(0xb3) V(0xb4) V(0xb5) V(0xb6) V(0xb7) \
  V(0xb8) V(0xb9) V(0xba) V(0xbb) V(0xbc) V(0xbd) V(0xbe) V(0xbf) \
  /* Free range 0xc0..0xcf */                                     \
  V(0xc0) V(0xc1) V(0xc2) V(0xc3) V(0xc4) V(0xc5) V(0xc6) V(0xc7) \
  V(0xc8) V(0xc9) V(0xca) V(0xcb) V(0xcc) V(0xcd) V(0xce) V(0xcf) \
  /* Free range 0xd0..0xdf */                                     \
  V(0xd0) V(0xd1) V(0xd2) V(0xd3) V(0xd4) V(0xd5) V(0xd6) V(0xd7) \
  V(0xd8) V(0xd9) V(0xda) V(0xdb) V(0xdc) V(0xdd) V(0xde) V(0xdf) \
  /* Free range 0xe0..0xef */                                     \
  V(0xe0) V(0xe1) V(0xe2) V(0xe3) V(0xe4) V(0xe5) V(0xe6) V(0xe7) \
  V(0xe8) V(0xe9) V(0xea) V(0xeb) V(0xec) V(0xed) V(0xee) V(0xef) \
  /* Free range 0xf0..0xff */                                     \
  V(0xf0) V(0xf1) V(0xf2) V(0xf3) V(0xf4) V(0xf5) V(0xf6) V(0xf7) \
  V(0xf8) V(0xf9) V(0xfa) V(0xfb) V(0xfc) V(0xfd) V(0xfe) V(0xff)
  // clang-format on

  // The static assert below will trigger when the number of preallocated spaces
  // changed. If that happens, update the kNewObject and kBackref bytecode
  // ranges in the comments below.
  STATIC_ASSERT(4 == kNumberOfSnapshotSpaces);

  // First 32 root array items.
  static const int kRootArrayConstantsCount = 0x20;

  // 32 common raw data lengths.
  static const int kFixedRawDataCount = 0x20;
  // 16 repeats lengths.
  static const int kFixedRepeatCount = 0x10;

  // 8 hot (recently seen or back-referenced) objects with optional skip.
  static const int kHotObjectCount = 8;

  enum Bytecode : byte {
    //
    // ---------- byte code range 0x00..0x1b ----------
    //

    // 0x00..0x03  Allocate new object, in specified space.
    kNewObject = 0x00,
    // Reference to previously allocated object.
    kBackref = 0x04,
    // Reference to an object in the read only heap.
    kReadOnlyHeapRef,
    // Object in the startup object cache.
    kStartupObjectCache,
    // Root array item.
    kRootArray,
    // Object provided in the attached list.
    kAttachedReference,
    // Object in the read-only object cache.
    kReadOnlyObjectCache,
    // Do nothing, used for padding.
    kNop,
    // A tag emitted at strategic points in the snapshot to delineate sections.
    // If the deserializer does not find these at the expected moments then it
    // is an indication that the snapshot and the VM do not fit together.
    // Examine the build process for architecture, version or configuration
    // mismatches.
    kSynchronize,
    // Repeats of variable length.
    kVariableRepeat,
    // Used for embedder-allocated backing stores for TypedArrays.
    kOffHeapBackingStore,
    // Used for embedder-provided serialization data for embedder fields.
    kEmbedderFieldsData,
    // Raw data of variable length.
    kVariableRawData,
    // Used to encode external references provided through the API.
    kApiReference,
    // External reference referenced by id.
    kExternalReference,
    // Same as two bytecodes above but for serializing sandboxed external
    // pointer values.
    // TODO(v8:10391): Remove them once all ExternalPointer usages are
    // sandbox-ready.
    kSandboxedApiReference,
    kSandboxedExternalReference,
    // Internal reference of a code objects in code stream.
    kInternalReference,
    // In-place weak references.
    kClearedWeakReference,
    kWeakPrefix,
    // Encodes an off-heap instruction stream target.
    kOffHeapTarget,
    // Registers the current slot as a "pending" forward reference, to be later
    // filled by a corresponding resolution bytecode.
    kRegisterPendingForwardRef,
    // Resolves an existing "pending" forward reference to point to the current
    // object.
    kResolvePendingForwardRef,
    // Special construction bytecode for the metamap. In theory we could re-use
    // forward-references for this, but then the forward reference would be
    // registered during object map deserialization, before the object is
    // allocated, so there wouldn't be a allocated object whose map field we can
    // register as the pending field. We could either hack around this, or
    // simply introduce this new bytecode.
    kNewMetaMap,
    // Special construction bytecode for Code object bodies, which have a more
    // complex deserialization ordering and RelocInfo processing.
    kCodeBody,

    //
    // ---------- byte code range 0x40..0x7f ----------
    //

    // 0x40..0x5f
    kRootArrayConstants = 0x40,

    // 0x60..0x7f
    kFixedRawData = 0x60,

    //
    // ---------- byte code range 0x80..0x9f ----------
    //

    // 0x80..0x8f
    kFixedRepeat = 0x80,

    // 0x90..0x97
    kHotObject = 0x90,
  };

  // Helper class for encoding and decoding a value into and from a bytecode.
  //
  // The value is encoded by allocating an entire bytecode range, and encoding
  // the value as an index in that range, starting at kMinValue; thus the range
  // of values
  //   [kMinValue, kMinValue + 1, ... , kMaxValue]
  // is encoded as
  //   [kBytecode, kBytecode + 1, ... , kBytecode + (N - 1)]
  // where N is the number of values, i.e. kMaxValue - kMinValue + 1.
  template <Bytecode kBytecode, int kMinValue, int kMaxValue,
            typename TValue = int>
  struct BytecodeValueEncoder {
    STATIC_ASSERT((kBytecode + kMaxValue - kMinValue) <= kMaxUInt8);

    static constexpr bool IsEncodable(TValue value) {
      return base::IsInRange(static_cast<int>(value), kMinValue, kMaxValue);
    }

    static constexpr byte Encode(TValue value) {
      CONSTEXPR_DCHECK(IsEncodable(value));
      return static_cast<byte>(kBytecode + static_cast<int>(value) - kMinValue);
    }

    static constexpr TValue Decode(byte bytecode) {
      CONSTEXPR_DCHECK(base::IsInRange(bytecode,
                                       Encode(static_cast<TValue>(kMinValue)),
                                       Encode(static_cast<TValue>(kMaxValue))));
      return static_cast<TValue>(bytecode - kBytecode + kMinValue);
    }
  };

  template <Bytecode bytecode>
  using SpaceEncoder =
      BytecodeValueEncoder<bytecode, 0, kNumberOfSnapshotSpaces - 1,
                           SnapshotSpace>;

  using NewObject = SpaceEncoder<kNewObject>;

  //
  // Some other constants.
  //

  // Sentinel after a new object to indicate that double alignment is needed.
  static const int kDoubleAlignmentSentinel = 0;

  // Raw data size encoding helpers.
  static const int kFirstEncodableFixedRawDataSize = 1;
  static const int kLastEncodableFixedRawDataSize =
      kFirstEncodableFixedRawDataSize + kFixedRawDataCount - 1;

  using FixedRawDataWithSize =
      BytecodeValueEncoder<kFixedRawData, kFirstEncodableFixedRawDataSize,
                           kLastEncodableFixedRawDataSize>;

  // Repeat count encoding helpers.
  static const int kFirstEncodableRepeatCount = 2;
  static const int kLastEncodableFixedRepeatCount =
      kFirstEncodableRepeatCount + kFixedRepeatCount - 1;
  static const int kFirstEncodableVariableRepeatCount =
      kLastEncodableFixedRepeatCount + 1;

  using FixedRepeatWithCount =
      BytecodeValueEncoder<kFixedRepeat, kFirstEncodableRepeatCount,
                           kLastEncodableFixedRepeatCount>;

  // Encodes/decodes repeat count into a serialized variable repeat count
  // value.
  struct VariableRepeatCount {
    static constexpr bool IsEncodable(int repeat_count) {
      return repeat_count >= kFirstEncodableVariableRepeatCount;
    }

    static constexpr int Encode(int repeat_count) {
      CONSTEXPR_DCHECK(IsEncodable(repeat_count));
      return repeat_count - kFirstEncodableVariableRepeatCount;
    }

    static constexpr int Decode(int value) {
      return value + kFirstEncodableVariableRepeatCount;
    }
  };

  using RootArrayConstant =
      BytecodeValueEncoder<kRootArrayConstants, 0, kRootArrayConstantsCount - 1,
                           RootIndex>;
  using HotObject = BytecodeValueEncoder<kHotObject, 0, kHotObjectCount - 1>;

  // This backing store reference value represents nullptr values during
  // serialization/deserialization.
  static const uint32_t kNullRefSentinel = 0;
};

}  // namespace internal
}  // namespace v8

#endif  // V8_SNAPSHOT_SERIALIZER_DESERIALIZER_H_
