示例#1
0
文件: parse.cpp 项目: fmarcos83/hhvm
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;
}
示例#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->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;
}