Beispiel #1
0
bool Type::checkValid() const {
  static_assert(sizeof(m_arrayKind) == 1,
                "Type expects ArrayKind to be one byte");
  if (m_extra) {
    assert((!(m_bits & kAnyObj) || !(m_bits & kAnyArr)) &&
           "Conflicting specialization");

    if (canSpecializeArrayKind() && hasArrayKind() && !m_hasConstVal) {
      assert(!(m_extra & 0xffffffffffff0000) &&
             "Non-zero padding bits in Type with array kind");
    }
  }

  return true;
}
Beispiel #2
0
RuntimeType Type::toRuntimeType() const {
  assert(!isPtr());
  auto const outer = isBoxed() ? KindOfRef : toDataType();
  auto const inner = isBoxed() ? innerType().toDataType() : KindOfNone;
  auto rtt = RuntimeType{outer, inner};

  if (isSpecialized()) {
    if (subtypeOf(Type::Arr)) {
      return hasArrayKind() ? rtt.setArrayKind(getArrayKind()) : rtt;
    }
    if (subtypeOf(Type::Obj)) {
      return rtt.setKnownClass(getClass());
    }
  }

  return rtt;
}
Beispiel #3
0
Type Type::combine(bits_t newBits, Type other) const {
  static_assert(std::is_same<Oper, Union>::value ||
                std::is_same<Oper, Intersect>::value,
                "Type::combine given unsupported template argument");

  // If neither type is specialized, the result is simple.
  if (LIKELY(!isSpecialized() && !other.isSpecialized())) {
    return Type(newBits);
  }

  // If one of the types can't be specialized while the other is specialized,
  // preserve the specialization.
  if (!canSpecializeAny() || !other.canSpecializeAny()) {
    auto const specType = isSpecialized() ? specializedType()
                                          : other.specializedType();

    // If the specialized type doesn't exist in newBits, drop the
    // specialization.
    if (newBits & specType.m_bits) return Type(newBits, specType.m_extra);
    return Type(newBits);
  }

  // If both types are eligible for the same kind of specialization and at
  // least one is specialized, delegate to Oper::combineSame.
  if (canSpecializeClass() && other.canSpecializeClass()) {
    folly::Optional<const Class*> aClass, bClass;
    if (getClass()) aClass = getClass();
    if (other.getClass()) bClass = other.getClass();

    return Oper::template combineSame<ClassOps>(newBits, kAnyObj,
                                                aClass, bClass);
  }

  if (canSpecializeArrayKind() && other.canSpecializeArrayKind()) {
    folly::Optional<ArrayData::ArrayKind> aKind, bKind;
    if (hasArrayKind()) aKind = getArrayKind();
    if (other.hasArrayKind()) bKind = other.getArrayKind();

    return Oper::template combineSame<ArrayOps>(newBits, kAnyArr, aKind, bKind);
  }

  // The types are eligible for different kinds of specialization and at least
  // one is specialized, so delegate to Oper::combineDifferent.
  return Oper::combineDifferent(newBits, *this, other);
}