// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#ifndef RUNTIME_VM_COMPILER_BACKEND_IL_SERIALIZER_H_
#define RUNTIME_VM_COMPILER_BACKEND_IL_SERIALIZER_H_

#if defined(DART_PRECOMPILED_RUNTIME)
#error "AOT runtime should not use compiler sources (including header files)"
#endif  // defined(DART_PRECOMPILED_RUNTIME)

#include <utility>  // For std::move.

#include "platform/globals.h"
#include "vm/allocation.h"
#include "vm/compiler/backend/locations.h"

namespace dart {

class AliasIdentity;
class BlockEntryInstr;
class CallTargets;
class CatchBlockEntryInstr;
struct CidRangeValue;
class Cids;
class Code;
class ConditionInstr;
class CompileType;
class Definition;
class Environment;
class FunctionEntryInstr;
class Instruction;
class FlowGraph;
class GraphEntryInstr;
class Heap;
class IndirectEntryInstr;
class JoinEntryInstr;
class LocalVariable;
class LocationSummary;
class MoveOperands;
class MoveSchedule;
class NonStreamingWriteStream;
class OsrEntryInstr;
class ParsedFunction;
class ParallelMoveInstr;
class PhiInstr;
class Range;
class ReadStream;
class RecordShape;
class TargetEntryInstr;
class TokenPosition;
class TryEntryInstr;

namespace compiler {
struct TableSelector;

namespace ffi {
class CallbackMarshaller;
class CallMarshaller;
class NativeCallingConvention;
}  // namespace ffi
}  // namespace compiler

// The list of types which are handled by flow graph serializer/deserializer.
// For each type there is a corresponding Write<T>(T) and Read<T>() methods.
//
// This list includes all types of fields of IL instructions
// which are serialized via DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS macro,
// except enum types which are unwrapped with serializable_type_t.
//
// The list is sorted alphabetically by type name.
#define IL_SERIALIZABLE_TYPE_LIST(V)                                           \
  V(AliasIdentity)                                                             \
  V(const AbstractType&)                                                       \
  V(const AbstractType*)                                                       \
  V(const Array&)                                                              \
  V(bool)                                                                      \
  V(const compiler::ffi::CallbackMarshaller&)                                  \
  V(const compiler::ffi::CallMarshaller&)                                      \
  V(const CallTargets&)                                                        \
  V(const char*)                                                               \
  V(CidRangeValue)                                                             \
  V(const Cids&)                                                               \
  V(const Class&)                                                              \
  V(const Code&)                                                               \
  V(ConditionInstr*)                                                           \
  V(CompileType*)                                                              \
  V(ConstantInstr*)                                                            \
  V(Definition*)                                                               \
  V(double)                                                                    \
  V(Environment*)                                                              \
  V(const Field&)                                                              \
  V(const ICData*)                                                             \
  V(const Instance&)                                                           \
  V(int8_t)                                                                    \
  V(int16_t)                                                                   \
  V(int32_t)                                                                   \
  V(int64_t)                                                                   \
  V(const Function&)                                                           \
  V(const FunctionType&)                                                       \
  V(Instruction*)                                                              \
  V(const LocalVariable&)                                                      \
  V(LocationSummary*)                                                          \
  V(MoveOperands*)                                                             \
  V(const MoveSchedule*)                                                       \
  V(const Object&)                                                             \
  V(ParallelMoveInstr*)                                                        \
  V(PhiInstr*)                                                                 \
  V(Range*)                                                                    \
  V(RecordShape)                                                               \
  V(Representation)                                                            \
  V(simd128_value_t)                                                           \
  V(const Slot&)                                                               \
  V(const Slot*)                                                               \
  V(const String&)                                                             \
  V(const compiler::TableSelector*)                                            \
  V(TokenPosition)                                                             \
  V(const TypeArguments&)                                                      \
  V(const TypeParameters&)                                                     \
  V(uint8_t)                                                                   \
  V(uint16_t)                                                                  \
  V(uint32_t)                                                                  \
  V(uint64_t)                                                                  \
  V(Value*)

// List of types serializable as references.
#define IL_SERIALIZABLE_REF_TYPE_LIST(V)                                       \
  V(BlockEntryInstr*)                                                          \
  V(CatchBlockEntryInstr*)                                                     \
  V(Definition*)                                                               \
  V(FunctionEntryInstr*)                                                       \
  V(IndirectEntryInstr*)                                                       \
  V(JoinEntryInstr*)                                                           \
  V(OsrEntryInstr*)                                                            \
  V(TargetEntryInstr*)                                                         \
  V(TryEntryInstr*)

// Serializes flow graph, including constants and references
// to objects of program structure.
//
// Each IL instruction is serialized in 2 step:
// - the main step (T::WriteTo / T::T()) serializes
//   instruction fields, basically everything required to
//   re-create instruction object.
// - the extra step (T::WriteExtra / T::ReadExtra) serializes
//   references to other instructions, including inputs,
//   environments, locations (may reference constants) and successors.
//
class FlowGraphSerializer : public ValueObject {
 public:
  explicit FlowGraphSerializer(NonStreamingWriteStream* stream);
  ~FlowGraphSerializer();

