示例#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;
  // 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;
}
示例#3
0
文件: parse.cpp 项目: MatmaRex/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.docComment };
  ret->unit            = unit;
  ret->cls             = cls;
  ret->nextBlockId     = 0;

  ret->attrs              = static_cast<Attr>(fe.attrs & ~AttrNoOverride);
  ret->userAttributes     = fe.userAttributes;
  ret->returnUserType     = fe.retUserType;
  ret->retTypeConstraint  = fe.retTypeConstraint;
  ret->originalFilename   = fe.originalFilename;

  ret->top                = fe.top;
  ret->isClosureBody      = fe.isClosureBody;
  ret->isAsync            = fe.isAsync;
  ret->isGenerator        = fe.isGenerator;
  ret->isPairGenerator    = fe.isPairGenerator;
  ret->isNative           = fe.isNative;

  /*
   * Builtin functions get some extra information.  The returnType flag is only
   * non-folly::none for these, but note that something may be a builtin and
   * still have a folly::none return type.
   */
  if (fe.attrs & AttrBuiltin) {
    ret->nativeInfo             = folly::make_unique<php::NativeInfo>();
    ret->nativeInfo->returnType = fe.returnType;
  }

  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;
}
示例#5
0
文件: parse.cpp 项目: aloiret/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.docComment };
  ret->unit            = unit;
  ret->cls             = cls;

  ret->attrs              = static_cast<Attr>(fe.attrs & ~AttrNoOverride);
  ret->userAttributes     = fe.userAttributes;
  ret->returnUserType     = fe.retUserType;
  ret->retTypeConstraint  = fe.retTypeConstraint;
  ret->originalFilename   = fe.originalFilename;

  ret->top                = fe.top;
  ret->isClosureBody      = fe.isClosureBody;
  ret->isAsync            = fe.isAsync;
  ret->isGenerator        = fe.isGenerator;
  ret->isPairGenerator    = fe.isPairGenerator;
  ret->isMemoizeWrapper   = fe.isMemoizeWrapper;

  add_frame_variables(*ret, fe);

  /*
   * Builtin functions get some extra information.  The returnType flag is only
   * non-folly::none for these, but note that something may be a builtin and
   * still have a folly::none return type.
   */
  if (fe.isNative) {
    auto const f = [&] () -> HPHP::Func* {
      if (ret->cls) {
        auto const cls = Unit::lookupClass(ret->cls->name);
        return cls ? cls->lookupMethod(ret->name) : nullptr;
      } else {
        return Unit::lookupFunc(ret->name);
      }
    }();

    ret->nativeInfo                   = folly::make_unique<php::NativeInfo>();
    ret->nativeInfo->returnType       = fe.hniReturnType;
    ret->nativeInfo->dynCallWrapperId = fe.dynCallWrapperId;
    if (f && !ret->cls && ret->params.size()) {
      // There are a handful of functions whose first parameter is by
      // ref, but which don't require a reference.  There is also
      // array_multisort, which has this property for all its
      // parameters; but that
      if (ret->params[0].byRef && !f->mustBeRef(0)) {
        ret->params[0].mustBeRef = false;
      }
    }
    if (!f || !f->nativeFuncPtr() ||
        (f->userAttributes().count(
          LowStringPtr(s_attr_Deprecated.get())))) {
      ret->attrs |= AttrNoFCallBuiltin;
    }
  }

  build_cfg(puState, *ret, fe);

  return ret;
}