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