// 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 compiler::ffi::NativeCallingConvention&)                             \
  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);

  // Used to track scopes of recursive types during serialization.
  struct TypeScope {
    TypeScope(FlowGraphSerializer* serializer, bool is_recursive)
        : serializer_(serializer),
          is_recursive_(is_recursive),
          was_writing_recursive_type_(serializer->writing_recursive_type_) {
      serializer->writing_recursive_type_ = is_recursive;
    }

    ~TypeScope() {
      serializer_->writing_recursive_type_ = was_writing_recursive_type_;
    }

    // Returns true if type of the current scope can be canonicalized
    // during deserialization. Recursive types which were not
    // fully deserialized should not be canonicalized.
    bool CanBeCanonicalized() const {
      return !is_recursive_ || !was_writing_recursive_type_;
    }

    FlowGraphSerializer* const serializer_;
    const bool is_recursive_;
    const bool was_writing_recursive_type_;
  };

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

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

  InstancePtr MaybeCanonicalize(const Instance& obj,
                                intptr_t object_index,
                                bool can_be_canonicalized);

  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;
  GrowableArray<intptr_t> pending_canonicalization_;
};

}  // namespace dart

#endif  // RUNTIME_VM_COMPILER_BACKEND_IL_SERIALIZER_H_
