// 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_TYPE_CACHE_H_
#define V8_TYPE_CACHE_H_

#include "src/types.h"

namespace v8 {
namespace internal {

class TypeCache final {
 private:
  // This has to be first for the initialization magic to work.
  base::AccountingAllocator allocator;
  Zone zone_;

 public:
  static TypeCache const& Get();

  TypeCache() : zone_(&allocator) {}

  Type* const kInt8 =
      CreateNative(CreateRange<int8_t>(), Type::UntaggedIntegral8());
  Type* const kUint8 =
      CreateNative(CreateRange<uint8_t>(), Type::UntaggedIntegral8());
  Type* const kUint8Clamped = kUint8;
  Type* const kInt16 =
      CreateNative(CreateRange<int16_t>(), Type::UntaggedIntegral16());
  Type* const kUint16 =
      CreateNative(CreateRange<uint16_t>(), Type::UntaggedIntegral16());
  Type* const kInt32 =
      CreateNative(Type::Signed32(), Type::UntaggedIntegral32());
  Type* const kUint32 =
      CreateNative(Type::Unsigned32(), Type::UntaggedIntegral32());
  Type* const kFloat32 = CreateNative(Type::Number(), Type::UntaggedFloat32());
  Type* const kFloat64 = CreateNative(Type::Number(), Type::UntaggedFloat64());

  Type* const kSmi = CreateNative(Type::SignedSmall(), Type::TaggedSigned());
  Type* const kHoleySmi = Type::Union(kSmi, Type::Hole(), zone());
  Type* const kHeapNumber = CreateNative(Type::Number(), Type::TaggedPointer());

  Type* const kSingletonZero = CreateRange(0.0, 0.0);
  Type* const kSingletonOne = CreateRange(1.0, 1.0);
  Type* const kSingletonTen = CreateRange(10.0, 10.0);
  Type* const kSingletonMinusOne = CreateRange(-1.0, -1.0);
  Type* const kZeroOrUndefined =
      Type::Union(kSingletonZero, Type::Undefined(), zone());
  Type* const kTenOrUndefined =
      Type::Union(kSingletonTen, Type::Undefined(), zone());
  Type* const kMinusOneOrZero = CreateRange(-1.0, 0.0);
  Type* const kMinusOneToOneOrMinusZeroOrNaN = Type::Union(
      Type::Union(CreateRange(-1.0, 1.0), Type::MinusZero(), zone()),
      Type::NaN(), zone());
  Type* const kZeroOrOne = CreateRange(0.0, 1.0);
  Type* const kZeroOrOneOrNaN = Type::Union(kZeroOrOne, Type::NaN(), zone());
  Type* const kZeroToThirtyOne = CreateRange(0.0, 31.0);
  Type* const kZeroToThirtyTwo = CreateRange(0.0, 32.0);
  Type* const kZeroish =
      Type::Union(kSingletonZero, Type::MinusZeroOrNaN(), zone());
  Type* const kInteger = CreateRange(-V8_INFINITY, V8_INFINITY);
  Type* const kIntegerOrMinusZero =
      Type::Union(kInteger, Type::MinusZero(), zone());
  Type* const kIntegerOrMinusZeroOrNaN =
      Type::Union(kIntegerOrMinusZero, Type::NaN(), zone());
  Type* const kPositiveInteger = CreateRange(0.0, V8_INFINITY);
  Type* const kPositiveIntegerOrMinusZero =
      Type::Union(kPositiveInteger, Type::MinusZero(), zone());
  Type* const kPositiveIntegerOrMinusZeroOrNaN =
      Type::Union(kPositiveIntegerOrMinusZero, Type::NaN(), zone());

  Type* const kAdditiveSafeInteger =
      CreateRange(-4503599627370496.0, 4503599627370496.0);
  Type* const kSafeInteger = CreateRange(-kMaxSafeInteger, kMaxSafeInteger);
  Type* const kAdditiveSafeIntegerOrMinusZero =
      Type::Union(kAdditiveSafeInteger, Type::MinusZero(), zone());
  Type* const kSafeIntegerOrMinusZero =
      Type::Union(kSafeInteger, Type::MinusZero(), zone());
  Type* const kPositiveSafeInteger = CreateRange(0.0, kMaxSafeInteger);

  Type* const kUntaggedUndefined =
      Type::Intersect(Type::Undefined(), Type::Untagged(), zone());

