const StringData* findClassName(SSATmp* cls) { assert(cls->isA(Type::Cls)); if (cls->isConst()) { return cls->getValClass()->preClass()->name(); } // Try to get the class name from a LdCls IRInstruction* clsInst = cls->inst(); if (clsInst->op() == LdCls || clsInst->op() == LdClsCached) { SSATmp* clsName = clsInst->src(0); assert(clsName->isA(Type::Str)); if (clsName->isConst()) { return clsName->getValStr(); } } return nullptr; }
SSATmp* Simplifier::simplifyLdCls(IRInstruction* inst) { SSATmp* clsName = inst->getSrc(0); if (clsName->isConst()) { const Class* cls = Unit::lookupUniqueClass(clsName->getValStr()); if (cls) { if (RuntimeOption::RepoAuthoritative && (cls->attrs() & AttrUnique)) { // the class is unique return m_tb->genDefConst(cls); } const Class* ctx = inst->getSrc(1)->getValClass(); if (ctx && ctx->classof(cls)) { // the class of the current function being compiled is the // same as or derived from cls, so cls must be defined and // cannot change the next time we execute this same code return m_tb->genDefConst(cls); } } return m_tb->gen(LdClsCached, clsName); } return nullptr; }