Object c_GenMapWaitHandle::ti_create(const Variant& dependencies) { if (UNLIKELY(!dependencies.isObject() || dependencies.getObjectData()->getCollectionType() != Collection::MapType)) { Object e(SystemLib::AllocInvalidArgumentExceptionObject( "Expected dependencies to be an instance of Map")); throw e; } assert(dependencies.getObjectData()->instanceof(c_Map::classof())); auto deps = p_Map::attach(c_Map::Clone(dependencies.getObjectData())); for (ssize_t iter_pos = deps->iter_begin(); deps->iter_valid(iter_pos); iter_pos = deps->iter_next(iter_pos)) { auto* current = tvAssertCell(deps->iter_value(iter_pos)); if (UNLIKELY(!c_WaitHandle::fromCell(current))) { Object e(SystemLib::AllocInvalidArgumentExceptionObject( "Expected dependencies to be a map of WaitHandle instances")); throw e; } } Object exception; for (ssize_t iter_pos = deps->iter_begin(); deps->iter_valid(iter_pos); iter_pos = deps->iter_next(iter_pos)) { auto* current = tvAssertCell(deps->iter_value(iter_pos)); assert(current->m_type == KindOfObject); assert(current->m_data.pobj->instanceof(c_WaitHandle::classof())); auto child = static_cast<c_WaitHandle*>(current->m_data.pobj); if (child->isSucceeded()) { auto k = deps->iter_key(iter_pos); deps->set(k.asCell(), &child->getResult()); } else if (child->isFailed()) { putException(exception, child->getException()); } else { assert(child->instanceof(c_WaitableWaitHandle::classof())); auto child_wh = static_cast<c_WaitableWaitHandle*>(child); p_GenMapWaitHandle my_wh = NEWOBJ(c_GenMapWaitHandle)(); my_wh->initialize(exception, deps.get(), iter_pos, child_wh); AsioSession* session = AsioSession::Get(); if (UNLIKELY(session->hasOnGenMapCreateCallback())) { session->onGenMapCreate(my_wh.get(), dependencies); } return my_wh; } } if (exception.isNull()) { return Object::attach(c_StaticWaitHandle::CreateSucceeded( make_tv<KindOfObject>(deps.detach()))); } else { return Object::attach(c_StaticWaitHandle::CreateFailed(exception.detach())); } }
ALWAYS_INLINE typename std::enable_if< std::is_base_of<BaseMap, TMap>::value, Object>::type BaseMap::php_takeWhile(const Variant& fn) { CallCtx ctx; vm_decode_function(fn, nullptr, false, ctx); if (!ctx.func) { SystemLib::throwInvalidArgumentExceptionObject( "Parameter must be a valid callback"); } auto map = req::make<TMap>(); if (!m_size) return Object{std::move(map)}; int32_t version UNUSED; if (std::is_same<c_Map, TMap>::value) { version = m_version; } for (ssize_t pos = iter_begin(); iter_valid(pos); pos = iter_next(pos)) { auto* e = iter_elm(pos); bool b = invokeAndCastToBool(ctx, 1, &e->data); if (std::is_same<c_Map, TMap>::value) { if (UNLIKELY(version != m_version)) { throw_collection_modified(); } } if (!b) break; e = iter_elm(pos); if (e->hasIntKey()) { map->set(e->ikey, &e->data); } else { assert(e->hasStrKey()); map->set(e->skey, &e->data); } } return Object{std::move(map)}; }
void lttng_ust_dl_update(void *ip) { struct dl_iterate_data data; if (getenv("LTTNG_UST_WITHOUT_BADDR_STATEDUMP")) return; /* * Fixup lttng-ust TLS when called from dlopen/dlclose * instrumentation. */ lttng_ust_fixup_tls(); data.exec_found = 0; data.first = true; data.cancel = false; /* * Iterate through the list of currently loaded shared objects and * generate tables entries for loadable segments using * extract_bin_info_events. * Removed libraries are detected by mark-and-sweep: marking is * done in the iteration over libraries, and sweeping is * performed by iter_end(). */ dl_iterate_phdr(extract_bin_info_events, &data); if (data.first) iter_begin(&data); iter_end(&data, ip); }
Array Globals::getDefinedVars() { Array ret = Array::Create(); for (ssize_t iter = iter_begin(); iter != ArrayData::invalid_index; iter = iter_advance(iter)) { Variant k; Variant v = getByIdx(iter, k); ret.set(k, v); } return ret; }
int main(int argc, char** argv) { size_t num_lines = 0; utils::istream_line_iterator iter_begin(std::cin); utils::istream_line_iterator iter_end; for (utils::istream_line_iterator iter = iter_begin; iter != iter_end; ++ iter) ++ num_lines; std::cout << "# of lines: " << num_lines << std::endl; }
ssize_t NameValueTableWrapper::vsize() const { // We need to iterate to find out the actual size, since // KindOfIndirect elements in the array may have been set to // KindOfUninit. ssize_t count = 0; for (ssize_t iter = iter_begin(); iter != ArrayData::invalid_index; iter = iter_advance(iter)) { ++count; } return count; }
ArrayData *ArrayData::dequeue(Variant &value) { if (!empty()) { auto const pos = iter_begin(); value = getValue(pos); ArrayData *ret = remove(getKey(pos), getCount() > 1); // In PHP, array_shift() will cause all numerically key-ed values re-keyed ret->renumber(); return ret; } value = uninit_null(); return this; }
void ArrayData::getChildren(std::vector<TypedValue *> &out) { if (isSharedMap()) { SharedMap *sm = static_cast<SharedMap *>(this); sm->getChildren(out); return; } for (ssize_t pos = iter_begin(); pos != ArrayData::invalid_index; pos = iter_advance(pos)) { TypedValue *tv = nvGetValueRef(pos); out.push_back(tv); } }
Object BaseMap::php_retain(const Variant& callback) { CallCtx ctx; vm_decode_function(callback, nullptr, false, ctx); if (!ctx.func) { SystemLib::throwInvalidArgumentExceptionObject( "Parameter must be a valid callback"); } auto size = m_size; if (!size) { return Object{this}; } constexpr int64_t argc = useKey ? 2 : 1; TypedValue argv[argc]; for (ssize_t pos = iter_begin(); iter_valid(pos); pos = iter_next(pos)) { auto* e = iter_elm(pos); if (useKey) { if (e->hasIntKey()) { argv[0].m_type = KindOfInt64; argv[0].m_data.num = e->ikey; } else { argv[0].m_type = KindOfString; argv[0].m_data.pstr = e->skey; } } argv[argc-1] = e->data; int32_t version = m_version; bool b = invokeAndCastToBool(ctx, argc, argv); if (UNLIKELY(version != m_version)) { throw_collection_modified(); } if (b) { continue; } mutateAndBump(); version = m_version; e = iter_elm(pos); ssize_t pp = (e->hasIntKey() ? findForRemove(e->ikey) : findForRemove(e->skey, e->skey->hash())); eraseNoCompact(pp); if (UNLIKELY(version != m_version)) { throw_collection_modified(); } } assert(m_size <= size); compactOrShrinkIfDensityTooLow(); return Object{this}; }
ArrayData *ArrayData::dequeue(Variant &value) { if (!empty()) { ssize_t pos = iter_begin(); value = getValue(pos); ArrayData *ret = remove(getKey(pos), getCount() > 1); // In PHP, array_shift() will cause all numerically key-ed values re-keyed if (ret) { ret->renumber(); } else { renumber(); } return ret; } value = null; return NULL; }
ALWAYS_INLINE typename std::enable_if< std::is_base_of<BaseMap, TMap>::value, Object>::type BaseMap::php_filter(const Variant& callback) const { VMRegGuard _; CallCtx ctx; vm_decode_function(callback, nullptr, false, ctx); if (!ctx.func) { SystemLib::throwInvalidArgumentExceptionObject( "Parameter must be a valid callback"); } auto map = req::make<TMap>(); if (!m_size) return Object(std::move(map)); map->mutate(); int32_t version = m_version; constexpr int64_t argc = useKey ? 2 : 1; TypedValue argv[argc]; for (ssize_t pos = iter_begin(); iter_valid(pos); pos = iter_next(pos)) { auto* e = iter_elm(pos); if (useKey) { if (e->hasIntKey()) { argv[0].m_type = KindOfInt64; argv[0].m_data.num = e->ikey; } else { argv[0].m_type = KindOfString; argv[0].m_data.pstr = e->skey; } } argv[argc-1] = e->data; bool b = invokeAndCastToBool(ctx, argc, argv); if (UNLIKELY(version != m_version)) { throw_collection_modified(); } if (!b) continue; e = iter_elm(pos); if (e->hasIntKey()) { map->set(e->ikey, &e->data); } else { assert(e->hasStrKey()); map->set(e->skey, &e->data); } } return Object(std::move(map)); }
typename std::enable_if< std::is_base_of<BaseSet, TSet>::value, Object>::type BaseSet::php_map(const Variant& callback) const { VMRegGuard _; CallCtx ctx; vm_decode_function(callback, nullptr, false, ctx); if (!ctx.func) { SystemLib::throwInvalidArgumentExceptionObject( "Parameter must be a valid callback"); } auto set = req::make<TSet>(); if (!m_size) return Object{std::move(set)}; assert(posLimit() != 0); assert(hashSize() > 0); assert(set->arrayData() == staticEmptyMixedArray()); auto oldCap = set->cap(); set->reserve(posLimit()); // presume minimum collisions ... assert(set->canMutateBuffer()); constexpr int64_t argc = useKey ? 2 : 1; TypedValue argv[argc]; for (ssize_t pos = iter_begin(); iter_valid(pos); pos = iter_next(pos)) { auto e = iter_elm(pos); TypedValue tvCbRet; int32_t pVer = m_version; if (useKey) { argv[0] = e->data; } argv[argc-1] = e->data; g_context->invokeFuncFew(&tvCbRet, ctx, argc, argv); // Now that tvCbRet is live, make sure to decref even if we throw. SCOPE_EXIT { tvRefcountedDecRef(&tvCbRet); }; if (UNLIKELY(m_version != pVer)) throw_collection_modified(); set->addRaw(&tvCbRet); } // ... and shrink back if that was incorrect set->shrinkIfCapacityTooHigh(oldCap); return Object{std::move(set)}; }
typename std::enable_if< std::is_base_of<BaseSet, TSet>::value, Object>::type BaseSet::php_filter(const Variant& callback) const { VMRegGuard _; CallCtx ctx; vm_decode_function(callback, nullptr, false, ctx); if (!ctx.func) { SystemLib::throwInvalidArgumentExceptionObject( "Parameter must be a valid callback"); } auto set = req::make<TSet>(); if (!m_size) return Object(std::move(set)); // we don't reserve(), because we don't know how selective callback will be set->mutate(); int32_t version = m_version; constexpr int64_t argc = useKey ? 2 : 1; TypedValue argv[argc]; for (ssize_t pos = iter_begin(); iter_valid(pos); pos = iter_next(pos)) { auto e = iter_elm(pos); if (useKey) { argv[0] = e->data; } argv[argc-1] = e->data; bool b = invokeAndCastToBool(ctx, argc, argv); if (UNLIKELY(version != m_version)) { throw_collection_modified(); } if (!b) continue; e = iter_elm(pos); if (e->hasIntKey()) { set->addRaw(e->data.m_data.num); } else { assert(e->hasStrKey()); set->addRaw(e->data.m_data.pstr); } } return Object(std::move(set)); }
static int extract_bin_info_events(struct dl_phdr_info *info, size_t size, void *_data) { int j, ret = 0; struct dl_iterate_data *data = _data; if (data->first) { iter_begin(data); data->first = false; } if (data->cancel) goto end; for (j = 0; j < info->dlpi_phnum; j++) { struct bin_info_data bin_data; if (info->dlpi_phdr[j].p_type != PT_LOAD) continue; memset(&bin_data, 0, sizeof(bin_data)); /* Calculate virtual memory address of the loadable segment */ bin_data.base_addr_ptr = (void *) info->dlpi_addr + info->dlpi_phdr[j].p_vaddr; if ((info->dlpi_name == NULL || info->dlpi_name[0] == 0)) { /* * Only the first phdr without a dlpi_name * encountered is considered as the program * executable. The rest are vdsos. */ if (!data->exec_found) { ssize_t path_len; data->exec_found = 1; /* * Use /proc/self/exe to resolve the * executable's full path. */ path_len = readlink("/proc/self/exe", bin_data.resolved_path, PATH_MAX - 1); if (path_len <= 0) break; bin_data.resolved_path[path_len] = '\0'; bin_data.vdso = 0; } else { snprintf(bin_data.resolved_path, PATH_MAX - 1, "[vdso]"); bin_data.vdso = 1; } } else { /* * For regular dl_phdr_info entries check if * the path to the binary really exists. If not, * treat as vdso and use dlpi_name as 'path'. */ if (!realpath(info->dlpi_name, bin_data.resolved_path)) { snprintf(bin_data.resolved_path, PATH_MAX - 1, "[%s]", info->dlpi_name); bin_data.vdso = 1; } else { bin_data.vdso = 0; } } ret = extract_baddr(&bin_data); break; } end: return ret; }
Variant ArrayData::reset() { setPosition(iter_begin()); return m_pos != iter_end() ? getValue(m_pos) : Variant(false); }
Variant NameValueTableWrapper::reset() { m_pos = iter_begin(); return current(); }
Object c_GenMapWaitHandle::ti_create(const Variant& dependencies) { ObjectData* obj; if (UNLIKELY(!dependencies.isObject() || !(obj = dependencies.getObjectData())->isCollection() || obj->collectionType() != CollectionType::Map)) { SystemLib::throwInvalidArgumentExceptionObject( "Expected dependencies to be an instance of Map"); } assertx(obj->collectionType() == CollectionType::Map); auto deps = req::ptr<c_Map>::attach(c_Map::Clone(obj)); auto ctx_idx = std::numeric_limits<context_idx_t>::max(); for (ssize_t iter_pos = deps->iter_begin(); deps->iter_valid(iter_pos); iter_pos = deps->iter_next(iter_pos)) { auto* current = tvAssertCell(deps->iter_value(iter_pos)); auto const child = c_WaitHandle::fromCell(current); if (UNLIKELY(!child)) { SystemLib::throwInvalidArgumentExceptionObject( "Expected dependencies to be a map of WaitHandle instances"); } if (!child->isFinished()) { ctx_idx = std::min( ctx_idx, static_cast<c_WaitableWaitHandle*>(child)->getContextIdx() ); } } Object exception; for (ssize_t iter_pos = deps->iter_begin(); deps->iter_valid(iter_pos); iter_pos = deps->iter_next(iter_pos)) { auto* current = tvAssertCell(deps->iter_value(iter_pos)); assert(current->m_type == KindOfObject); assert(current->m_data.pobj->instanceof(c_WaitHandle::classof())); auto child = static_cast<c_WaitHandle*>(current->m_data.pobj); if (child->isSucceeded()) { auto k = deps->iter_key(iter_pos); auto result = child->getResult(); deps->set(k.asCell(), &result); } else if (child->isFailed()) { putException(exception, child->getException()); } else { assert(child->instanceof(c_WaitableWaitHandle::classof())); auto child_wh = static_cast<c_WaitableWaitHandle*>(child); auto my_wh = req::make<c_GenMapWaitHandle>(); my_wh->initialize(exception, deps.get(), iter_pos, ctx_idx, child_wh); AsioSession* session = AsioSession::Get(); if (UNLIKELY(session->hasOnGenMapCreate())) { session->onGenMapCreate(my_wh.get(), dependencies); } return Object(std::move(my_wh)); } } if (exception.isNull()) { return Object::attach(c_StaticWaitHandle::CreateSucceeded( make_tv<KindOfObject>(deps.detach()))); } else { return Object::attach(c_StaticWaitHandle::CreateFailed(exception.detach())); } }
Variant ArrayData::reset() { m_pos = iter_begin(); return m_pos != invalid_index ? getValue(m_pos) : Variant(false); }