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; }
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"); } }
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"); } }
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 " "; }
bool Func::isClonedClosure() const { if (!isClosureBody()) return false; if (!cls()) return true; return cls()->lookupMethod(name()) != this; }