// Copyright (c) 2019, 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_

#include "platform/assert.h"
#include "platform/text_buffer.h"

#include "vm/allocation.h"
#include "vm/compiler/backend/flow_graph.h"
#include "vm/compiler/backend/il.h"
#include "vm/compiler/backend/sexpression.h"
#include "vm/hash_table.h"
#include "vm/object.h"
#include "vm/zone.h"

namespace dart {

// Flow graph serialization.
class FlowGraphSerializer : ValueObject {
 public:
#define FOR_EACH_BLOCK_ENTRY_KIND(M)                                           \
  M(Target)                                                                    \
  M(Join)                                                                      \
  M(Graph)                                                                     \
  M(Normal)                                                                    \
  M(Unchecked)                                                                 \
  M(OSR)                                                                       \
  M(Catch)                                                                     \
  M(Indirect)

  enum BlockEntryKind {
#define KIND_DECL(name) k##name,
    FOR_EACH_BLOCK_ENTRY_KIND(KIND_DECL)
#undef KIND_DECL
    // clang-format off
    kNumEntryKinds,
    kInvalid = -1,
    // clang-format on
  };

  // Special case: returns kTarget for a nullptr input.
  static BlockEntryKind BlockEntryTagToKind(SExpSymbol* tag);
  SExpSymbol* BlockEntryKindToTag(BlockEntryKind k);
  static bool BlockEntryKindHasInitialDefs(BlockEntryKind kind);

  static void SerializeToBuffer(const FlowGraph* flow_graph,
                                TextBuffer* buffer);
  static void SerializeToBuffer(Zone* zone,
                                const FlowGraph* flow_graph,
                                TextBuffer* buffer);
  static SExpression* SerializeToSExp(const FlowGraph* flow_graph);
  static SExpression* SerializeToSExp(Zone* zone, const FlowGraph* flow_graph);

  const FlowGraph* flow_graph() const { return flow_graph_; }
  Zone* zone() const { return zone_; }

  SExpression* FlowGraphToSExp();

  SExpSymbol* BlockEntryTag(const BlockEntryInstr* entry);
  SExpression* BlockIdToSExp(intptr_t block_id);
  SExpression* CanonicalNameToSExp(const Object& obj);
  SExpression* UseToSExp(const Definition* definition);

  // Helper method for creating canonical names.
  void SerializeCanonicalName(TextBuffer* b, const Object& obj);

  // Methods for serializing Dart values. If the argument
  // value is the null object, the null pointer is returned.
  SExpression* AbstractTypeToSExp(const AbstractType& typ);
  SExpression* ArrayToSExp(const Array& arr);
  SExpression* ClassToSExp(const Class& cls);
  SExpression* ClosureToSExp(const Closure& c);
  SExpression* ContextToSExp(const Context& c);
  SExpression* CodeToSExp(const Code& c);
  SExpression* FieldToSExp(const Field& f);
  SExpression* FunctionToSExp(const Function& f);
  SExpression* InstanceToSExp(const Instance& obj);
  SExpression* TypeArgumentsToSExp(const TypeArguments& ta);

  // A method for serializing a Dart value of arbitrary type. Unlike the
  // type-specific methods, this returns the symbol "null" for the null object.
  SExpression* ObjectToSExp(const Object& obj);

  // A wrapper method for ObjectToSExp that first checks and sees if
  // the provided value is in the constant pool. If it is, then it
  // returns a reference to the constant definition via UseToSExp.
  SExpression* DartValueToSExp(const Object& obj);

  // A wrapper method for TypeArgumentsToSExp that also returns nullptr if the
  // type arguments are empty and checks against the constant pool.
  SExpression* NonEmptyTypeArgumentsToSExp(const TypeArguments& ta);

  // Methods for serializing IL-specific values.
  SExpression* LocalVariableToSExp(const LocalVariable& v);
  SExpression* SlotToSExp(const Slot& s);
  SExpression* ICDataToSExp(const ICData* ic_data);

