Пример #1
0
Файл: func.cpp Проект: BwRy/hhvm
void FuncRepoProxy::GetFuncsStmt
                  ::get(UnitEmitter& ue) {
  RepoTxn txn(m_repo);
  if (!prepared()) {
    std::stringstream ssSelect;
    ssSelect << "SELECT funcSn,preClassId,name,top,extraData "
                "FROM "
             << m_repo.table(m_repoId, "Func")
             << " WHERE unitSn == @unitSn ORDER BY funcSn ASC;";
    txn.prepare(*this, ssSelect.str());
  }
  RepoTxnQuery query(txn, *this);
  query.bindInt64("@unitSn", ue.sn());
  do {
    query.step();
    if (query.row()) {
      int funcSn;               /**/ query.getInt(0, funcSn);
      Id preClassId;            /**/ query.getId(1, preClassId);
      StringData* name;         /**/ query.getStaticString(2, name);
      bool top;                 /**/ query.getBool(3, top);
      BlobDecoder extraBlob =   /**/ query.getBlob(4);

      FuncEmitter* fe;
      if (preClassId < 0) {
        fe = ue.newFuncEmitter(name);
      } else {
        PreClassEmitter* pce = ue.pce(preClassId);
        fe = ue.newMethodEmitter(name, pce);
        bool added UNUSED = pce->addMethod(fe);
        assert(added);
      }
      assert(fe->sn() == funcSn);
      fe->setTop(top);
      fe->serdeMetaData(extraBlob);
      if (!SystemLib::s_inited && !fe->isPseudoMain()) {
        assert(fe->attrs() & AttrBuiltin);
        if (preClassId < 0) {
          assert(fe->attrs() & AttrPersistent);
          assert(fe->attrs() & AttrUnique);
          assert(fe->attrs() & AttrSkipFrame);
        }
      }
      fe->setEhTabIsSorted();
      fe->finish(fe->past(), true);
      ue.recordFunction(fe);
    }
  } while (!query.done());
  txn.commit();
}
Пример #2
0
std::unique_ptr<php::Func> parse_func(ParseUnitState& puState,
                                      borrowed_ptr<php::Unit> unit,
                                      borrowed_ptr<php::Class> cls,
                                      const FuncEmitter& fe) {
  FTRACE(2, "  func: {}\n",
    fe.name()->data() && *fe.name()->data() ? fe.name()->data()
                                            : "pseudomain");

  auto ret             = folly::make_unique<php::Func>();
  ret->name            = fe.name();
  ret->srcInfo         = php::SrcInfo { fe.getLocation(),
                                        fe.getDocComment() };
  ret->unit            = unit;
  ret->cls             = cls;
  ret->nextBlockId     = 0;

  ret->attrs                  = fe.attrs();
  ret->userAttributes         = fe.getUserAttributes();
  ret->returnUserType         = fe.returnUserType();
  ret->originalFilename       = fe.originalFilename();

  ret->top                    = fe.top();
  ret->isClosureBody          = fe.isClosureBody();
  ret->isGeneratorBody        = fe.isGenerator();
  ret->isGeneratorFromClosure = fe.isGeneratorFromClosure();
  ret->isPairGenerator        = fe.isPairGenerator();
  ret->isAsync                = fe.isAsync();
  ret->innerGeneratorFunc     = nullptr;
  ret->outerGeneratorFunc     = nullptr;

  /*
   * Generators that aren't inside classes (includes generators from
   * closures) end up with inner generator bodies living as free
   * functions, not on a class.  We track them here to link them after
   * we've finished parsing the whole unit.  parse_methods handles the
   * within-class generator linking cases.
   */
  if (auto const innerName = fe.getGeneratorBodyName()) {
    if (!ret->cls || ret->isClosureBody) {
      puState.generatorsToLink.emplace_back(borrow(ret), innerName);
    }
  }
  if (ret->isGeneratorBody && !cls) {
    always_assert(!puState.innerGenerators.count(ret->name));
    puState.innerGenerators[ret->name] = borrow(ret);
  }

  /*
   * HNI-style native functions get some extra information.
   */
  if (fe.isHNINative()) {
    ret->nativeInfo             = folly::make_unique<php::NativeInfo>();
    ret->nativeInfo->returnType = fe.getReturnType();
  }

  add_frame_variables(*ret, fe);
  build_cfg(puState, *ret, fe);

  return ret;
}
Пример #3
0
std::unique_ptr<php::Func> parse_func(ParseUnitState& puState,
                                      borrowed_ptr<php::Unit> unit,
                                      borrowed_ptr<php::Class> cls,
                                      const FuncEmitter& fe) {
  FTRACE(2, "  func: {}\n",
    fe.name()->data() && *fe.name()->data() ? fe.name()->data()
                                            : "pseudomain");

  auto ret             = folly::make_unique<php::Func>();
  ret->name            = fe.name();
  ret->srcInfo         = php::SrcInfo { fe.getLocation(),
                                        fe.getDocComment() };
  ret->unit            = unit;
  ret->cls             = cls;
  // Note: probably need to clear AttrLeaf here eventually.
  ret->attrs                  = fe.attrs();
  ret->userAttributes         = fe.getUserAttributes();
  ret->userRetTypeConstraint  = fe.returnTypeConstraint();
  ret->originalFilename       = fe.originalFilename();

  ret->top                    = fe.top();
  ret->isClosureBody          = fe.isClosureBody();
  ret->isGeneratorBody        = fe.isGenerator();
  ret->isGeneratorFromClosure = fe.isGeneratorFromClosure();
  ret->isPairGenerator        = fe.isPairGenerator();
  ret->hasGeneratorAsBody     = fe.hasGeneratorAsBody();

  ret->nextBlockId     = 0;

  add_frame_variables(*ret, fe);
  build_cfg(puState, *ret, fe);

  return ret;
}
Пример #4
0
std::unique_ptr<php::Func> parse_func(ParseUnitState& puState,
                                      borrowed_ptr<php::Unit> unit,
                                      borrowed_ptr<php::Class> cls,
                                      const FuncEmitter& fe) {
    FTRACE(2, "  func: {}\n",
           fe.name()->data() && *fe.name()->data() ? fe.name()->data()
           : "pseudomain");

    auto ret             = folly::make_unique<php::Func>();
    ret->name            = fe.name();
    ret->srcInfo         = php::SrcInfo { fe.getLocation(),
                                          fe.getDocComment() };
    ret->unit            = unit;
    ret->cls             = cls;
    ret->nextBlockId     = 0;

    ret->attrs                  = fe.attrs();
    ret->userAttributes         = fe.getUserAttributes();
    ret->returnUserType         = fe.returnUserType();
    ret->originalFilename       = fe.originalFilename();

    ret->top                    = fe.top();
    ret->isClosureBody          = fe.isClosureBody();
    ret->isGeneratorBody        = fe.isGenerator();
    ret->isGeneratorFromClosure = fe.isGeneratorFromClosure();
    ret->isPairGenerator        = fe.isPairGenerator();
    ret->isAsync                = fe.isAsync();
    ret->generatorBodyName      = fe.getGeneratorBodyName();

    /*
     * HNI-style native functions get some extra information.
     */
    if (fe.isHNINative()) {
        ret->nativeInfo             = folly::make_unique<php::NativeInfo>();
        ret->nativeInfo->returnType = fe.getReturnType();
    }

    add_frame_variables(*ret, fe);
    build_cfg(puState, *ret, fe);

    return ret;
}