  // Writes [flow_graph] into the stream.
  // The graph should be compacted via CompactSSA().
  // [detached_defs] should contain all definitions which are
  // detached from the graph but can still be referenced from
  // environments.
  void WriteFlowGraph(const FlowGraph& flow_graph,
                      const ZoneGrowableArray<Definition*>& detached_defs);

  // Implementation of 'Write' method, specialized for a particular type.
  // This struct is used for the partial template instantiations below.
  //
  // Explicit (full) specializations of 'Write' method are not provided as
  // gcc doesn't support explicit template specializations of members of
  // a non-template class
  // (CWG 730 https://cplusplus.github.io/CWG/issues/730.html).
  // The 2nd template argument is used to make all template instantiations
  // partial as gcc doesn't support explicit (full) template specializations
  // in class scope (CWG 727 https://cplusplus.github.io/CWG/issues/727.html).
  template <typename T, class = void>
  struct WriteTrait {
    using ArgType = T;
  };

  template <typename T>
  struct WriteTrait<GrowableArray<T>> {
    using ArgType = const GrowableArray<T>&;
    static void Write(FlowGraphSerializer* s, ArgType x) {
      const intptr_t len = x.length();
      s->Write<intptr_t>(len);
      for (intptr_t i = 0; i < len; ++i) {
        s->Write<T>(x[i]);
      }
    }
  };

  template <typename T>
  struct WriteTrait<const GrowableArray<T>&> {
    using ArgType = const GrowableArray<T>&;
    static void Write(FlowGraphSerializer* s, ArgType x) {
      WriteTrait<GrowableArray<T>>::Write(s, x);
    }
  };

  template <typename T>
  struct WriteTrait<ZoneGrowableArray<T>*> {
    using ArgType = const ZoneGrowableArray<T>*;
    static void Write(FlowGraphSerializer* s, ArgType x) {
      if (x == nullptr) {
        s->Write<intptr_t>(-1);
        return;
      }
      const intptr_t len = x->length();
      s->Write<intptr_t>(len);
      for (intptr_t i = 0; i < len; ++i) {
        s->Write<T>((*x)[i]);
      }
    }
  };

  template <typename T>
  struct WriteTrait<const ZoneGrowableArray<T>&> {
    using ArgType = const ZoneGrowableArray<T>&;
    static void Write(FlowGraphSerializer* s, ArgType x) {
      WriteTrait<ZoneGrowableArray<T>*>::Write(s, &x);
    }
  };

