コード例 #1
0
ファイル: annotation.cpp プロジェクト: 6api/hhvm
void annotate(NormalizedInstruction* i) {
  switch (i->op()) {
  case Op::FCallD:
    {
      auto const fpi      = i->func()->findFPI(i->source.offset());
      auto const pushOp   = i->m_unit->getOpcode(fpi->m_fpushOff);
      auto const clsName  = i->m_unit->lookupLitstrId(i->imm[1].u_SA);
      auto const funcName = i->m_unit->lookupLitstrId(i->imm[2].u_SA);
      auto const isStatic = pushOp == Op::FPushClsMethodD ||
                            pushOp == Op::FPushClsMethodF ||
                            pushOp == Op::FPushClsMethod;

      /*
       * Currently we don't attempt any of this for FPushClsMethod
       * because lookupImmutableMethod is only for situations that
       * don't involve LSB.
       */
      auto const func =
        pushOp == Op::FPushClsMethod
          ? nullptr
          : lookupDirectFunc(i->source, funcName, clsName, isStatic);

      if (func) {
        FTRACE(1, "found direct func ({}) for FCallD\n",
          func->fullName()->data());
        i->funcd = func;
      }
    }
    break;
  default:
    break;
  }
}
コード例 #2
0
ファイル: annotation.cpp プロジェクト: Ronnrein/hhvm
static void recordActRecPush(const SrcKey sk,
                             const StringData* name,
                             const StringData* clsName,
                             bool staticCall) {
  auto unit = sk.unit();
  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 = sk.func()->findFPI(next.offset());
  assert(fpi);
  assert(name->isStatic());
  assert(sk.offset() == fpi->m_fpushOff);
  auto const fcall = SrcKey { sk.func(), fpi->m_fcallOff, sk.resumed() };
  assert(isFCallStar(*reinterpret_cast<const Op*>(unit->at(fcall.offset()))));
  auto const func = lookupDirectFunc(sk, name, clsName, staticCall);
  if (func) {
    recordFunc(fcall, func);
  }
}
コード例 #3
0
ファイル: annotation.cpp プロジェクト: Ronnrein/hhvm
void annotate(NormalizedInstruction* i) {
  switch(i->op()) {
    case OpFPushObjMethodD:
    case OpFPushClsMethodD:
    case OpFPushClsMethodF:
    case OpFPushCtorD:
    case OpFPushCtor:
    case OpFPushFuncD: {
      if (RuntimeOption::RepoAuthoritative && Repo::global().UsedHHBBC) {
        break;
      }

      // When we push predictable activation records, we can use a simpler
      // translation for their corresponding FCall.
      const StringData* className = nullptr;
      const StringData* funcName = nullptr;
      if (i->op() == OpFPushFuncD) {
        funcName = i->m_unit->lookupLitstrId(i->imm[1].u_SA);
      } else if (i->op() == OpFPushObjMethodD) {
        if (i->inputs[0]->valueType() != KindOfObject) break;
        const Class* cls = i->inputs[0]->rtt.valueClass();
        if (!cls) break;
        funcName = i->m_unit->lookupLitstrId(i->imm[1].u_SA);
        className = cls->name();
      } else if (i->op() == OpFPushClsMethodF) {
        if (!i->inputs[1]->isString() ||
            i->inputs[1]->rtt.valueString() == nullptr ||
            i->inputs[0]->valueType() != KindOfClass) {
          break;
        }
        const Class* cls = i->inputs[0]->rtt.valueClass();
        if (!cls) break;
        funcName = i->inputs[1]->rtt.valueString();
        className = cls->name();
      } else if (i->op() == OpFPushClsMethodD) {
        funcName = i->m_unit->lookupLitstrId(i->imm[1].u_SA);
        className = i->m_unit->lookupLitstrId(i->imm[2].u_SA);
      } else if (i->op() == OpFPushCtorD) {
        className = i->m_unit->lookupLitstrId(i->imm[1].u_SA);
        const Class* cls = Unit::lookupUniqueClass(className);
        if (!cls) break;
        auto const ctor = cls->getCtor();
        funcName = ctor->name();
        className = ctor->cls()->name();
      } else {
        assert(i->op() == OpFPushCtor);
        const Class* cls = i->inputs[0]->rtt.valueClass();
        if (!cls) break;
        auto const ctor = cls->getCtor();
        funcName = ctor->name();
        className = ctor->cls()->name();
      }
      assert(funcName->isStatic());
      recordActRecPush(i->source, funcName, className,
                       i->op() == OpFPushClsMethodD ||
                       i->op() == OpFPushClsMethodF);
    } break;
    case OpFCall:
    case OpFCallArray: {
      if (RuntimeOption::RepoAuthoritative && Repo::global().UsedHHBBC) {
        break;
      }
      if (auto const func = folly::get_ptr(s_callDB, i->source)) {
        i->funcd = *func;
      }
    } break;
    default: break;

    case Op::FCallD: {
      auto const fpi      = i->func()->findFPI(i->source.offset());
      auto const pushOp   = i->m_unit->getOpcode(fpi->m_fpushOff);
      auto const clsName  = i->m_unit->lookupLitstrId(i->imm[1].u_SA);
      auto const funcName = i->m_unit->lookupLitstrId(i->imm[2].u_SA);
      auto const isStatic = pushOp == Op::FPushClsMethodD ||
                            pushOp == Op::FPushClsMethodF ||
                            pushOp == Op::FPushClsMethod;

      /*
       * Currently we don't attempt any of this for FPushClsMethod
       * because lookupImmutableMethod is only for situations that
       * don't involve LSB.
       */
      auto const func =
        pushOp == Op::FPushClsMethod
          ? nullptr
          : lookupDirectFunc(i->source, funcName, clsName, isStatic);

      if (func) {
        FTRACE(1, "found direct func (%s) for FCallD\n",
          func->fullName()->data());
        i->funcd = func;
      }
      break;
    }
  }
}