  // Helper methods for adding atoms to S-expression lists
  void AddBool(SExpList* sexp, bool b);
  void AddInteger(SExpList* sexp, intptr_t i);
  void AddString(SExpList* sexp, const char* cstr);
  void AddSymbol(SExpList* sexp, const char* cstr);
  void AddExtraBool(SExpList* sexp, const char* label, bool b);
  void AddExtraInteger(SExpList* sexp, const char* label, intptr_t i);
  void AddExtraString(SExpList* sexp, const char* label, const char* cstr);
  void AddExtraSymbol(SExpList* sexp, const char* label, const char* cstr);

 private:
  friend class Precompiler;  // For LLVMConstantsMap.

  FlowGraphSerializer(Zone* zone, const FlowGraph* flow_graph);
  ~FlowGraphSerializer();

  static const char* const initial_indent;

  // Helper methods for the function level that are not used by any
  // instruction serialization methods.
  SExpression* FunctionEntryToSExp(BlockEntryInstr* entry);
  SExpression* EntriesToSExp(GraphEntryInstr* start);
  SExpression* ConstantPoolToSExp(GraphEntryInstr* start);

  const FlowGraph* const flow_graph_;
  Zone* const zone_;
  ObjectStore* const object_store_;

  // A map of currently open (being serialized) recursive types. We use this
  // to determine whether to serialize the referred types in TypeRefs.
  IntMap<const Type*> open_recursive_types_;

  // Used for --populate-llvm-constant-pool in ConstantPoolToSExp.
  class LLVMConstantMapKeyEqualsTraits : public AllStatic {
   public:
    static const char* Name() { return "LLVMConstantMapKeyEqualsTraits"; }
    static bool ReportStats() { return false; }

    static bool IsMatch(const Object& a, const Object& b) {
      return a.raw() == b.raw();
    }
    static uword Hash(const Object& obj) {
      if (obj.IsSmi()) return reinterpret_cast<uword>(obj.raw());
      if (obj.IsInstance()) return Instance::Cast(obj).CanonicalizeHash();
      return obj.GetClassId();
    }
  };
  typedef UnorderedHashMap<LLVMConstantMapKeyEqualsTraits> LLVMConstantsMap;

  GrowableObjectArray& llvm_pool_;
  LLVMConstantsMap llvm_map_;
  Smi& llvm_index_;

  // Handles used across functions, where the contained value is used
  // immediately and does not need to live across calls to other serializer
  // functions.
  String& tmp_string_;

  // Handles for use within a single function in the following cases:
  //
  // * The function is guaranteed to not be re-entered during execution.
  // * The contained value is not live across any possible re-entry.
  //
  // Generally, the most likely source of possible re-entry is calling
  // DartValueToSExp with a sub-element of type Object, but any call to a
  // FlowGraphSerializer method that may eventually enter one of the methods
  // listed below should be examined with care.
  TypeArguments& array_type_args_;     // ArrayToSExp
  Context& closure_context_;           // ClosureToSExp
  Function& closure_function_;         // ClosureToSExp
  TypeArguments& closure_type_args_;   // ClosureToSExp
  Object& code_owner_;                 // CodeToSExp
  Context& context_parent_;            // ContextToSExp
  Object& context_elem_;               // ContextToSExp
  TypeArguments& function_type_args_;  // FunctionToSExp
  Function& ic_data_target_;           // ICDataToSExp
  AbstractType& ic_data_type_;         // ICDataToSExp
  Field& instance_field_;              // InstanceToSExp
  TypeArguments& instance_type_args_;  // InstanceToSExp
  Library& serialize_library_;         // SerializeCanonicalName
  Class& serialize_owner_;             // SerializeCanonicalName
  Function& serialize_parent_;         // SerializeCanonicalName
  AbstractType& type_arguments_elem_;  // TypeArgumentsToSExp
  Class& type_class_;                  // AbstractTypeToSExp
  Function& type_function_;            // AbstractTypeToSExp
  AbstractType& type_ref_type_;        // AbstractTypeToSExp
};

}  // namespace dart

#endif  // RUNTIME_VM_COMPILER_BACKEND_IL_SERIALIZER_H_
