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(); }
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(); }