// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_COMPILER_TYPES_H_
#define V8_COMPILER_TYPES_H_

#include "src/base/compiler-specific.h"
#include "src/common/globals.h"
#include "src/compiler/heap-refs.h"
#include "src/handles/handles.h"
#include "src/numbers/conversions.h"
#include "src/objects/objects.h"
#include "src/utils/ostreams.h"

namespace v8 {
namespace internal {
namespace compiler {

// SUMMARY
//
// A simple type system for compiler-internal use. It is based entirely on
// union types, and all subtyping hence amounts to set inclusion. Besides the
// obvious primitive types and some predefined unions, the type language also
// can express class types (a.k.a. specific maps) and singleton types (i.e.,
// concrete constants).
//
// The following equations and inequations hold:
//
//   None <= T
//   T <= Any
//
//   Number = Signed32 \/ Unsigned32 \/ Double
//   Smi <= Signed32
//   Name = String \/ Symbol
//   UniqueName = InternalizedString \/ Symbol
//   InternalizedString < String
//
//   Receiver = Object \/ Proxy
//   OtherUndetectable < Object
//   DetectableReceiver = Receiver - OtherUndetectable
//
//   Constant(x) < T  iff instance_type(map(x)) < T
//
//
// RANGE TYPES
//
// A range type represents a continuous integer interval by its minimum and
// maximum value.  Either value may be an infinity, in which case that infinity
// itself is also included in the range.   A range never contains NaN or -0.
//
// If a value v happens to be an integer n, then Constant(v) is considered a
// subtype of Range(n, n) (and therefore also a subtype of any larger range).
// In order to avoid large unions, however, it is usually a good idea to use
// Range rather than Constant.
//
//
// PREDICATES
//
// There are two main functions for testing types:
//
//   T1.Is(T2)     -- tests whether T1 is included in T2 (i.e., T1 <= T2)
//   T1.Maybe(T2)  -- tests whether T1 and T2 overlap (i.e., T1 /\ T2 =/= 0)
//
// Typically, the former is to be used to select representations (e.g., via
// T.Is(SignedSmall())), and the latter to check whether a specific case needs
// handling (e.g., via T.Maybe(Number())).
//
// There is no functionality to discover whether a type is a leaf in the
// lattice. That is intentional. It should always be possible to refine the
// lattice (e.g., splitting up number types further) without invalidating any
// existing assumptions or tests.
// Consequently, do not normally use Equals for type tests, always use Is!
//
// The NowIs operator implements state-sensitive subtying, as described above.
// Any compilation decision based on such temporary properties requires runtime
// guarding!
//
//
// PROPERTIES
//
// Various formal properties hold for constructors, operators, and predicates
// over types. For example, constructors are injective and subtyping is a
// complete partial order.
//
// See test/cctest/test-types.cc for a comprehensive executable specification,
// especially with respect to the properties of the more exotic 'temporal'
// constructors and predicates (those prefixed 'Now').
//
//
// IMPLEMENTATION
//
// Internally, all 'primitive' types, and their unions, are represented as
// bitsets. Bit 0 is reserved for tagging. Only structured types require
// allocation.

// -----------------------------------------------------------------------------
// Values for bitset types

// clang-format off

#define INTERNAL_BITSET_TYPE_LIST(V)                                      \
  V(OtherUnsigned31, 1u << 1)  \
  V(OtherUnsigned32, 1u << 2)  \
  V(OtherSigned32,   1u << 3)  \
  V(OtherNumber,     1u << 4)  \
  V(OtherString,     1u << 5)  \

#define PROPER_BITSET_TYPE_LIST(V) \
  V(None,                     0u)        \
  V(Negative31,               1u << 6)   \
  V(Null,                     1u << 7)   \
  V(Undefined,                1u << 8)   \
  V(Boolean,                  1u << 9)   \
  V(Unsigned30,               1u << 10)   \
  V(MinusZero,                1u << 11)  \
  V(NaN,                      1u << 12)  \
  V(Symbol,                   1u << 13)  \
  V(InternalizedString,       1u << 14)  \
  V(OtherCallable,            1u << 16)  \
  V(OtherObject,              1u << 17)  \
  V(OtherUndetectable,        1u << 18)  \
  V(CallableProxy,            1u << 19)  \
  V(OtherProxy,               1u << 20)  \
  V(Function,                 1u << 21)  \
  V(BoundFunction,            1u << 22)  \
  V(Hole,                     1u << 23)  \
  V(OtherInternal,            1u << 24)  \
  V(ExternalPointer,          1u << 25)  \
  V(Array,                    1u << 26)  \
  V(BigInt,                   1u << 27)  \
  \
  V(Signed31,                     kUnsigned30 | kNegative31) \
  V(Signed32,                     kSigned31 | kOtherUnsigned31 | \
                                  kOtherSigned32) \
  V(Signed32OrMinusZero,          kSigned32 | kMinusZero) \
  V(Signed32OrMinusZeroOrNaN,     kSigned32 | kMinusZero | kNaN) \
  V(Negative32,                   kNegative31 | kOtherSigned32) \
  V(Unsigned31,                   kUnsigned30 | kOtherUnsigned31) \
  V(Unsigned32,                   kUnsigned30 | kOtherUnsigned31 | \
                                  kOtherUnsigned32) \
  V(Unsigned32OrMinusZero,        kUnsigned32 | kMinusZero) \
  V(Unsigned32OrMinusZeroOrNaN,   kUnsigned32 | kMinusZero | kNaN) \
  V(Integral32,                   kSigned32 | kUnsigned32) \
  V(Integral32OrMinusZero,        kIntegral32 | kMinusZero) \
  V(Integral32OrMinusZeroOrNaN,   kIntegral32OrMinusZero | kNaN) \
  V(PlainNumber,                  kIntegral32 | kOtherNumber) \
  V(OrderedNumber,                kPlainNumber | kMinusZero) \
  V(MinusZeroOrNaN,               kMinusZero | kNaN) \
  V(Number,                       kOrderedNumber | kNaN) \
  V(Numeric,                      kNumber | kBigInt) \
  V(String,                       kInternalizedString | kOtherString) \
  V(UniqueName,                   kSymbol | kInternalizedString) \
  V(Name,                         kSymbol | kString) \
  V(InternalizedStringOrNull,     kInternalizedString | kNull) \
  V(BooleanOrNumber,              kBoolean | kNumber) \
  V(BooleanOrNullOrNumber,        kBooleanOrNumber | kNull) \
  V(BooleanOrNullOrUndefined,     kBoolean | kNull | kUndefined) \
  V(Oddball,                      kBooleanOrNullOrUndefined | kHole) \
  V(NullOrNumber,                 kNull | kNumber) \
  V(NullOrUndefined,              kNull | kUndefined) \
  V(Undetectable,                 kNullOrUndefined | kOtherUndetectable) \
  V(NumberOrHole,                 kNumber | kHole) \
  V(NumberOrOddball,              kNumber | kNullOrUndefined | kBoolean | \
                                  kHole) \
  V(NumericOrString,              kNumeric | kString) \
  V(NumberOrUndefined,            kNumber | kUndefined) \
  V(NumberOrUndefinedOrNullOrBoolean,  \
                                  kNumber | kNullOrUndefined | kBoolean) \
  V(PlainPrimitive,               kNumber | kString | kBoolean | \
                                  kNullOrUndefined) \
  V(NonBigIntPrimitive,           kSymbol | kPlainPrimitive) \
  V(Primitive,                    kBigInt | kNonBigIntPrimitive) \
  V(OtherUndetectableOrUndefined, kOtherUndetectable | kUndefined) \
  V(Proxy,                        kCallableProxy | kOtherProxy) \
  V(ArrayOrOtherObject,           kArray | kOtherObject) \
  V(ArrayOrProxy,                 kArray | kProxy) \
  V(DetectableCallable,           kFunction | kBoundFunction | \
                                  kOtherCallable | kCallableProxy) \
  V(Callable,                     kDetectableCallable | kOtherUndetectable) \
  V(NonCallable,                  kArray | kOtherObject | kOtherProxy) \
  V(NonCallableOrNull,            kNonCallable | kNull) \
  V(DetectableObject,             kArray | kFunction | kBoundFunction | \
                                  kOtherCallable | kOtherObject) \
  V(DetectableReceiver,           kDetectableObject | kProxy) \
  V(DetectableReceiverOrNull,     kDetectableReceiver | kNull) \
  V(Object,                       kDetectableObject | kOtherUndetectable) \
  V(Receiver,                     kObject | kProxy) \
  V(ReceiverOrUndefined,          kReceiver | kUndefined) \
  V(ReceiverOrNullOrUndefined,    kReceiver | kNull | kUndefined) \
  V(SymbolOrReceiver,             kSymbol | kReceiver) \
  V(StringOrReceiver,             kString | kReceiver) \
  V(Unique,                       kBoolean | kUniqueName | kNull | \
                                  kUndefined | kReceiver) \
  V(Internal,                     kHole | kExternalPointer | kOtherInternal) \
  V(NonInternal,                  kPrimitive | kReceiver) \
  V(NonBigInt,                    kNonBigIntPrimitive | kReceiver) \
  V(NonNumber,                    kBigInt | kUnique | kString | kInternal) \
  V(Any,                          0xfffffffeu)

// clang-format on

/*
 * The following diagrams show how integers (in the mathematical sense) are
 * divided among the different atomic numerical types.
 *
 *   ON    OS32     N31     U30     OU31    OU32     ON
 * ______[_______[_______[_______[_______[_______[_______
 *     -2^31   -2^30     0      2^30    2^31    2^32
 *
 * E.g., OtherUnsigned32 (OU32) covers all integers from 2^31 to 2^32-1.
 *
 * Some of the atomic numerical bitsets are internal only (see
 * INTERNAL_BITSET_TYPE_LIST).  To a types user, they should only occur in
 * union with certain other bitsets.  For instance, OtherNumber should only
 * occur as part of PlainNumber.
 */

#define BITSET_TYPE_LIST(V)    \
  INTERNAL_BITSET_TYPE_LIST(V) \
  PROPER_BITSET_TYPE_LIST(V)

class JSHeapBroker;
class HeapConstantType;
class OtherNumberConstantType;
class TupleType;
class Type;
class UnionType;

// -----------------------------------------------------------------------------
// Bitset types (internal).

class V8_EXPORT_PRIVATE BitsetType {
 public:
  using bitset = uint32_t;  // Internal

