Пример #1
0
RefData* closureStaticLocInit(StringData* name, ActRec* fp, TypedValue val) {
  auto const func = fp->m_func;
  assert(func->isClosureBody() || func->isGeneratorFromClosure());
  auto const closureLoc =
    LIKELY(func->isClosureBody())
      ? frame_local(fp, func->numParams())
      : frame_local(fp, frame_continuation(fp)->m_origFunc->numParams());

  bool inited;
  auto const refData = lookupStaticFromClosure(
    closureLoc->m_data.pobj, name, inited);
  if (!inited) {
    cellCopy(val, *refData->tv());
  }
  refData->incRefCount();
  return refData;
}
Пример #2
0
Func* Func::clone() const {
  Func* f = new (allocFuncMem(
        m_name,
        m_numParams,
        isClosureBody() || isGeneratorFromClosure()
  )) Func(*this);
  f->initPrologues(m_numParams, isGenerator());
  f->m_funcId = InvalidFuncId;
  return f;
}
String c_AsyncFunctionWaitHandle::getName() {
  switch (getState()) {
    case STATE_BLOCKED:
    case STATE_READY:
    case STATE_RUNNING: {
      auto func = actRec()->func();
      if (!func->cls() ||
          func->cls()->attrs() & AttrNoOverride ||
          actRec()->localsDecRefd()) {
        auto name = func->fullName();
        if (func->isClosureBody()) {
          const char* p = strchr(name->data(), ':');
          if (p) {
            return
              concat(String(name->data(), p + 1 - name->data(), CopyString),
                     s__closure_);
          } else {
            return s__closure_;
          }
        }
        return String{const_cast<StringData*>(name)};
      }

      auto const cls = actRec()->hasThis() ?
        actRec()->getThis()->getVMClass() :
        actRec()->getClass();

      if (cls == func->cls() && !func->isClosureBody()) {
        return String{const_cast<StringData*>(func->fullName())};
      }

      StrNR funcName(func->isClosureBody() ? s__closure_.get() : func->name());

      return concat3(cls->nameStr(), "::", funcName);
    }

    default:
      raise_fatal_error(
          "Invariant violation: encountered unexpected state");
  }
}
Пример #4
0
std::string func_flag_list(const FuncInfo& finfo) {
  auto const func = finfo.func;
  std::vector<std::string> flags;

  if (func->isGenerator()) flags.push_back("isGenerator");
  if (func->isAsync()) flags.push_back("isAsync");
  if (func->isClosureBody()) flags.push_back("isClosureBody");
  if (func->isPairGenerator()) flags.push_back("isPairGenerator");

  std::string strflags = folly::join(" ", flags);
  if (!strflags.empty()) return " " + strflags + " ";
  return " ";
}
String c_AsyncFunctionWaitHandle::getName() {
  switch (getState()) {
    case STATE_BLOCKED:
    case STATE_READY:
    case STATE_RUNNING: {
      auto func = actRec()->func();
      if (!actRec()->getThisOrClass() ||
          func->cls()->attrs() & AttrNoOverride) {
        auto name = func->fullName();
        if (func->isClosureBody()) {
          const char* p = strchr(name->data(), ':');
          if (p) {
            return
              concat(String(name->data(), p + 1 - name->data(), CopyString),
                     s__closure_);
          } else {
            return s__closure_;
          }
        }
        return String{const_cast<StringData*>(name)};
      }
      String funcName;
      if (actRec()->func()->isClosureBody()) {
        // Can we do better than this?
        funcName = s__closure_;
      } else {
        funcName = const_cast<StringData*>(actRec()->func()->name());
      }

      String clsName;
      if (actRec()->hasThis()) {
        clsName = const_cast<StringData*>(actRec()->getThis()->
                                          getVMClass()->name());
      } else if (actRec()->hasClass()) {
        clsName = const_cast<StringData*>(actRec()->getClass()->name());
      } else {
        return funcName;
      }

      return concat3(clsName, "::", funcName);
    }

    default:
      raise_fatal_error(
          "Invariant violation: encountered unexpected state");
  }
}
Пример #6
0
std::string func_flag_list(const FuncInfo& finfo) {
  auto const func = finfo.func;
  std::vector<std::string> flags;

  if (auto name = func->getGeneratorBodyName()) {
    flags.push_back(
        folly::format("hasGeneratorBody(\"{}\")", name->toCppString()).str()
    );
  }
  if (func->isGenerator()) flags.push_back("isGenerator");
  if (func->isAsync()) flags.push_back("isAsync");
  if (func->isGeneratorFromClosure()) flags.push_back("isGeneratorFromClosure");
  if (func->isClosureBody()) flags.push_back("isClosureBody");
  if (func->isPairGenerator()) flags.push_back("isPairGenerator");

  std::string strflags = folly::join(" ", flags);
  if (!strflags.empty()) return " " + strflags + " ";
  return " ";
}
Пример #7
0
bool Func::isClonedClosure() const {
  if (!isClosureBody()) return false;
  if (!cls()) return true;
  return cls()->lookupMethod(name()) != this;
}