// 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 ComparisonInstr;
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;

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(ComparisonInstr*)                                                          \
  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(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*)

// 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 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:
  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_