  enum : uint32_t {
#define DECLARE_TYPE(type, value) k##type = (value),
    BITSET_TYPE_LIST(DECLARE_TYPE)
#undef DECLARE_TYPE
        kUnusedEOL = 0
  };

  static bitset SignedSmall();
  static bitset UnsignedSmall();

  static bool IsNone(bitset bits) { return bits == kNone; }

  static bool Is(bitset bits1, bitset bits2) {
    return (bits1 | bits2) == bits2;
  }

  static double Min(bitset);
  static double Max(bitset);

  static bitset Glb(double min, double max);
  static bitset Lub(HeapObjectType const& type) {
    return Lub<HeapObjectType>(type);
  }
  static bitset Lub(MapRef const& map) { return Lub<MapRef>(map); }
  static bitset Lub(double value);
  static bitset Lub(double min, double max);
  static bitset ExpandInternals(bitset bits);

  static const char* Name(bitset);
  static void Print(std::ostream& os, bitset);  // NOLINT
#ifdef DEBUG
  static void Print(bitset);
#endif

  static bitset NumberBits(bitset bits);

 private:
  struct Boundary {
    bitset internal;
    bitset external;
    double min;
  };
  static const Boundary BoundariesArray[];
  static inline const Boundary* Boundaries();
  static inline size_t BoundariesSize();

