static inline zend_long *pthreads_get_guard(zend_object *zobj, zval *member) /* {{{ */ { HashTable *guards; zend_long stub, *guard; zval tmp; ZEND_ASSERT(GC_FLAGS(zobj) & IS_OBJ_USE_GUARDS); if (GC_FLAGS(zobj) & IS_OBJ_HAS_GUARDS) { guards = Z_PTR(zobj->properties_table[zobj->ce->default_properties_count]); ZEND_ASSERT(guards != NULL); if (Z_TYPE_P(member) == IS_LONG) { if ((guard = (zend_long *)zend_hash_index_find_ptr(guards, Z_LVAL_P(member))) != NULL) { return guard; } } else { if ((guard = (zend_long *)zend_hash_find_ptr(guards, Z_STR_P(member))) != NULL) { return guard; } } } else { ALLOC_HASHTABLE(guards); zend_hash_init(guards, 8, NULL, pthreads_guard_dtor, 0); ZVAL_PTR(&tmp, guards); Z_PTR(zobj->properties_table[zobj->ce->default_properties_count]) = guards; GC_FLAGS(zobj) |= IS_OBJ_HAS_GUARDS; } stub = 0; if (Z_TYPE_P(member) == IS_LONG) { return (zend_long *)zend_hash_index_add_mem(guards, Z_LVAL_P(member), &stub, sizeof(zend_ulong)); } else return (zend_long *)zend_hash_add_mem(guards, Z_STR_P(member), &stub, sizeof(zend_ulong)); }
/* Must prevent duplicates ... if there are duplicates, replace new by old! */ static void phpdbg_add_watch_collision(phpdbg_watchpoint_t *watch) { phpdbg_watch_collision *cur; /* Check for either recursive or (simple and/or implicit) */ ZEND_ASSERT(((watch->flags & PHPDBG_WATCH_RECURSIVE) == 0) ^ ((watch->flags & (PHPDBG_WATCH_IMPLICIT | PHPDBG_WATCH_SIMPLE)) == 0)); if ((cur = zend_hash_index_find_ptr(&PHPDBG_G(watch_collisions), (zend_ulong) watch->addr.ref))) { phpdbg_watchpoint_t *old; int flags = 0; if ((old = zend_hash_find_ptr(&cur->watches, watch->str)) || (old = zend_hash_find_ptr(&cur->implicit_watches, watch->str))) { if (((old->flags ^ watch->flags) & (PHPDBG_WATCH_NORMAL|PHPDBG_WATCH_IMPLICIT)) == 0) { return; /* there was no change ... */ } flags = old->flags; if (flags & PHPDBG_WATCH_RECURSIVE) { if (!(watch->flags & PHPDBG_WATCH_RECURSIVE) && !--cur->refs) { phpdbg_delete_watchpoints_recursive(watch); } } if (flags & PHPDBG_WATCH_NORMAL) { zend_hash_del(&cur->watches, watch->str); if (zend_hash_num_elements(&cur->watches) > 0) { cur->watch = Z_PTR_P(zend_hash_get_current_data_ex(&cur->watches, NULL)); } else { cur->watch = Z_PTR_P(zend_hash_get_current_data_ex(&cur->implicit_watches, NULL)); } } if (flags & PHPDBG_WATCH_IMPLICIT) { zend_hash_del(&cur->implicit_watches, watch->str); } old->flags = watch->flags; phpdbg_free_watch(watch); efree(watch); watch = old; } if (watch->flags & PHPDBG_WATCH_RECURSIVE) { if (!(flags & PHPDBG_WATCH_RECURSIVE) && !cur->refs++) { phpdbg_create_recursive_zval_watch(watch->parent); } } } else { phpdbg_watch_collision coll; coll.refs = (watch->flags & PHPDBG_WATCH_RECURSIVE) != 0; coll.watch = watch; zend_hash_init(&coll.watches, 8, arghs, NULL, 0); zend_hash_init(&coll.implicit_watches, 8, ..., NULL, 0); cur = zend_hash_index_add_mem(&PHPDBG_G(watch_collisions), (zend_ulong) watch->addr.ref, &coll, sizeof(phpdbg_watch_collision)); phpdbg_store_watchpoint(cur->watch); phpdbg_activate_watchpoint(cur->watch); if (coll.refs) { phpdbg_create_recursive_zval_watch(watch->parent); } } if (watch->flags & PHPDBG_WATCH_NORMAL) { cur->watch = watch; zend_hash_add_ptr(&cur->watches, watch->str, watch->parent); } if (watch->flags & PHPDBG_WATCH_IMPLICIT) { zend_hash_add_ptr(&cur->implicit_watches, watch->str, watch->parent); } }