/* * Helper method from converting between a PHP function and a CufIter. */ static bool vm_decode_function_cufiter(const Variant& function, SmartCufIterPtr& cufIter) { ObjectData* obj = nullptr; HPHP::Class* cls = nullptr; HPHP::JIT::CallerFrame cf; StringData* invName = nullptr; // Don't warn here, let the caller decide what to do if the func is nullptr. const HPHP::Func* func = vm_decode_function(function, cf(), false, obj, cls, invName, false); if (func == nullptr) { return false; } cufIter = smart::make_unique<CufIter>(); cufIter->setFunc(func); cufIter->setName(invName); if (obj) { cufIter->setCtx(obj); obj->incRefCount(); } else { cufIter->setCtx(cls); } return true; }
void AutoloadHandler::removeHandler(CVarRef handler) { SmartCufIterPtr cufIter = nullptr; if (!vm_decode_function_cufiter(handler, cufIter)) { return; } // Use find_if instead of remove_if since we know there can only be one match // in the vector. auto const& compareBundles = CompareBundles(cufIter.get()); m_handlers.erase( std::find_if(m_handlers.begin(), m_handlers.end(), compareBundles)); }
bool AutoloadHandler::addHandler(const Variant& handler, bool prepend) { SmartCufIterPtr cufIter = nullptr; if (!vm_decode_function_cufiter(handler, cufIter)) { return false; } m_spl_stack_inited = true; // Zend doesn't modify the order of the list if the handler is already // registered. auto const& compareBundles = CompareBundles(cufIter.get()); if (std::find_if(m_handlers.begin(), m_handlers.end(), compareBundles) != m_handlers.end()) { return true; } if (!prepend) { m_handlers.emplace_back(handler, cufIter); } else { m_handlers.emplace_front(handler, cufIter); } return true; }