  template <typename MapRefLike>
  static bitset Lub(MapRefLike const& map);
};

// -----------------------------------------------------------------------------
// Superclass for non-bitset types (internal).
class TypeBase {
 protected:
  friend class Type;

  enum Kind { kHeapConstant, kOtherNumberConstant, kTuple, kUnion, kRange };

  Kind kind() const { return kind_; }
  explicit TypeBase(Kind kind) : kind_(kind) {}

  static bool IsKind(Type type, Kind kind);

 private:
  Kind kind_;
};

// -----------------------------------------------------------------------------
// Range types.

class RangeType : public TypeBase {
 public:
  struct Limits {
    double min;
    double max;
    Limits(double min, double max) : min(min), max(max) {}
    explicit Limits(const RangeType* range)
        : min(range->Min()), max(range->Max()) {}
    bool IsEmpty();
    static Limits Empty() { return Limits(1, 0); }
    static Limits Intersect(Limits lhs, Limits rhs);
    static Limits Union(Limits lhs, Limits rhs);
  };

  double Min() const { return limits_.min; }
  double Max() const { return limits_.max; }

  static bool IsInteger(double x) {
    return nearbyint(x) == x && !IsMinusZero(x);  // Allows for infinities.
  }

 private:
  friend class Type;
  friend class BitsetType;
  friend class UnionType;