  // Specialization in case intptr_t is not mapped to intN_t.
  template <typename T>
  struct WriteTrait<T,
                    std::enable_if_t<std::is_same_v<intptr_t, T> &&
                                     !std::is_same_v<intptr_t, int32_t> &&
                                     !std::is_same_v<intptr_t, int64_t>>> {
    using ArgType = intptr_t;
    static void Write(FlowGraphSerializer* s, intptr_t x) {
#ifdef ARCH_IS_64_BIT
      s->Write<int64_t>(x);
#else
      s->Write<int32_t>(x);
#endif
    }
  };

  // Specialization in case uintptr_t is not mapped to uintN_t.
  template <typename T>
  struct WriteTrait<T,
                    std::enable_if_t<std::is_same_v<uintptr_t, T> &&
                                     !std::is_same_v<uintptr_t, uint32_t> &&
                                     !std::is_same_v<uintptr_t, uint64_t>>> {
    using ArgType = uintptr_t;
    static void Write(FlowGraphSerializer* s, uintptr_t x) {
#ifdef ARCH_IS_64_BIT
      s->Write<uint64_t>(x);
#else
      s->Write<uint32_t>(x);
#endif
    }
  };

#define DECLARE_WRITE_TRAIT(type)                                              \
  template <typename T>                                                        \
  struct WriteTrait<T, std::enable_if_t<std::is_same_v<type, T>>> {            \
    using ArgType = type;                                                      \
    static void Write(FlowGraphSerializer* s, type x);                         \
  };
  IL_SERIALIZABLE_TYPE_LIST(DECLARE_WRITE_TRAIT)
#undef DECLARE_WRITE_TRAIT

  template <typename T>
  void Write(typename WriteTrait<T>::ArgType x) {
    WriteTrait<T>::Write(this, x);
  }

  // Implementation of 'WriteRef' method, specialized for a particular type.
  // This struct is used for the partial template instantiations below.
  //
  // Explicit (full) specializations of 'WriteRef' method are not provided as
  // gcc doesn't support explicit template specializations of members of
  // a non-template class
  // (CWG 730 https://cplusplus.github.io/CWG/issues/730.html).
  // The 2nd template argument is used to make all template instantiations
  // partial as gcc doesn't support explicit (full) template specializations
  // in class scope (CWG 727 https://cplusplus.github.io/CWG/issues/727.html).
  template <typename T, class = void>
  struct WriteRefTrait {};

#define DECLARE_WRITE_REF_TRAIT(type)                                          \
  template <typename T>                                                        \
  struct WriteRefTrait<T, std::enable_if_t<std::is_same_v<type, T>>> {         \
    static void WriteRef(FlowGraphSerializer* s, T x);                         \
  };
  IL_SERIALIZABLE_REF_TYPE_LIST(DECLARE_WRITE_REF_TRAIT)
#undef DECLARE_WRITE_REF_TRAIT

  template <typename T>
  void WriteRef(T x) {
    WriteRefTrait<T>::WriteRef(this, x);
  }

  template <typename T>
  void WriteGrowableArrayOfRefs(const GrowableArray<T>& array) {
    const intptr_t len = array.length();
    Write<intptr_t>(len);
    for (intptr_t i = 0; i < len; ++i) {
      WriteRef<T>(array[i]);
    }
  }

  BaseWriteStream* stream() const { return stream_; }
  Zone* zone() const { return zone_; }
  Thread* thread() const { return thread_; }
  IsolateGroup* isolate_group() const { return isolate_group_; }
  Heap* heap() const { return heap_; }
  bool can_write_refs() const { return can_write_refs_; }

 private:
  void AddBaseObject(const Object& x);
  void WriteObjectImpl(const Object& x, intptr_t cid, intptr_t object_index);
  bool IsWritten(const Object& obj);
  bool HasEnclosingTypes(const Object& obj);
  bool WriteObjectWithEnclosingTypes(const Object& type);
  void WriteEnclosingTypes(const Object& type,
                           intptr_t num_free_fun_type_params);

