Exemplo n.º 1
0
bool tvMatchesRepoAuthType(TypedValue tv, RepoAuthType ty) {
    assert(tvIsPlausible(tv));

    bool const initNull = tv.m_type == KindOfNull;

    using T = RepoAuthType::Tag;
    switch (ty.tag()) {
    case T::Uninit:
        return tv.m_type == KindOfUninit;
    case T::InitNull:
        return initNull;

    case T::OptBool:
        if (initNull) return true;
    // fallthrough
    case T::Bool:
        return tv.m_type == KindOfBoolean;
    case T::OptInt:
        if (initNull) return true;
    // fallthrough
    case T::Int:
        return tv.m_type == KindOfInt64;
    case T::OptDbl:
        if (initNull) return true;
    // fallthrough
    case T::Dbl:
        return tv.m_type == KindOfDouble;
    case T::OptRes:
        if (initNull) return true;
    // fallthrough
    case T::Res:
        return tv.m_type == KindOfResource;
    case T::OptObj:
        if (initNull) return true;
    // fallthrough
    case T::Obj:
        return tv.m_type == KindOfObject;

    case T::OptSStr:
        if (initNull) return true;
    // fallthrough
    case T::SStr:
        return tv.m_type == KindOfStaticString ||
               (tv.m_type == KindOfString && tv.m_data.pstr->isStatic());

    case T::OptStr:
        if (initNull) return true;
    // fallthrough
    case T::Str:
        return IS_STRING_TYPE(tv.m_type);

    case T::OptSArr:
        if (initNull) return true;
    // fallthrough
    case T::SArr:
        if (tv.m_type != KindOfArray || !tv.m_data.parr->isStatic()) {
            return false;
        }
        if (auto const arr = ty.array()) {
            if (!tvMatchesArrayType(tv, arr)) return false;
        }
        return true;

    case T::OptArr:
        if (initNull) return true;
    // fallthrough
    case T::Arr:
        if (tv.m_type != KindOfArray) return false;
        if (auto const arr = ty.array()) {
            if (!tvMatchesArrayType(tv, arr)) return false;
        }
        return true;

    case T::Null:
        return initNull || tv.m_type == KindOfUninit;

    case T::OptSubObj:
        if (initNull) return true;
    // fallthrough
    case T::SubObj:
    {
        auto const cls = Unit::lookupClass(ty.clsName());
        if (!cls) return false;
        return tv.m_type == KindOfObject &&
               tv.m_data.pobj->getVMClass()->classof(cls);
    }

    case T::OptExactObj:
        if (initNull) return true;
    // fallthrough
    case T::ExactObj:
    {
        auto const cls = Unit::lookupClass(ty.clsName());
        if (!cls) return false;
        return tv.m_type == KindOfObject && tv.m_data.pobj->getVMClass() == cls;
    }

    case T::InitUnc:
        if (tv.m_type == KindOfUninit) return false;
    // fallthrough
    case T::Unc:
        return !IS_REFCOUNTED_TYPE(tv.m_type) ||
               (tv.m_type == KindOfString && tv.m_data.pstr->isStatic()) ||
               (tv.m_type == KindOfArray && tv.m_data.parr->isStatic());

    case T::InitCell:
        if (tv.m_type == KindOfUninit) return false;
    // fallthrough
    case T::Cell:
        return tv.m_type != KindOfRef;

    case T::Ref:
        return tv.m_type == KindOfRef;

    case T::InitGen:
        if (tv.m_type == KindOfUninit) return false;
    // fallthrough
    case T::Gen:
        return true;
    }
    not_reached();
}
Exemplo n.º 2
0
bool tvMatchesRepoAuthType(TypedValue tv, RepoAuthType ty) {
  assert(tvIsPlausible(tv));

  bool const initNull = tv.m_type == KindOfNull;

  using T = RepoAuthType::Tag;
  switch (ty.tag()) {
  case T::Uninit:       return tv.m_type == KindOfUninit;
  case T::InitNull:     return initNull;

  case T::OptBool:      if (initNull) return true;
                        // fallthrough
  case T::Bool:         return tv.m_type == KindOfBoolean;
  case T::OptInt:       if (initNull) return true;
                        // fallthrough
  case T::Int:          return tv.m_type == KindOfInt64;
  case T::OptDbl:       if (initNull) return true;
                        // fallthrough
  case T::Dbl:          return tv.m_type == KindOfDouble;
  case T::OptRes:       if (initNull) return true;
                        // fallthrough
  case T::Res:          return tv.m_type == KindOfResource;
  case T::OptObj:       if (initNull) return true;
                        // fallthrough
  case T::Obj:          return tv.m_type == KindOfObject;

  case T::OptSStr:
    if (initNull) return true;
    // fallthrough
  case T::SStr:
    return isStringType(tv.m_type) && tv.m_data.pstr->isStatic();

  case T::OptStr:
    if (initNull) return true;
    // fallthrough
  case T::Str:
    return isStringType(tv.m_type);

  case T::OptSArr:
    if (initNull) return true;
    // fallthrough
  case T::SArr:
    if (!isArrayType(tv.m_type) || !tv.m_data.parr->isStatic()) {
      return false;
    }
    if (auto const arr = ty.array()) {
      if (!tvMatchesArrayType(tv, arr)) return false;
    }
    return true;

  case T::OptArr:
    if (initNull) return true;
    // fallthrough
  case T::Arr:
    if (!isArrayType(tv.m_type)) return false;
    if (auto const arr = ty.array()) {
      if (!tvMatchesArrayType(tv, arr)) return false;
    }
    return true;

  case T::OptSVArr:
    if (initNull) return true;
    // fallthrough
  case T::SVArr:
    if (!isArrayType(tv.m_type) ||
        !tv.m_data.parr->isStatic() ||
        !tv.m_data.parr->isVArray()) {
      return false;
    }
    if (auto const arr = ty.array()) {
      if (!tvMatchesArrayType(tv, arr)) return false;
    }
    return true;

  case T::OptVArr:
    if (initNull) return true;
    // fallthrough
  case T::VArr:
    if (!isArrayType(tv.m_type) || !tv.m_data.parr->isVArray()) return false;
    if (auto const arr = ty.array()) {
      if (!tvMatchesArrayType(tv, arr)) return false;
    }
    return true;

  case T::OptSDArr:
    if (initNull) return true;
    // fallthrough
  case T::SDArr:
    if (!isArrayType(tv.m_type) ||
        !tv.m_data.parr->isStatic() ||
        !tv.m_data.parr->isDArray()) {
      return false;
    }
    if (auto const arr = ty.array()) {
      if (!tvMatchesArrayType(tv, arr)) return false;
    }
    return true;

  case T::OptDArr:
    if (initNull) return true;
    // fallthrough
  case T::DArr:
    if (!isArrayType(tv.m_type) || !tv.m_data.parr->isDArray()) return false;
    if (auto const arr = ty.array()) {
      if (!tvMatchesArrayType(tv, arr)) return false;
    }
    return true;

  case T::OptSVec:
    if (initNull) return true;
    // fallthrough
  case T::SVec:
    return isVecType(tv.m_type) && tv.m_data.parr->isStatic();

  case T::OptVec:
    if (initNull) return true;
    // fallthrough
  case T::Vec:
    return isVecType(tv.m_type);

  case T::OptSDict:
    if (initNull) return true;
    // fallthrough
  case T::SDict:
    return isDictType(tv.m_type) && tv.m_data.parr->isStatic();

  case T::OptDict:
    if (initNull) return true;
    // fallthrough
  case T::Dict:
    return isDictType(tv.m_type);

  case T::OptSKeyset:
    if (initNull) return true;
    // fallthrough
  case T::SKeyset:
    return isKeysetType(tv.m_type) && tv.m_data.parr->isStatic();

  case T::OptKeyset:
    if (initNull) return true;
    // fallthrough
  case T::Keyset:
    return isKeysetType(tv.m_type);

  case T::Null:
    return initNull || tv.m_type == KindOfUninit;

  case T::OptSubObj:
    if (initNull) return true;
    // fallthrough
  case T::SubObj:
    {
      auto const cls = Unit::lookupClass(ty.clsName());
      if (!cls) return false;
      return tv.m_type == KindOfObject &&
             tv.m_data.pobj->getVMClass()->classof(cls);
    }

  case T::OptExactObj:
    if (initNull) return true;
    // fallthrough
  case T::ExactObj:
    {
      auto const cls = Unit::lookupClass(ty.clsName());
      if (!cls) return false;
      return tv.m_type == KindOfObject && tv.m_data.pobj->getVMClass() == cls;
    }

  case T::InitUnc:
    if (tv.m_type == KindOfUninit) return false;
    // fallthrough
  case T::Unc:
    return !isRefcountedType(tv.m_type) ||
           (tv.m_type == KindOfString && tv.m_data.pstr->isStatic()) ||
           (isArrayLikeType(tv.m_type) && tv.m_data.parr->isStatic());

  case T::OptArrKey:
    if (initNull) return true;
    // fallthrough
  case T::ArrKey:
    return isStringType(tv.m_type) || tv.m_type == KindOfInt64;

  case T::OptUncArrKey:
    if (initNull) return true;
    // fallthrough
  case T::UncArrKey:
    return (isStringType(tv.m_type) && !tv.m_data.pstr->isRefCounted()) ||
      tv.m_type == KindOfInt64;

  case T::InitCell:
    if (tv.m_type == KindOfUninit) return false;
    // fallthrough
  case T::Cell:
    return tv.m_type != KindOfRef;

  case T::Ref:
    return tv.m_type == KindOfRef;

  case T::InitGen:
    if (tv.m_type == KindOfUninit) return false;
    // fallthrough
  case T::Gen:
    return true;
  }
  not_reached();
}