// Copyright (c) 2018, 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.

// Slot is an abstraction that describes an readable (and possibly writeable)
// location within an object.
//
// In general slots follow the memory model for normal Dart fields - but can
// also be used to describe locations that don't have corresponding Field
// object, i.e. fields within native objects like arrays or contexts.
//
// Slot objects created by the compiler have an identity. If two slots F and G
// are different then compiler assumes that store into F can't alias a load
// from G and vice versa.
//
// All slots can be split into 4 categories:
//
//   - slots for fields of native classes (Array, Closure, etc);
//   - slots for type arguments;
//   - slots for captured variable;
//   - slots for normal Dart fields (e.g. those that Field object).
//

#ifndef RUNTIME_VM_COMPILER_BACKEND_SLOT_H_
#define RUNTIME_VM_COMPILER_BACKEND_SLOT_H_

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

#include "vm/compiler/backend/compile_type.h"
#include "vm/compiler/backend/locations.h"
#include "vm/thread.h"

namespace dart {

class LocalScope;
class LocalVariable;
class ParsedFunction;

// The list of slots that correspond to nullable boxed fields of native objects
// in the following format:
//
//     V(class_name, underlying_type, field_name, exact_type, FINAL|VAR)
//
// - class_name and field_name specify the name of the host class and the name
//   of the field respectively;
// - underlying_type: the Raw class which holds the field;
// - exact_type specifies exact type of the field (any load from this field
//   would only yield instances of this type);
// - the last component specifies whether field behaves like a final field
//   (i.e. initialized once at construction time and does not change after
//   that) or like a non-final field.
#define NULLABLE_BOXED_NATIVE_SLOTS_LIST(V)                                    \
  V(Function, UntaggedFunction, signature, FunctionType, FINAL_COMPRESSED)     \
  V(Context, UntaggedContext, parent, Context, FINAL)                          \
  V(Closure, UntaggedClosure, instantiator_type_arguments, TypeArguments,      \
    FINAL)                                                                     \
  V(Closure, UntaggedClosure, delayed_type_arguments, TypeArguments, FINAL)    \
  V(Closure, UntaggedClosure, function_type_arguments, TypeArguments, FINAL)   \
  V(ClosureData, UntaggedClosureData, default_type_arguments, TypeArguments,   \
    FINAL_COMPRESSED)                                                          \
  V(Type, UntaggedType, arguments, TypeArguments, FINAL_COMPRESSED)            \
  V(FunctionType, UntaggedFunctionType, type_parameters, TypeArguments,        \
    FINAL_COMPRESSED)                                                          \
  V(WeakProperty, UntaggedWeakProperty, key, Dynamic, VAR)                     \
  V(WeakProperty, UntaggedWeakProperty, value, Dynamic, VAR)

// The list of slots that correspond to non-nullable boxed fields of native
// objects in the following format:
//
//     V(class_name, underlying_type, field_name, exact_type, FINAL|VAR)
//
// - class_name and field_name specify the name of the host class and the name
//   of the field respectively;
// - underlying_type: the Raw class which holds the field;
// - exact_type specifies exact type of the field (any load from this field
//   would only yield instances of this type);
// - the last component specifies whether field behaves like a final field
//   (i.e. initialized once at construction time and does not change after
//   that) or like a non-final field.
#define NONNULLABLE_BOXED_NATIVE_SLOTS_LIST(V)                                 \
  V(Array, UntaggedArray, length, Smi, FINAL)                                  \
  V(Closure, UntaggedClosure, function, Function, FINAL)                       \
  V(Closure, UntaggedClosure, context, Context, FINAL)                         \
  V(Closure, UntaggedClosure, hash, Context, VAR)                              \
  V(Function, UntaggedFunction, data, Dynamic, FINAL_COMPRESSED)               \
  V(FunctionType, UntaggedFunctionType, parameter_names, Array,                \
    FINAL_COMPRESSED)                                                          \
  V(FunctionType, UntaggedFunctionType, parameter_types, Array,                \
    FINAL_COMPRESSED)                                                          \
  V(GrowableObjectArray, UntaggedGrowableObjectArray, length, Smi, VAR)        \
  V(GrowableObjectArray, UntaggedGrowableObjectArray, data, Array, VAR)        \
  V(TypedDataBase, UntaggedTypedDataBase, length, Smi, FINAL_COMPRESSED)       \
  V(TypedDataView, UntaggedTypedDataView, offset_in_bytes, Smi,                \
    FINAL_COMPRESSED)                                                          \
  V(TypedDataView, UntaggedTypedDataView, data, Dynamic, FINAL_COMPRESSED)     \
  V(String, UntaggedString, length, Smi, FINAL_COMPRESSED)                     \
  V(LinkedHashMap, UntaggedLinkedHashMap, index, TypedDataUint32Array, VAR)    \
  V(LinkedHashMap, UntaggedLinkedHashMap, data, Array, VAR)                    \
  V(LinkedHashMap, UntaggedLinkedHashMap, hash_mask, Smi, VAR)                 \
  V(LinkedHashMap, UntaggedLinkedHashMap, used_data, Smi, VAR)                 \
  V(LinkedHashMap, UntaggedLinkedHashMap, deleted_keys, Smi, VAR)              \
  V(ArgumentsDescriptor, UntaggedArray, type_args_len, Smi, FINAL)             \
  V(ArgumentsDescriptor, UntaggedArray, positional_count, Smi, FINAL)          \
  V(ArgumentsDescriptor, UntaggedArray, count, Smi, FINAL)                     \
  V(ArgumentsDescriptor, UntaggedArray, size, Smi, FINAL)                      \
  V(PointerBase, UntaggedPointerBase, data_field, Dynamic, FINAL)              \
  V(TypeArguments, UntaggedTypeArguments, length, Smi, FINAL_COMPRESSED)       \
  V(TypeParameter, UntaggedTypeParameter, bound, Dynamic, FINAL_COMPRESSED)    \
  V(TypeParameter, UntaggedTypeParameter, name, Dynamic, FINAL_COMPRESSED)     \
  V(UnhandledException, UntaggedUnhandledException, exception, Dynamic,        \
    FINAL_COMPRESSED)                                                          \
  V(UnhandledException, UntaggedUnhandledException, stacktrace, Dynamic,       \
    FINAL_COMPRESSED)

// List of slots that correspond to unboxed fields of native objects in the
// following format:
//
//     V(class_name, underlying_type, field_name, representation, FINAL|VAR)
//
// - class_name and field_name specify the name of the host class and the name
//   of the field respectively;
// - underlying_type: the Raw class which holds the field;
// - representation specifies the representation of the bits stored within
//   the unboxed field (minus the kUnboxed prefix);
// - the last component specifies whether field behaves like a final field
//   (i.e. initialized once at construction time and does not change after
//   that) or like a non-final field.
//
// Note: As the underlying field is unboxed, these slots cannot be nullable.
#define UNBOXED_NATIVE_SLOTS_LIST(V)                                           \
  V(ClosureData, UntaggedClosureData, default_type_arguments_kind, Uint8,      \
    FINAL)                                                                     \
  V(Function, UntaggedFunction, kind_tag, Uint32, FINAL)                       \
  V(Function, UntaggedFunction, packed_fields, Uint32, FINAL)                  \
  V(FunctionType, UntaggedFunctionType, packed_fields, Uint32, FINAL)          \
  V(Pointer, UntaggedPointer, data_field, FfiIntPtr, FINAL)                    \
  V(TypedDataBase, UntaggedTypedDataBase, data_field, IntPtr, VAR)             \
  V(TypeParameter, UntaggedTypeParameter, flags, Uint8, FINAL)

// For uses that do not need the exact_type (boxed) or representation (unboxed)
// or whether a boxed native slot is nullable. (Generally, such users only need
// the class name, the underlying type, and/or the field name.)
#define NATIVE_SLOTS_LIST(V)                                                   \
  NULLABLE_BOXED_NATIVE_SLOTS_LIST(V)                                          \
  NONNULLABLE_BOXED_NATIVE_SLOTS_LIST(V)                                       \
  UNBOXED_NATIVE_SLOTS_LIST(V)

// Slot is an abstraction that describes an readable (and possibly writeable)
// location within an object.
//
// Slot objects returned by Slot::Get* methods have identity and can be
// compared by pointer. If two slots are different they must not alias.
// If two slots can alias - they must be represented by identical
// slot object.
class Slot : public ZoneAllocated {
 public:
  // clang-format off
  enum class Kind : uint8_t {
    // Native slots are identified by their kind - each native slot has its own.
#define DECLARE_KIND(ClassName, __, FieldName, ___, ____)                      \
  k##ClassName##_##FieldName,
    NATIVE_SLOTS_LIST(DECLARE_KIND)
#undef DECLARE_KIND

