static HashTable* dom_get_debug_info_helper(zval *object, int *is_temp TSRMLS_DC) /* {{{ */
{
- dom_object *obj = (dom_object *)zend_object_store_get_object(object TSRMLS_CC);
- HashTable *debug_info, *props;
- HashPosition pos;
- dom_prop_handler *entry;
+ dom_object *obj = zend_object_store_get_object(object TSRMLS_CC);
+ HashTable *debug_info,
+ *prop_handlers = obj->prop_handler,
+ *std_props;
+ HashPosition pos;
+ dom_prop_handler *entry;
+ zval *object_value,
+ *null_value;
+
+ *is_temp = 1;
+
+ ALLOC_HASHTABLE(debug_info);
+ ZEND_INIT_SYMTABLE_EX(debug_info, 32, 0);
+
+ std_props = zend_std_get_properties(object TSRMLS_CC);
+ zend_hash_copy(debug_info, std_props, (copy_ctor_func_t)zval_add_ref,
+ NULL, sizeof(zval*));
+
+ if (!prop_handlers) {
+ return debug_info;
+ }
- *is_temp = 1;
+ ALLOC_INIT_ZVAL(object_value);
+ ZVAL_STRING(object_value, "(object value omitted)", 1);
- ALLOC_HASHTABLE(debug_info);
- if (! obj->prop_handler) {
- return debug_info;
- }
+ ALLOC_INIT_ZVAL(null_value);
+ ZVAL_NULL(null_value);
- props = obj->prop_handler;
- ZEND_INIT_SYMTABLE_EX(debug_info, zend_hash_num_elements(props) + 1, 0);
-
- zend_hash_internal_pointer_reset_ex(props, &pos);
- while (zend_hash_get_current_data_ex(props, (void **)&entry, &pos) == SUCCESS) {
- zval member;
- zval *value;
-
- char *string_key=NULL;
- uint string_length=0;
- ulong num_key;
-
- zend_hash_get_current_key_ex(props, &string_key, &string_length, &num_key, 0, &pos);
-
- INIT_ZVAL(member);
- ZVAL_STRINGL(&member, string_key, string_length, 0);
- value = zend_read_property(Z_OBJCE_P(object), object, Z_STRVAL(member), Z_STRLEN(member)-1, 1 TSRMLS_CC);
- if (value != EG(uninitialized_zval_ptr)) {
- switch(Z_TYPE_P(value)) {
- case IS_STRING:
- case IS_BOOL:
- case IS_LONG:
- case IS_DOUBLE:
- case IS_ARRAY:
- zend_hash_add(debug_info, string_key, string_length, &value, sizeof(zval *), NULL);
- break;
-
- default:
- ZVAL_NULL(value);
- zend_hash_add(debug_info, string_key, string_length, &value, sizeof(zval *), NULL);
- break;
- }
- } else {
- ZVAL_NULL(value);
- zend_hash_add(debug_info, string_key, string_length, &value, sizeof(zval *), NULL);
- }
- zend_hash_move_forward_ex(props, &pos);
- }
+ for (zend_hash_internal_pointer_reset_ex(prop_handlers, &pos);
+ zend_hash_get_current_data_ex(prop_handlers, (void **)&entry, &pos)
+ == SUCCESS;
+ zend_hash_move_forward_ex(prop_handlers, &pos)) {
+ zval *value;
+ char *string_key = NULL;
+ uint string_length = 0;
+ ulong num_key;
+
+ if (entry->read_func(obj, &value TSRMLS_CC) == FAILURE) {
+ continue;
+ }
+
+ if (zend_hash_get_current_key_ex(prop_handlers, &string_key,
+ &string_length, &num_key, 0, &pos) != HASH_KEY_IS_STRING) {
+ continue;
+ }
+
+ if (value == EG(uninitialized_zval_ptr)) {
+ value = null_value;
+ } else if (Z_TYPE_P(value) == IS_OBJECT) {
+ /* these are zvalues create on demand, with refcount and is_ref
+ * status left in an uninitalized stated */
+ zval_dtor(value);
+ efree(value);
+
+ value = object_value;
+ } else {
+ /* see comment above */
+ Z_SET_REFCOUNT_P(value, 0);
+ Z_UNSET_ISREF_P(value);
+ }
+
+ zval_add_ref(&value);
+ zend_hash_add(debug_info, string_key, string_length,
+ &value, sizeof(zval *), NULL);
+ }
+
+ zval_ptr_dtor(&null_value);
+ zval_ptr_dtor(&object_value);
- return debug_info;
+ return debug_info;
}
/* }}} */