Variant f_class_parents(const Variant& obj, bool autoload /* = true */) { Class* cls; if (obj.isString()) { cls = Unit::getClass(obj.getStringData(), autoload); if (!cls) { return false; } } else if (obj.isObject()) { cls = obj.getObjectData()->getVMClass(); } else { return false; } Array ret(Array::Create()); for (cls = cls->parent(); cls; cls = cls->parent()) { ret.set(cls->nameStr(), VarNR(cls->name())); } return ret; }
Variant HHVM_FUNCTION(get_class, const Variant& object /* = null_variant */) { if (object.isNull()) { // No arg passed. String ret; CallerFrame cf; auto cls = arGetContextClassImpl<true>(cf()); if (cls) { ret = String(cls->nameStr()); } if (ret.empty()) { raise_warning("get_class() called without object from outside a class"); return false; } return ret; } if (!object.isObject()) return false; return VarNR(object.toObject()->getClassName()); }
Variant f_class_implements(const Variant& obj, bool autoload /* = true */) { Class* cls; if (obj.isString()) { cls = Unit::getClass(obj.getStringData(), autoload); if (!cls) { return false; } } else if (obj.isObject()) { cls = obj.getObjectData()->getVMClass(); } else { return false; } Array ret(Array::Create()); const Class::InterfaceMap& ifaces = cls->allInterfaces(); for (int i = 0, size = ifaces.size(); i < size; i++) { ret.set(ifaces[i]->nameStr(), VarNR(ifaces[i]->name())); } return ret; }
void EventHook::RunUserProfiler(const ActRec* ar, int mode) { // Don't do anything if we are running the profiling function itself // or if we haven't set up a profiler. if (g_vmContext->m_executingSetprofileCallback || g_vmContext->m_setprofileCallback.isNull()) { return; } // Don't profile 86ctor, since its an implementation detail, // and we dont guarantee to call it if (ar->m_func->cls() && ar->m_func == ar->m_func->cls()->getCtor() && Func::isSpecial(ar->m_func->name())) { return; } Transl::VMRegAnchor _; ExecutingSetprofileCallbackGuard guard; Array params; Array frameinfo; if (mode == ProfileEnter) { params.append(s_enter); frameinfo.set(s_args, hhvm_get_frame_args(ar)); } else { params.append(s_exit); if (!g_vmContext->m_faults.empty()) { Fault fault = g_vmContext->m_faults.back(); if (fault.m_faultType == Fault::Type::UserException) { frameinfo.set(s_exception, fault.m_userException); } } else if (!ar->m_func->info() && !ar->m_func->isGenerator()) { // TODO (#1131400) This is wrong for builtins frameinfo.set(s_return, tvAsCVarRef(g_vmContext->m_stack.topTV())); } } params.append(VarNR(ar->m_func->fullName())); params.append(frameinfo); vm_call_user_func(g_vmContext->m_setprofileCallback, params); }
Variant f_class_uses(const Variant& obj, bool autoload /* = true */) { Class* cls; if (obj.isString()) { cls = Unit::getClass(obj.getStringData(), autoload); if (!cls) { String err = "class_uses(): Class %s does not exist"; if (autoload) { err += " and could not be loaded"; } raise_warning(err.c_str(), obj.toString().c_str()); return false; } } else if (obj.isObject()) { cls = obj.getObjectData()->getVMClass(); } else { raise_warning("class_uses(): object or string expected"); return false; } Array ret(Array::Create()); for (auto const& traitName : cls->preClass()->usedTraits()) { ret.set(StrNR(traitName), VarNR(traitName)); } return ret; }
bool EventHook::RunInterceptHandler(ActRec* ar) { const Func* func = ar->func(); if (LIKELY(func->maybeIntercepted() == 0)) return true; // Intercept only original generator / async function calls, not resumption. if (ar->resumed()) return true; Variant* h = get_intercept_handler(func->fullNameStr(), &func->maybeIntercepted()); if (!h) return true; /* * In production mode, only functions that we have assumed can be * intercepted during static analysis should actually be * intercepted. */ if (RuntimeOption::RepoAuthoritative && !RuntimeOption::EvalJitEnableRenameFunction) { if (!(func->attrs() & AttrInterceptable)) { raise_error("fb_intercept was used on a non-interceptable function (%s) " "in RepoAuthoritative mode", func->fullName()->data()); } } VMRegAnchor _; PC savePc = vmpc(); Variant doneFlag = true; Variant called_on; if (ar->hasThis()) { called_on = Variant(ar->getThis()); } else if (ar->hasClass()) { // For static methods, give handler the name of called class called_on = Variant(const_cast<StringData*>(ar->getClass()->name())); } Variant intArgs = PackedArrayInit(5) .append(VarNR(ar->func()->fullName())) .append(called_on) .append(get_frame_args_with_ref(ar)) .append(h->asCArrRef()[1]) .appendRef(doneFlag) .toArray(); Variant ret = vm_call_user_func(h->asCArrRef()[0], intArgs); if (doneFlag.toBoolean()) { Offset pcOff; ActRec* outer = g_context->getPrevVMState(ar, &pcOff); frame_free_locals_inl_no_hook<true>(ar, ar->func()->numLocals()); Stack& stack = vmStack(); stack.top() = (Cell*)(ar + 1); cellDup(*ret.asCell(), *stack.allocTV()); vmfp() = outer; vmpc() = outer ? outer->func()->unit()->at(pcOff) : nullptr; return false; } vmfp() = ar; vmpc() = savePc; return true; }
static Variant get_breakpoint_message(const BreakInfo& bi) { if (auto eb = boost::get<ExnBreak>(&bi)) return VarNR(eb->message); return init_null(); }
void ThriftBuffer::write(CObjRef data) { VariableSerializer vs(m_serializerType); String sdata = vs.serialize(VarNR(data), true); write(sdata); }
bool UnitEmitter::insert(UnitOrigin unitOrigin, RepoTxn& txn) { Repo& repo = Repo::get(); UnitRepoProxy& urp = repo.urp(); int repoId = Repo::get().repoIdForNewUnit(unitOrigin); if (repoId == RepoIdInvalid) { return true; } m_repoId = repoId; try { { m_lineTable = createLineTable(m_sourceLocTab, m_bclen); urp.insertUnit[repoId].insert(*this, txn, m_sn, m_md5, m_bc, m_bclen); } int64_t usn = m_sn; urp.insertUnitLineTable(repoId, txn, usn, m_lineTable); for (unsigned i = 0; i < m_litstrs.size(); ++i) { urp.insertUnitLitstr[repoId].insert(txn, usn, i, m_litstrs[i]); } for (unsigned i = 0; i < m_arrays.size(); ++i) { VariableSerializer vs(VariableSerializer::Type::Serialize); urp.insertUnitArray[repoId].insert( txn, usn, i, vs.serializeValue(VarNR(m_arrays[i]), false /* limit */).toCppString() ); } for (auto& fe : m_fes) { fe->commit(txn); } for (auto& pce : m_pceVec) { pce->commit(txn); } for (int i = 0, n = m_mergeableStmts.size(); i < n; i++) { switch (m_mergeableStmts[i].first) { case MergeKind::Done: case MergeKind::UniqueDefinedClass: not_reached(); case MergeKind::Class: break; case MergeKind::TypeAlias: case MergeKind::ReqDoc: { urp.insertUnitMergeable[repoId].insert( txn, usn, i, m_mergeableStmts[i].first, m_mergeableStmts[i].second, nullptr); break; } case MergeKind::Define: case MergeKind::PersistentDefine: case MergeKind::Global: { int ix = m_mergeableStmts[i].second; urp.insertUnitMergeable[repoId].insert( txn, usn, i, m_mergeableStmts[i].first, m_mergeableValues[ix].first, &m_mergeableValues[ix].second); break; } } } if (RuntimeOption::RepoDebugInfo) { for (size_t i = 0; i < m_sourceLocTab.size(); ++i) { SourceLoc& e = m_sourceLocTab[i].second; Offset endOff = i < m_sourceLocTab.size() - 1 ? m_sourceLocTab[i + 1].first : m_bclen; urp.insertUnitSourceLoc[repoId] .insert(txn, usn, endOff, e.line0, e.char0, e.line1, e.char1); } } return false; } catch (RepoExc& re) { TRACE(3, "Failed to commit '%s' (0x%016" PRIx64 "%016" PRIx64 ") to '%s': %s\n", m_filepath->data(), m_md5.q[0], m_md5.q[1], repo.repoName(repoId).c_str(), re.msg().c_str()); return true; } }
ArrayData* ArrayData::nvSet(int64 ki, int64 vi, bool copy) { return set(ki, VarNR(vi), copy); }