    // A slot used to store type arguments.
    kTypeArguments,

    // A slot at a specific [index] in a [RawTypeArgument] vector.
    kTypeArgumentsIndex,

    // A slot corresponding to an array element at given offset.
    // Only used during allocation sinking and in MaterializeObjectInstr.
    kArrayElement,

    // A slot within a Context object that contains a value of a captured
    // local variable.
    kCapturedVariable,

    // A slot that corresponds to a Dart field (has corresponding Field object).
    kDartField,
  };
  // clang-format on

  static const char* KindToCString(Kind k);
  static bool ParseKind(const char* str, Kind* k);

  // Returns a slot that represents length field for the given [array_cid].
  static const Slot& GetLengthFieldForArrayCid(intptr_t array_cid);

  // Return a slot that represents type arguments field at the given offset
  // or for the given class.
  //
  // We do not distinguish type argument fields within disjoint
  // class hierarchies: type argument fields at the same offset would be
  // represented by the same Slot object. Type argument slots are final
  // so disambiguating type arguments fields does not improve alias analysis.
  static const Slot& GetTypeArgumentsSlotAt(Thread* thread, intptr_t offset);
  static const Slot& GetTypeArgumentsSlotFor(Thread* thread, const Class& cls);

  // Returns a slot at a specific [index] in a [RawTypeArgument] vector.
  static const Slot& GetTypeArgumentsIndexSlot(Thread* thread, intptr_t index);