  NonStreamingWriteStream* stream_;
  Zone* zone_;
  Thread* thread_;
  IsolateGroup* isolate_group_;
  Heap* heap_;
  intptr_t object_counter_ = 0;
  bool can_write_refs_ = false;
  intptr_t num_free_fun_type_params_ = kMaxInt;
};

// Deserializes flow graph.
// All constants and types are canonicalized during deserialization.
class FlowGraphDeserializer : public ValueObject {
 public:
  FlowGraphDeserializer(const ParsedFunction& parsed_function,
                        ReadStream* stream);

  const ParsedFunction& parsed_function() const { return parsed_function_; }

  Zone* zone() const { return zone_; }
  ReadStream* stream() const { return stream_; }
  Thread* thread() const { return thread_; }
  IsolateGroup* isolate_group() const { return isolate_group_; }

  GraphEntryInstr* graph_entry() const { return graph_entry_; }
  void set_graph_entry(GraphEntryInstr* entry) { graph_entry_ = entry; }

  BlockEntryInstr* current_block() const { return current_block_; }
  void set_current_block(BlockEntryInstr* block) { current_block_ = block; }

  BlockEntryInstr* block(intptr_t block_id) const {
    BlockEntryInstr* b = blocks_[block_id];
    ASSERT(b != nullptr);
    return b;
  }
  void set_block(intptr_t block_id, BlockEntryInstr* block) {
    ASSERT(blocks_[block_id] == nullptr);
    blocks_[block_id] = block;
  }

  Definition* definition(intptr_t ssa_temp_index) const {
    Definition* def = definitions_[ssa_temp_index];
    ASSERT(def != nullptr);
    return def;
  }
  void set_definition(intptr_t ssa_temp_index, Definition* def) {
    ASSERT(definitions_[ssa_temp_index] == nullptr);
    definitions_[ssa_temp_index] = def;
  }

  FlowGraph* ReadFlowGraph();

  // Implementation of 'Read' method, specialized for a particular type.
  // This struct is used for the partial template instantiations below.
  //
  // Explicit (full) specializations of 'Read' method are not provided as
  // gcc doesn't support explicit template specializations of members of
  // a non-template class
  // (CWG 730 https://cplusplus.github.io/CWG/issues/730.html).
  // The 2nd template argument is used to make all template instantiations
  // partial as gcc doesn't support explicit (full) template specializations
  // in class scope (CWG 727 https://cplusplus.github.io/CWG/issues/727.html).
  template <typename T, class = void>
  struct ReadTrait {};

  template <typename T>
  struct ReadTrait<GrowableArray<T>> {
    static GrowableArray<T> Read(FlowGraphDeserializer* d) {
      const intptr_t len = d->Read<intptr_t>();
      GrowableArray<T> array(len);
      for (int i = 0; i < len; ++i) {
        array.Add(d->Read<T>());
      }
      return array;
    }
  };

  template <typename T>
  struct ReadTrait<const GrowableArray<T>&> {
    static const GrowableArray<T>& Read(FlowGraphDeserializer* d) {
      return ReadTrait<GrowableArray<T>>::Read(d);
    }
  };

  template <typename T>
  struct ReadTrait<ZoneGrowableArray<T>*> {
    static ZoneGrowableArray<T>* Read(FlowGraphDeserializer* d) {
      const intptr_t len = d->Read<intptr_t>();
      if (len < 0) {
        return nullptr;
      }
      auto* array = new (d->zone()) ZoneGrowableArray<T>(d->zone(), len);
      for (int i = 0; i < len; ++i) {
        array->Add(d->Read<T>());
      }
      return array;
    }
  };

  template <typename T>
  struct ReadTrait<const ZoneGrowableArray<T>&> {
    static const ZoneGrowableArray<T>& Read(FlowGraphDeserializer* d) {
      return *ReadTrait<ZoneGrowableArray<T>*>::Read(d);
    }
  };

