static const Func* lookupDirectFunc(SrcKey const sk, const StringData* fname, const StringData* clsName, bool staticCall) { if (clsName && !clsName->isame(s_empty.get())) { auto const cls = Unit::lookupUniqueClass(clsName); bool magic = false; auto const ctx = sk.func()->cls(); return lookupImmutableMethod(cls, fname, magic, staticCall, ctx); } auto const func = Unit::lookupFunc(fname); if (func && func->isNameBindingImmutable(sk.unit())) { return func; } return nullptr; }
static void recordActRecPush(const SrcKey& sk, const Unit* unit, const FPIEnt* fpi, const StringData* name, const StringData* clsName, bool staticCall) { // sk is the address of a FPush* of the function whose static name // is name. The boundaries of FPI regions are such that we can't quite // find the FCall that matches this FuncD without decoding forward to // the end; this is not ideal, but is hopefully affordable at translation // time. ASSERT(name->isStatic()); ASSERT(sk.offset() == fpi->m_fpushOff); SrcKey fcall; SrcKey next(sk); next.advance(unit); do { if (*unit->at(next.offset()) == OpFCall) { // Remember the last FCall in the region; the region might end // with UnboxR, e.g. fcall = next; } next.advance(unit); } while (next.offset() <= fpi->m_fcallOff); ASSERT(*unit->at(fcall.offset()) == OpFCall); if (clsName) { const Class* cls = Unit::lookupClass(clsName); bool magic = false; const Func* func = lookupImmutableMethod(cls, name, magic, staticCall); if (func) { recordFunc(fcall, func); } return; } const Func* func = Unit::lookupFunc(name); if (func && func->isNameBindingImmutable(unit)) { // this will never go into a call cache, so we dont need to // encode the args. it will be used in OpFCall below to // set the i->funcd. recordFunc(fcall, func); } else { // It's not enough to remember the function name; we also need to encode // the number of arguments and current flag disposition. int numArgs = getImm(unit->at(sk.offset()), 0).u_IVA; recordNameAndArgs(fcall, name, numArgs); } }
static void recordActRecPush(NormalizedInstruction& i, const Unit* unit, const StringData* name, const StringData* clsName, bool staticCall) { const SrcKey& sk = i.source; FTRACE(2, "annotation: recordActRecPush: {}@{} {}{}{} ({}static)\n", unit->filepath()->data(), sk.offset(), clsName ? clsName->data() : "", clsName ? "::" : "", name, !staticCall ? "non" : ""); SrcKey next(sk); next.advance(unit); const FPIEnt *fpi = curFunc()->findFPI(next.offset()); assert(fpi); assert(name->isStatic()); assert(sk.offset() == fpi->m_fpushOff); SrcKey fcall = sk; fcall.m_offset = fpi->m_fcallOff; assert(isFCallStar(*unit->at(fcall.offset()))); if (clsName) { const Class* cls = Unit::lookupUniqueClass(clsName); bool magic = false; const Func* func = lookupImmutableMethod(cls, name, magic, staticCall); if (func) { recordFunc(i, fcall, func); } return; } const Func* func = Unit::lookupFunc(name); if (func && func->isNameBindingImmutable(unit)) { // this will never go into a call cache, so we dont need to // encode the args. it will be used in OpFCall below to // set the i->funcd. recordFunc(i, fcall, func); } else { // It's not enough to remember the function name; we also need to encode // the number of arguments and current flag disposition. int numArgs = getImm(unit->at(sk.offset()), 0).u_IVA; recordNameAndArgs(fcall, name, numArgs); } }