  static RangeType* New(double min, double max, Zone* zone) {
    return New(Limits(min, max), zone);
  }

  static RangeType* New(Limits lim, Zone* zone) {
    DCHECK(IsInteger(lim.min) && IsInteger(lim.max));
    DCHECK(lim.min <= lim.max);
    BitsetType::bitset bits = BitsetType::Lub(lim.min, lim.max);

    return new (zone->New(sizeof(RangeType))) RangeType(bits, lim);
  }

  RangeType(BitsetType::bitset bitset, Limits limits)
      : TypeBase(kRange), bitset_(bitset), limits_(limits) {}

  BitsetType::bitset Lub() const { return bitset_; }

  BitsetType::bitset bitset_;
  Limits limits_;
};

// -----------------------------------------------------------------------------
// The actual type.

class V8_EXPORT_PRIVATE Type {
 public:
  using bitset = BitsetType::bitset;  // Internal

// Constructors.
#define DEFINE_TYPE_CONSTRUCTOR(type, value) \
  static Type type() { return NewBitset(BitsetType::k##type); }
  PROPER_BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR)
#undef DEFINE_TYPE_CONSTRUCTOR

  Type() : payload_(0) {}

  static Type SignedSmall() { return NewBitset(BitsetType::SignedSmall()); }
  static Type UnsignedSmall() { return NewBitset(BitsetType::UnsignedSmall()); }

  static Type OtherNumberConstant(double value, Zone* zone);
  static Type HeapConstant(JSHeapBroker* broker, Handle<i::Object> value,
                           Zone* zone);
  static Type HeapConstant(const HeapObjectRef& value, Zone* zone);
  static Type Range(double min, double max, Zone* zone);
  static Type Range(RangeType::Limits lims, Zone* zone);
  static Type Tuple(Type first, Type second, Type third, Zone* zone);
  static Type Union(int length, Zone* zone);

  // NewConstant is a factory that returns Constant, Range or Number.
  static Type NewConstant(JSHeapBroker* broker, Handle<i::Object> value,
                          Zone* zone);
  static Type NewConstant(double value, Zone* zone);

  static Type Union(Type type1, Type type2, Zone* zone);
  static Type Intersect(Type type1, Type type2, Zone* zone);

  static Type For(HeapObjectType const& type) {
    return NewBitset(BitsetType::ExpandInternals(BitsetType::Lub(type)));
  }
  static Type For(MapRef const& type) {
    return NewBitset(BitsetType::ExpandInternals(BitsetType::Lub(type)));
  }

  // Predicates.
  bool IsNone() const { return payload_ == None().payload_; }
  bool IsInvalid() const { return payload_ == 0u; }

  bool Is(Type that) const {
    return payload_ == that.payload_ || this->SlowIs(that);
  }
  bool Maybe(Type that) const;
  bool Equals(Type that) const { return this->Is(that) && that.Is(*this); }

  // Inspection.
  bool IsBitset() const { return payload_ & 1; }
  bool IsRange() const { return IsKind(TypeBase::kRange); }
  bool IsHeapConstant() const { return IsKind(TypeBase::kHeapConstant); }
  bool IsOtherNumberConstant() const {
    return IsKind(TypeBase::kOtherNumberConstant);
  }
  bool IsTuple() const { return IsKind(TypeBase::kTuple); }

  const HeapConstantType* AsHeapConstant() const;
  const OtherNumberConstantType* AsOtherNumberConstant() const;
  const RangeType* AsRange() const;
  const TupleType* AsTuple() const;

  // Minimum and maximum of a numeric type.
  // These functions do not distinguish between -0 and +0.  NaN is ignored.
  // Only call them on subtypes of Number whose intersection with OrderedNumber
  // is not empty.
  double Min() const;
  double Max() const;

  // Extracts a range from the type: if the type is a range or a union
  // containing a range, that range is returned; otherwise, nullptr is returned.
  Type GetRange() const;

  int NumConstants() const;

  static Type Invalid() { return Type(); }

  bool operator==(Type other) const { return payload_ == other.payload_; }
  bool operator!=(Type other) const { return payload_ != other.payload_; }

  // Printing.

  void PrintTo(std::ostream& os) const;

#ifdef DEBUG
  void Print() const;
#endif

  // Helpers for testing.
  bool IsUnionForTesting() { return IsUnion(); }
  bitset AsBitsetForTesting() { return AsBitset(); }
  const UnionType* AsUnionForTesting() { return AsUnion(); }
  Type BitsetGlbForTesting() { return NewBitset(BitsetGlb()); }
  Type BitsetLubForTesting() { return NewBitset(BitsetLub()); }

 private:
  // Friends.
  template <class>
  friend class Iterator;
  friend BitsetType;
  friend UnionType;
  friend size_t hash_value(Type type);

  explicit Type(bitset bits) : payload_(bits | 1u) {}
  Type(TypeBase* type_base)  // NOLINT(runtime/explicit)
      : payload_(reinterpret_cast<uintptr_t>(type_base)) {}

  // Internal inspection.
  bool IsKind(TypeBase::Kind kind) const {
    if (IsBitset()) return false;
    const TypeBase* base = ToTypeBase();
    return base->kind() == kind;
  }

  const TypeBase* ToTypeBase() const {
    return reinterpret_cast<TypeBase*>(payload_);
  }
  static Type FromTypeBase(TypeBase* type) { return Type(type); }

  bool IsAny() const { return payload_ == Any().payload_; }
  bool IsUnion() const { return IsKind(TypeBase::kUnion); }

  bitset AsBitset() const {
    DCHECK(IsBitset());
    return static_cast<bitset>(payload_) ^ 1u;
  }

  const UnionType* AsUnion() const;

  bitset BitsetGlb() const;  // greatest lower bound that's a bitset
  bitset BitsetLub() const;  // least upper bound that's a bitset

  bool SlowIs(Type that) const;

  static Type NewBitset(bitset bits) { return Type(bits); }

  static bool Overlap(const RangeType* lhs, const RangeType* rhs);
  static bool Contains(const RangeType* lhs, const RangeType* rhs);

  static int UpdateRange(Type type, UnionType* result, int size, Zone* zone);

  static RangeType::Limits IntersectRangeAndBitset(Type range, Type bits,
                                                   Zone* zone);
  static RangeType::Limits ToLimits(bitset bits, Zone* zone);

  bool SimplyEquals(Type that) const;

  static int AddToUnion(Type type, UnionType* result, int size, Zone* zone);
  static int IntersectAux(Type type, Type other, UnionType* result, int size,
                          RangeType::Limits* limits, Zone* zone);
  static Type NormalizeUnion(UnionType* unioned, int size, Zone* zone);
  static Type NormalizeRangeAndBitset(Type range, bitset* bits, Zone* zone);

  // If LSB is set, the payload is a bitset; if LSB is clear, the payload is
  // a pointer to a subtype of the TypeBase class.
  uintptr_t payload_;
};

inline size_t hash_value(Type type) { return type.payload_; }
V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, Type type);

// -----------------------------------------------------------------------------
// Constant types.

class OtherNumberConstantType : public TypeBase {
 public:
  double Value() const { return value_; }