  // Specialization in case intptr_t is not mapped to intN_t.
  template <typename T>
  struct ReadTrait<T,
                   std::enable_if_t<std::is_same_v<intptr_t, T> &&
                                    !std::is_same_v<intptr_t, int32_t> &&
                                    !std::is_same_v<intptr_t, int64_t>>> {
    static intptr_t Read(FlowGraphDeserializer* d) {
#ifdef ARCH_IS_64_BIT
      return d->Read<int64_t>();
#else
      return d->Read<int32_t>();
#endif
    }
  };

  // Specialization in case uintptr_t is not mapped to uintN_t.
  template <typename T>
  struct ReadTrait<T,
                   std::enable_if_t<std::is_same_v<uintptr_t, T> &&
                                    !std::is_same_v<uintptr_t, uint32_t> &&
                                    !std::is_same_v<uintptr_t, uint64_t>>> {
    static uintptr_t Read(FlowGraphDeserializer* d) {
#ifdef ARCH_IS_64_BIT
      return d->Read<uint64_t>();
#else
      return d->Read<uint32_t>();
#endif
    }
  };

#define DECLARE_READ_TRAIT(type)                                               \
  template <typename T>                                                        \
  struct ReadTrait<T, std::enable_if_t<std::is_same_v<type, T>>> {             \
    static type Read(FlowGraphDeserializer* d);                                \
  };
  IL_SERIALIZABLE_TYPE_LIST(DECLARE_READ_TRAIT)
#undef DECLARE_READ_TRAIT

  template <typename T>
  T Read() {
    return ReadTrait<T>::Read(this);
  }

  // Implementation of 'ReadRef' method, specialized for a particular type.
  // This struct is used for the partial template instantiations below.
  //
  // Explicit (full) specializations of 'ReadRef' method are not provided as
  // gcc doesn't support explicit template specializations of members of
  // a non-template class
  // (CWG 730 https://cplusplus.github.io/CWG/issues/730.html).
  // The 2nd template argument is used to make all template instantiations
  // partial as gcc doesn't support explicit (full) template specializations
  // in class scope (CWG 727 https://cplusplus.github.io/CWG/issues/727.html).
  template <typename T, class = void>
  struct ReadRefTrait {};

#define DECLARE_READ_REF_TRAIT(type)                                           \
  template <typename T>                                                        \
  struct ReadRefTrait<T, std::enable_if_t<std::is_same_v<type, T>>> {          \
    static T ReadRef(FlowGraphDeserializer* d);                                \
  };
  IL_SERIALIZABLE_REF_TYPE_LIST(DECLARE_READ_REF_TRAIT)
#undef DECLARE_READ_REF_TRAIT

  template <typename T>
  T ReadRef() {
    return ReadRefTrait<T>::ReadRef(this);
  }

  template <typename T>
  GrowableArray<T> ReadGrowableArrayOfRefs() {
    const intptr_t len = Read<intptr_t>();
    GrowableArray<T> array(len);
    for (int i = 0; i < len; ++i) {
      array.Add(ReadRef<T>());
    }
    return array;
  }

 private:
  void AddBaseObject(const Object& x);
  ClassPtr GetClassById(classid_t id) const;
  const Object& ReadObjectImpl(intptr_t cid, intptr_t object_index);
  void SetObjectAt(intptr_t object_index, const Object& object);
  const Object& ReadObjectWithEnclosingTypes();

  const ParsedFunction& parsed_function_;
  ReadStream* stream_;
  Zone* zone_;
  Thread* thread_;
  IsolateGroup* isolate_group_;

  // Deserialized objects.
  GraphEntryInstr* graph_entry_ = nullptr;
  BlockEntryInstr* current_block_ = nullptr;
  GrowableArray<BlockEntryInstr*> blocks_;
  GrowableArray<Definition*> definitions_;
  GrowableArray<const Object*> objects_;
  intptr_t object_counter_ = 0;
};

}  // namespace dart

#endif  // RUNTIME_VM_COMPILER_BACKEND_IL_SERIALIZER_H_