  // Returns a slot corresponding to an array element at [offset_in_bytes].
  static const Slot& GetArrayElementSlot(Thread* thread,
                                         intptr_t offset_in_bytes);

  // Returns a slot that represents the given captured local variable.
  static const Slot& GetContextVariableSlotFor(Thread* thread,
                                               const LocalVariable& var);

  // Returns a slot that represents the given Dart field.
  static const Slot& Get(const Field& field,
                         const ParsedFunction* parsed_function);

  // Convenience getters for native slots.
#define DEFINE_GETTER(ClassName, UnderlyingType, FieldName, __, ___)           \
  static const Slot& ClassName##_##FieldName() {                               \
    return GetNativeSlot(Kind::k##ClassName##_##FieldName);                    \
  }

  NATIVE_SLOTS_LIST(DEFINE_GETTER)
#undef DEFINE_GETTER

  Kind kind() const { return kind_; }
  bool IsDartField() const { return kind() == Kind::kDartField; }
  bool IsLocalVariable() const { return kind() == Kind::kCapturedVariable; }
  bool IsTypeArguments() const { return kind() == Kind::kTypeArguments; }
  bool IsArgumentOfType() const { return kind() == Kind::kTypeArgumentsIndex; }
  bool IsArrayElement() const { return kind() == Kind::kArrayElement; }

  const char* Name() const;

  intptr_t offset_in_bytes() const { return offset_in_bytes_; }

  // Currently returns the representation of unboxed native fields and kTagged
  // for most other types of fields. One special case: fields marked as
  // containing non-nullable ints in AOT kernel, which have the kUnboxedInt64
  // representation.
  Representation representation() const { return representation_; }

  bool is_immutable() const { return IsImmutableBit::decode(flags_); }

  intptr_t nullable_cid() const { return cid_; }
  bool is_nullable() const { return IsNullableBit::decode(flags_); }

  // Returns true if properties of this slot were based on the guarded state
  // of the corresponding Dart field.
  bool is_guarded_field() const { return IsGuardedBit::decode(flags_); }

  bool is_compressed() const { return IsCompressedBit::decode(flags_); }

  // Static type of the slots if any.
  //
  // A value that is read from the slot is guaranteed to be assignable to its
  // static type.
  const AbstractType& static_type() const;

  // More precise type information about values that can be read from this slot.
  CompileType ComputeCompileType() const;

  const Field& field() const {
    ASSERT(IsDartField());
    ASSERT(data_ != nullptr);
    return *DataAs<const Field>();
  }

  bool Equals(const Slot& other) const;
  uword Hash() const;

  bool IsIdentical(const Slot& other) const { return this == &other; }

  bool IsContextSlot() const {
    return kind() == Kind::kCapturedVariable || kind() == Kind::kContext_parent;
  }

 private:
  friend class FlowGraphDeserializer;  // For GetNativeSlot.

  Slot(Kind kind,
       int8_t bits,
       ClassIdTagType cid,
       intptr_t offset_in_bytes,
       const void* data,
       const AbstractType* static_type,
       Representation representation)
      : kind_(kind),
        flags_(bits),
        cid_(cid),
        offset_in_bytes_(offset_in_bytes),
        representation_(representation),
        data_(data),
        static_type_(static_type) {}

  Slot(const Slot& other)
      : Slot(other.kind_,
             other.flags_,
             other.cid_,
             other.offset_in_bytes_,
             other.data_,
             other.static_type_,
             other.representation_) {}

  using IsImmutableBit = BitField<int8_t, bool, 0, 1>;
  using IsNullableBit = BitField<int8_t, bool, IsImmutableBit::kNextBit, 1>;
  using IsGuardedBit = BitField<int8_t, bool, IsNullableBit::kNextBit, 1>;
  using IsCompressedBit = BitField<int8_t, bool, IsGuardedBit::kNextBit, 1>;

  template <typename T>
  const T* DataAs() const {
    return static_cast<const T*>(data_);
  }

  // There is a fixed statically known number of native slots so we cache
  // them statically.
  static AcqRelAtomic<Slot*> native_fields_;
  static const Slot& GetNativeSlot(Kind kind);

  const Kind kind_;
  const int8_t flags_;  // is_immutable, is_nullable
  const ClassIdTagType cid_;  // Concrete cid of a value or kDynamicCid.

  const intptr_t offset_in_bytes_;
  const Representation representation_;

  // Kind dependent data:
  //   - name as a Dart String object for local variables;
  //   - name as a C string for native slots;
  //   - Field object for Dart fields;
  const void* data_;

  const AbstractType* static_type_;

  friend class SlotCache;
};

}  // namespace dart

#endif  // RUNTIME_VM_COMPILER_BACKEND_SLOT_H_