  // Asm.js related types.
  Type* const kAsmSigned = kInt32;
  Type* const kAsmUnsigned = kUint32;
  Type* const kAsmInt = Type::Union(kAsmSigned, kAsmUnsigned, zone());
  Type* const kAsmFixnum = Type::Intersect(kAsmSigned, kAsmUnsigned, zone());
  Type* const kAsmFloat = kFloat32;
  Type* const kAsmDouble = kFloat64;
  Type* const kAsmFloatQ = Type::Union(kAsmFloat, kUntaggedUndefined, zone());
  Type* const kAsmDoubleQ = Type::Union(kAsmDouble, kUntaggedUndefined, zone());
  // Not part of the Asm.js type hierarchy, but represents a part of what
  // intish encompasses.
  Type* const kAsmIntQ = Type::Union(kAsmInt, kUntaggedUndefined, zone());
  Type* const kAsmFloatDoubleQ = Type::Union(kAsmFloatQ, kAsmDoubleQ, zone());
  // Asm.js size unions.
  Type* const kAsmSize8 = Type::Union(kInt8, kUint8, zone());
  Type* const kAsmSize16 = Type::Union(kInt16, kUint16, zone());
  Type* const kAsmSize32 =
      Type::Union(Type::Union(kInt32, kUint32, zone()), kAsmFloat, zone());
  Type* const kAsmSize64 = kFloat64;
  // Asm.js other types.
  Type* const kAsmComparable = Type::Union(
      kAsmSigned,
      Type::Union(kAsmUnsigned, Type::Union(kAsmDouble, kAsmFloat, zone()),
                  zone()),
      zone());
  Type* const kAsmIntArrayElement =
      Type::Union(Type::Union(kInt8, kUint8, zone()),
                  Type::Union(Type::Union(kInt16, kUint16, zone()),
                              Type::Union(kInt32, kUint32, zone()), zone()),
                  zone());

  // The FixedArray::length property always containts a smi in the range
  // [0, FixedArray::kMaxLength].
  Type* const kFixedArrayLengthType = CreateNative(
      CreateRange(0.0, FixedArray::kMaxLength), Type::TaggedSigned());

  // The FixedDoubleArray::length property always containts a smi in the range
  // [0, FixedDoubleArray::kMaxLength].
  Type* const kFixedDoubleArrayLengthType = CreateNative(
      CreateRange(0.0, FixedDoubleArray::kMaxLength), Type::TaggedSigned());

  // The JSArray::length property always contains a tagged number in the range
  // [0, kMaxUInt32].
  Type* const kJSArrayLengthType =
      CreateNative(Type::Unsigned32(), Type::Tagged());

  // The JSTyped::length property always contains a tagged number in the range
  // [0, kMaxSmiValue].
  Type* const kJSTypedArrayLengthType =
      CreateNative(Type::UnsignedSmall(), Type::TaggedSigned());

  // The String::length property always contains a smi in the range
  // [0, String::kMaxLength].
  Type* const kStringLengthType =
      CreateNative(CreateRange(0.0, String::kMaxLength), Type::TaggedSigned());

#define TYPED_ARRAY(TypeName, type_name, TYPE_NAME, ctype, size) \
  Type* const k##TypeName##Array = CreateArray(k##TypeName);
  TYPED_ARRAYS(TYPED_ARRAY)
#undef TYPED_ARRAY

 private:
  Type* CreateArray(Type* element) { return Type::Array(element, zone()); }

  Type* CreateArrayFunction(Type* array) {
    Type* arg1 = Type::Union(Type::Unsigned32(), Type::Object(), zone());
    Type* arg2 = Type::Union(Type::Unsigned32(), Type::Undefined(), zone());
    Type* arg3 = arg2;
    return Type::Function(array, arg1, arg2, arg3, zone());
  }

  Type* CreateNative(Type* semantic, Type* representation) {
    return Type::Intersect(semantic, representation, zone());
  }

  template <typename T>
  Type* CreateRange() {
    return CreateRange(std::numeric_limits<T>::min(),
                       std::numeric_limits<T>::max());
  }

  Type* CreateRange(double min, double max) {
    return Type::Range(min, max, zone());
  }

  Zone* zone() { return &zone_; }
};

}  // namespace internal
}  // namespace v8

#endif  // V8_TYPE_CACHE_H_