  static bool IsOtherNumberConstant(double value);

 private:
  friend class Type;
  friend class BitsetType;

  static OtherNumberConstantType* New(double value, Zone* zone) {
    return new (zone->New(sizeof(OtherNumberConstantType)))
        OtherNumberConstantType(value);  // NOLINT
  }

  explicit OtherNumberConstantType(double value)
      : TypeBase(kOtherNumberConstant), value_(value) {
    CHECK(IsOtherNumberConstant(value));
  }

  BitsetType::bitset Lub() const { return BitsetType::kOtherNumber; }

  double value_;
};

class V8_EXPORT_PRIVATE HeapConstantType : public NON_EXPORTED_BASE(TypeBase) {
 public:
  Handle<HeapObject> Value() const;
  const HeapObjectRef& Ref() const { return heap_ref_; }

 private:
  friend class Type;
  friend class BitsetType;

  static HeapConstantType* New(const HeapObjectRef& heap_ref, Zone* zone) {
    DCHECK(!heap_ref.IsHeapNumber());
    DCHECK_IMPLIES(heap_ref.IsString(), heap_ref.IsInternalizedString());
    BitsetType::bitset bitset = BitsetType::Lub(heap_ref.GetHeapObjectType());
    return new (zone->New(sizeof(HeapConstantType)))
        HeapConstantType(bitset, heap_ref);
  }

