예제 #1
0
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;
}
예제 #2
0
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);
  }
}
예제 #3
0
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);
  }
}