Пример #1
0
bool ArraySpec::operator<=(const ArraySpec& rhs) const {
  auto const& lhs = *this;

  if (lhs == Bottom || rhs == Top) return true;
  if (lhs == Top || rhs == Bottom) return false;

  // It's possible to subtype RAT::Array types, but it's potentially O(n), so
  // we just don't do it.
  return (!rhs.kind()  || lhs.kind()  == rhs.kind()) &&
         (!rhs.type()  || lhs.type()  == rhs.type()) &&
         (!rhs.shape() || lhs.shape() == rhs.shape());
}
Пример #2
0
// Return true if the array satisfies requirement on the ArraySpec.
static bool arrayFitsSpec(const ArrayData* arr, const ArraySpec spec) {
  if (spec == ArraySpec::Top) return true;

  if (auto const spec_kind = spec.kind()) {
    if (arr->kind() == spec_kind) return true;
  }

  if (auto const rat_type = spec.type()) {
    using A = RepoAuthType::Array;
    if (arr->empty() && rat_type->emptiness() != A::Empty::No) return true;
    if (arr->isVectorData()) {
      switch (rat_type->tag()) {
        case A::Tag::Packed:
          if (arr->size() != rat_type->size()) break;
          // fall through
        case A::Tag::PackedN: {
          int64_t k = 0;
          for ( ; k < arr->size(); ++k) {
            auto const specElemType =
              rat_type->tag() == A::Tag::Packed ? rat_type->packedElem(k)
                                                : rat_type->elemType();
            if (!tvMatchesRepoAuthType(*(arr->get(k).asTypedValue()),
                                       specElemType)) {
              break;
            }
          }
          if (k == arr->size()) return true;
          break;
        }
      }
    }
  }

  return false;
}
Пример #3
0
ArraySpec ArraySpec::operator|(const ArraySpec& rhs) const {
  auto const& lhs = *this;

  if (lhs <= rhs) return rhs;
  if (rhs <= lhs) return lhs;

  // Take the union componentwise.  Components union trivially (i.e., to
  // "unspecialized") unless they are equal.
  auto new_kind = lhs.kind() == rhs.kind() ? lhs.kind() : folly::none;
  auto new_type = lhs.type() == rhs.type() ? lhs.type() : nullptr;

  // If the shapes were nontrivial and equal, the specs would be equal.
  assertx(!lhs.shape() || lhs.shape() != rhs.shape());

  // Nontrivial kind /and/ type unions would imply equal kinds and types.
  assertx(!new_kind || !new_type);

  if (new_kind) return ArraySpec(*new_kind);
  if (new_type) return ArraySpec(new_type);
  return Top;
}