  HeapConstantType(BitsetType::bitset bitset, const HeapObjectRef& heap_ref);

  BitsetType::bitset Lub() const { return bitset_; }

  BitsetType::bitset bitset_;
  HeapObjectRef heap_ref_;
};

// -----------------------------------------------------------------------------
// Superclass for types with variable number of type fields.
class StructuralType : public TypeBase {
 public:
  int LengthForTesting() const { return Length(); }

 protected:
  friend class Type;

  int Length() const { return length_; }

  Type Get(int i) const {
    DCHECK(0 <= i && i < this->Length());
    return elements_[i];
  }

  void Set(int i, Type type) {
    DCHECK(0 <= i && i < this->Length());
    elements_[i] = type;
  }

  void Shrink(int length) {
    DCHECK(2 <= length && length <= this->Length());
    length_ = length;
  }

  StructuralType(Kind kind, int length, Zone* zone)
      : TypeBase(kind), length_(length) {
    elements_ = reinterpret_cast<Type*>(zone->New(sizeof(Type) * length));
  }

 private:
  int length_;
  Type* elements_;
};

// -----------------------------------------------------------------------------
// Tuple types.

class TupleType : public StructuralType {
 public:
  int Arity() const { return this->Length(); }
  Type Element(int i) const { return this->Get(i); }

  void InitElement(int i, Type type) { this->Set(i, type); }

 private:
  friend class Type;

  TupleType(int length, Zone* zone) : StructuralType(kTuple, length, zone) {}

  static TupleType* New(int length, Zone* zone) {
    return new (zone->New(sizeof(TupleType))) TupleType(length, zone);
  }
};

// -----------------------------------------------------------------------------
// Union types (internal).
// A union is a structured type with the following invariants:
// - its length is at least 2
// - at most one field is a bitset, and it must go into index 0
// - no field is a union
// - no field is a subtype of any other field
class UnionType : public StructuralType {
 private:
  friend Type;
  friend BitsetType;

  UnionType(int length, Zone* zone) : StructuralType(kUnion, length, zone) {}

  static UnionType* New(int length, Zone* zone) {
    return new (zone->New(sizeof(UnionType))) UnionType(length, zone);
  }

  bool Wellformed() const;
};

}  // namespace compiler
}  // namespace internal
}  // namespace v8

#endif  // V8_COMPILER_TYPES_H_
