예제 #1
0
/*
 * Note: this is currently separate from typeFromRAT for now, just because we
 * don't want to enable every single type for assertions yet.
 *
 * (Some of them currently regress performance, presumably because the IR
 * doesn't always handle the additional type information very well.  It is
 * possibly a compile-time slowdown only, but we haven't investigated yet.)
 */
folly::Optional<Type> ratToAssertType(IRGS& env, RepoAuthType rat) {
  using T = RepoAuthType::Tag;

  switch (rat.tag()) {
    case T::Uninit:
    case T::InitNull:
    case T::Null:
    case T::Bool:
    case T::Int:
    case T::Dbl:
    case T::Res:
    case T::SStr:
    case T::Str:
    case T::Obj:
    case T::SArr:
    case T::Arr:
    case T::Cell:
    case T::Ref:
    case T::InitUnc:
    case T::Unc:
      return typeFromRAT(rat);

    case T::OptExactObj:
    case T::OptSubObj:
    case T::ExactObj:
    case T::SubObj: {
      auto ty = typeFromRAT(rat);
      auto const cls = Unit::lookupClassOrUniqueClass(rat.clsName());

      if (!classIsUniqueOrCtxParent(env, cls)) {
        ty |= TObj; // Kill specialization.
      }
      return ty;
    }

    // Type assertions can't currently handle Init-ness.
    case T::InitCell:
      return TCell;
    case T::InitGen:
      return folly::none;

    case T::Gen:
      return folly::none;

    case T::OptInt:
    case T::OptObj:
    case T::OptDbl:
    case T::OptBool:
    case T::OptSStr:
    case T::OptStr:
    case T::OptRes:
      return folly::none;

    case T::OptSArr:
    case T::OptArr:
      // TODO(#4205897): optional array types.
      return folly::none;
  }
  not_reached();
}
예제 #2
0
SSATmp* ldClsPropAddrKnown(IRGS& env,
                           const Class* cls,
                           const StringData* name) {
  initSProps(env, cls); // calls init; must be above sPropHandle()
  auto const slot = cls->lookupSProp(name);
  auto const handle = cls->sPropHandle(slot);
  auto const repoTy =
    !RuntimeOption::RepoAuthoritative
      ? RepoAuthType{}
      : cls->staticPropRepoAuthType(slot);
  auto const ptrTy = typeFromRAT(repoTy).ptr(Ptr::SProp);
  return gen(env, LdRDSAddr, RDSHandleData { handle }, ptrTy);
}
예제 #3
0
Type packedArrayElemType(SSATmp* arr, SSATmp* idx, const Class* ctx) {
  assertx(arr->isA(TArr) &&
          arr->type().arrSpec().kind() == ArrayData::kPackedKind &&
          idx->isA(TInt));

  if (arr->hasConstVal() && idx->hasConstVal()) {
    auto const idxVal = idx->intVal();
    if (idxVal >= 0 && idxVal < arr->arrVal()->size()) {
      return Type(arr->arrVal()->nvGet(idxVal)->m_type);
    }
    return TInitNull;
  }

  Type t = arr->isA(TPersistentArr) ? TInitCell : TGen;

  auto const at = arr->type().arrSpec().type();
  if (!at) return t;

  switch (at->tag()) {
    case RepoAuthType::Array::Tag::Packed:
    {
      if (idx->hasConstVal(TInt)) {
        auto const idxVal = idx->intVal();
        if (idxVal >= 0 && idxVal < at->size()) {
          return typeFromRAT(at->packedElem(idxVal), ctx) & t;
        }
        return TInitNull;
      }
      Type elemType = TBottom;
      for (uint32_t i = 0; i < at->size(); ++i) {
        elemType |= typeFromRAT(at->packedElem(i), ctx);
      }
      return elemType & t;
    }
    case RepoAuthType::Array::Tag::PackedN:
      return typeFromRAT(at->elemType(), ctx) & t;
  }
  not_reached();
}