From: Marcus Boerger Date: Thu, 18 Jan 2007 23:23:13 +0000 (+0000) Subject: - Add debug_info helper to overloadedobjects X-Git-Tag: RELEASE_1_0_0RC1~216 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=13da6bf4d796fa00a10f18c9987285e8fe9359d7;p=php - Add debug_info helper to overloadedobjects --- diff --git a/Zend/zend.c b/Zend/zend.c index 51650fb137..7e6f549138 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -578,9 +578,10 @@ ZEND_API void zend_print_zval_r_ex(zend_write_func_t write_func, zval *expr, int break; case IS_OBJECT: { - HashTable *properties = NULL; + HashTable *properties; zstr class_name = NULL_ZSTR; zend_uint clen; + int is_temp; if (Z_OBJ_HANDLER_P(expr, get_class_name)) { Z_OBJ_HANDLER_P(expr, get_class_name)(expr, &class_name, &clen, 0 TSRMLS_CC); @@ -593,17 +594,24 @@ ZEND_API void zend_print_zval_r_ex(zend_write_func_t write_func, zval *expr, int if (class_name.v) { efree(class_name.v); } - if (Z_OBJ_HANDLER_P(expr, get_properties)) { + if (Z_OBJ_HANDLER_P(expr, get_debug_info)) { + properties = Z_OBJ_HANDLER_P(expr, get_debug_info)(expr, &is_temp TSRMLS_CC); + } else if (Z_OBJ_HANDLER_P(expr, get_properties)) { properties = Z_OBJPROP_P(expr); + is_temp = 0; + } else { + break; } - if (properties) { - if (++properties->nApplyCount>1) { - ZEND_PUTS(" *RECURSION*"); - properties->nApplyCount--; - return; - } - print_hash(properties, indent, 1 TSRMLS_CC); + if (++properties->nApplyCount>1) { + ZEND_PUTS(" *RECURSION*"); properties->nApplyCount--; + return; + } + print_hash(properties, indent, 1 TSRMLS_CC); + properties->nApplyCount--; + if (is_temp) { + zend_hash_destroy(properties); + efree(properties); } break; } diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index eb4281be0e..080641798c 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -49,13 +49,19 @@ called, we cal __call handler. */ -static HashTable *zend_std_get_properties(zval *object TSRMLS_DC) +ZEND_API HashTable *zend_std_get_properties(zval *object TSRMLS_DC) { zend_object *zobj; zobj = Z_OBJ_P(object); return zobj->properties; } +ZEND_API HashTable *zend_std_get_debug_info(zval *object, int *is_temp TSRMLS_DC) +{ + *is_temp = 0; + return zend_std_get_properties(object TSRMLS_CC); +} + static zval *zend_std_call_getter(zval *object, zval *member TSRMLS_DC) { zval *retval = NULL; @@ -1186,6 +1192,7 @@ ZEND_API zend_object_handlers std_object_handlers = { zend_std_compare_objects, /* compare_objects */ zend_std_cast_object_tostring, /* cast_object */ NULL, /* count_elements */ + NULL, /* get_debug_info */ }; /* diff --git a/Zend/zend_object_handlers.h b/Zend/zend_object_handlers.h index c5fbb84014..033140b67e 100644 --- a/Zend/zend_object_handlers.h +++ b/Zend/zend_object_handlers.h @@ -80,6 +80,8 @@ typedef void (*zend_object_unset_dimension_t)(zval *object, zval *offset TSRMLS_ /* Used to get hash of the properties of the object, as hash of zval's */ typedef HashTable *(*zend_object_get_properties_t)(zval *object TSRMLS_DC); +typedef HashTable *(*zend_object_get_debug_info_t)(zval *object, int *is_temp TSRMLS_DC); + /* Used to call methods */ /* args on stack! */ /* Andi - EX(fbc) (function being called) needs to be initialized already in the INIT fcall opcode so that the parameters can be parsed the right way. We need to add another callback for this. @@ -132,6 +134,7 @@ struct _zend_object_handlers { zend_object_compare_t compare_objects; zend_object_cast_t cast_object; zend_object_count_elements_t count_elements; + zend_object_get_debug_info_t get_debug_info; }; extern ZEND_API zend_object_handlers std_object_handlers; @@ -142,7 +145,8 @@ ZEND_API zval **zend_std_get_static_property(zend_class_entry *ce, zend_uchar ty ZEND_API zend_bool zend_std_unset_static_property(zend_class_entry *ce, zend_uchar type, zstr property_name, int property_name_len TSRMLS_DC); ZEND_API union _zend_function *zend_std_get_constructor(zval *object TSRMLS_DC); ZEND_API struct _zend_property_info *zend_get_property_info(zend_class_entry *ce, zval *member, int silent TSRMLS_DC); - +ZEND_API HashTable *zend_std_get_properties(zval *object TSRMLS_DC); +ZEND_API HashTable *zend_std_get_debug_info(zval *object, int *is_temp TSRMLS_DC); ZEND_API int zend_std_cast_object_tostring(zval *readobj, zval *writeobj, int type, void *extra TSRMLS_DC); diff --git a/ext/standard/var.c b/ext/standard/var.c index f2cbf75f7a..477c4331f7 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -177,10 +177,11 @@ static int php_object_property_dump(zval **zv, int num_args, va_list args, zend_ PHPAPI void php_var_dump(zval **struc, int level, int verbose TSRMLS_DC) { - HashTable *myht = NULL; + HashTable *myht; zstr class_name; zend_uint class_name_len; int (*php_element_dump_func)(zval**, int, va_list, zend_hash_key*); + int is_temp; if (level > 1) { php_printf("%*c", level - 1, ' '); @@ -217,9 +218,18 @@ PHPAPI void php_var_dump(zval **struc, int level, int verbose TSRMLS_DC) } php_printf("%sarray(%d) {\n", COMMON, zend_hash_num_elements(myht)); php_element_dump_func = php_array_element_dump; + is_temp = 0; goto head_done; case IS_OBJECT: - myht = Z_OBJPROP_PP(struc); + if (Z_OBJ_HANDLER_PP(struc, get_debug_info)) { + myht = Z_OBJ_HANDLER_PP(struc, get_debug_info)(*struc, &is_temp TSRMLS_CC); + } else if (Z_OBJ_HANDLER_PP(struc, get_properties)) { + myht = Z_OBJPROP_PP(struc); + is_temp = 0; + } else { + myht = NULL; + is_temp = 0; + } if (myht && myht->nApplyCount > 1) { PUTS("*RECURSION*\n"); return; @@ -232,6 +242,10 @@ PHPAPI void php_var_dump(zval **struc, int level, int verbose TSRMLS_DC) head_done: if (myht) { zend_hash_apply_with_arguments(myht, (apply_func_args_t) php_element_dump_func, 3, level, verbose, (Z_TYPE_PP(struc) == IS_ARRAY ? 0 : 1)); + if (is_temp) { + zend_hash_destroy(myht); + efree(myht); + } } if (level > 1) { php_printf("%*c", level-1, ' '); @@ -377,6 +391,7 @@ PHPAPI void php_debug_zval_dump(zval **struc, int level, int verbose TSRMLS_DC) zend_uint class_name_len; zend_class_entry *ce; int (*zval_element_dump_func)(zval**, int, va_list, zend_hash_key*); + int is_temp; if (level > 1) { php_printf("%*c", level - 1, ' '); @@ -415,19 +430,31 @@ PHPAPI void php_debug_zval_dump(zval **struc, int level, int verbose TSRMLS_DC) zval_element_dump_func = zval_array_element_dump; goto head_done; case IS_OBJECT: - myht = Z_OBJPROP_PP(struc); + if (Z_OBJ_HANDLER_PP(struc, get_debug_info)) { + myht = Z_OBJ_HANDLER_PP(struc, get_debug_info)(*struc, &is_temp TSRMLS_CC); + } else if (Z_OBJ_HANDLER_PP(struc, get_properties)) { + myht = Z_OBJPROP_PP(struc); + is_temp = 0; + } else { + myht = NULL; + is_temp = 0; + } if (myht && myht->nApplyCount > 1) { PUTS("*RECURSION*\n"); return; } - ce = Z_OBJCE(**struc); - Z_OBJ_HANDLER(**struc, get_class_name)(*struc, &class_name, &class_name_len, 0 TSRMLS_CC); + ce = Z_OBJCE_PP(struc); + Z_OBJ_HANDLER_PP(struc, get_class_name)(*struc, &class_name, &class_name_len, 0 TSRMLS_CC); php_printf("%sobject(%v)#%d (%d) refcount(%u){\n", COMMON, class_name, Z_OBJ_HANDLE_PP(struc), myht ? zend_hash_num_elements(myht) : 0, Z_REFCOUNT_PP(struc)); efree(class_name.v); zval_element_dump_func = zval_object_property_dump; head_done: if (myht) { zend_hash_apply_with_arguments(myht, (apply_func_args_t) zval_element_dump_func, 1, level, (Z_TYPE_PP(struc) == IS_ARRAY ? 0 : 1)); + if (is_temp) { + zend_hash_destroy(myht); + efree(myht); + } } if (level > 1) { php_printf("%*c", level-1, ' ');