colder Thu, 13 Aug 2009 22:07:05 +0000 Revision: http://svn.php.net/viewvc?view=revision&revision=287266
Log: Fix several recursion problems when var_dump'ing self-referencing objects Changed paths: U php/php-src/branches/PHP_5_3/ext/spl/spl_array.c U php/php-src/branches/PHP_5_3/ext/spl/spl_dllist.c U php/php-src/branches/PHP_5_3/ext/spl/spl_heap.c U php/php-src/branches/PHP_5_3/ext/spl/spl_observer.c A php/php-src/branches/PHP_5_3/ext/spl/tests/SplObjectStorage_var_dump.phpt A php/php-src/branches/PHP_5_3/ext/spl/tests/array_027.phpt A php/php-src/branches/PHP_5_3/ext/spl/tests/dllist_012.phpt A php/php-src/branches/PHP_5_3/ext/spl/tests/heap_012.phpt U php/php-src/trunk/ext/spl/spl_array.c U php/php-src/trunk/ext/spl/spl_dllist.c U php/php-src/trunk/ext/spl/spl_heap.c U php/php-src/trunk/ext/spl/spl_observer.c A php/php-src/trunk/ext/spl/tests/SplObjectStorage_var_dump.phpt A php/php-src/trunk/ext/spl/tests/array_027.phpt A php/php-src/trunk/ext/spl/tests/dllist_012.phpt A php/php-src/trunk/ext/spl/tests/heap_012.phpt
Modified: php/php-src/branches/PHP_5_3/ext/spl/spl_array.c =================================================================== --- php/php-src/branches/PHP_5_3/ext/spl/spl_array.c 2009-08-13 20:19:31 UTC (rev 287265) +++ php/php-src/branches/PHP_5_3/ext/spl/spl_array.c 2009-08-13 22:07:05 UTC (rev 287266) @@ -76,6 +76,7 @@ zend_class_entry *ce_get_iterator; php_serialize_data_t *serialize_data; php_unserialize_data_t *unserialize_data; + HashTable *debug_info; } spl_array_object; static inline HashTable *spl_array_get_hash_table(spl_array_object* intern, int check_std_props TSRMLS_DC) { /* {{{ */ @@ -144,6 +145,11 @@ zval_ptr_dtor(&intern->array); zval_ptr_dtor(&intern->retval); + if (intern->debug_info != NULL) { + zend_hash_destroy(intern->debug_info); + efree(intern->debug_info); + } + efree(object); } /* }}} */ @@ -172,6 +178,7 @@ intern->ar_flags = 0; intern->serialize_data = NULL; intern->unserialize_data = NULL; + intern->debug_info = NULL; intern->ce_get_iterator = spl_ce_ArrayIterator; if (orig) { spl_array_object *other = (spl_array_object*)zend_object_store_get_object(orig TSRMLS_CC); @@ -677,32 +684,34 @@ static HashTable* spl_array_get_debug_info(zval *obj, int *is_temp TSRMLS_DC) /* {{{ */ { spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(obj TSRMLS_CC); - HashTable *rv; zval *tmp, *storage; int name_len; char *zname; zend_class_entry *base; + *is_temp = 0; + if (HASH_OF(intern->array) == intern->std.properties) { - *is_temp = 0; return intern->std.properties; } else { - *is_temp = 1; + if (intern->debug_info == NULL) { + ALLOC_HASHTABLE(intern->debug_info); + ZEND_INIT_SYMTABLE_EX(intern->debug_info, zend_hash_num_elements(intern->std.properties) + 1, 0); + } - ALLOC_HASHTABLE(rv); - ZEND_INIT_SYMTABLE_EX(rv, zend_hash_num_elements(intern->std.properties) + 1, 0); + if (intern->debug_info->nApplyCount == 0) { + zend_hash_copy(intern->debug_info, intern->std.properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); - zend_hash_copy(rv, intern->std.properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + storage = intern->array; + zval_add_ref(&storage); - storage = intern->array; - zval_add_ref(&storage); + base = (Z_OBJ_HT_P(obj) == &spl_handler_ArrayIterator) ? spl_ce_ArrayIterator : spl_ce_ArrayObject; + zname = spl_gen_private_prop_name(base, "storage", sizeof("storage")-1, &name_len TSRMLS_CC); + zend_symtable_update(intern->debug_info, zname, name_len+1, &storage, sizeof(zval *), NULL); + efree(zname); + } - base = (Z_OBJ_HT_P(obj) == &spl_handler_ArrayIterator) ? spl_ce_ArrayIterator : spl_ce_ArrayObject; - zname = spl_gen_private_prop_name(base, "storage", sizeof("storage")-1, &name_len TSRMLS_CC); - zend_symtable_update(rv, zname, name_len+1, &storage, sizeof(zval *), NULL); - efree(zname); - - return rv; + return intern->debug_info; } } /* }}} */ Modified: php/php-src/branches/PHP_5_3/ext/spl/spl_dllist.c =================================================================== --- php/php-src/branches/PHP_5_3/ext/spl/spl_dllist.c 2009-08-13 20:19:31 UTC (rev 287265) +++ php/php-src/branches/PHP_5_3/ext/spl/spl_dllist.c 2009-08-13 22:07:05 UTC (rev 287266) @@ -94,6 +94,7 @@ zend_function *fptr_offset_del; zend_function *fptr_count; zend_class_entry *ce_get_iterator; + HashTable *debug_info; }; /* define an overloaded iterator structure */ @@ -351,6 +352,11 @@ SPL_LLIST_CHECK_DELREF(intern->traverse_pointer); zval_ptr_dtor(&intern->retval); + if (intern->debug_info != NULL) { + zend_hash_destroy(intern->debug_info); + efree(intern->debug_info); + } + efree(object); } /* }}} */ @@ -374,6 +380,7 @@ intern->flags = 0; intern->traverse_position = 0; + intern->debug_info = NULL; if (orig) { spl_dllist_object *other = (spl_dllist_object*)zend_object_store_get_object(orig TSRMLS_CC); @@ -500,44 +507,47 @@ { spl_dllist_object *intern = (spl_dllist_object*)zend_object_store_get_object(obj TSRMLS_CC); spl_ptr_llist_element *current = intern->llist->head, *next; - HashTable *rv; zval *tmp, zrv, *dllist_array; char *pnstr; int pnlen; - int i = 0;; + int i = 0; - *is_temp = 1; + *is_temp = 0; - ALLOC_HASHTABLE(rv); - ZEND_INIT_SYMTABLE_EX(rv, zend_hash_num_elements(intern->std.properties) + 1, 0); + if (intern->debug_info == NULL) { + ALLOC_HASHTABLE(intern->debug_info); + zend_hash_init(intern->debug_info, 1, NULL, ZVAL_PTR_DTOR, 0); + } - INIT_PZVAL(&zrv); - Z_ARRVAL(zrv) = rv; + if (intern->debug_info->nApplyCount == 0) { + INIT_PZVAL(&zrv); + Z_ARRVAL(zrv) = intern->debug_info; - zend_hash_copy(rv, intern->std.properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + zend_hash_copy(intern->debug_info, intern->std.properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); - pnstr = spl_gen_private_prop_name(spl_ce_SplDoublyLinkedList, "flags", sizeof("flags")-1, &pnlen TSRMLS_CC); - add_assoc_long_ex(&zrv, pnstr, pnlen+1, intern->flags); - efree(pnstr); + pnstr = spl_gen_private_prop_name(spl_ce_SplDoublyLinkedList, "flags", sizeof("flags")-1, &pnlen TSRMLS_CC); + add_assoc_long_ex(&zrv, pnstr, pnlen+1, intern->flags); + efree(pnstr); - ALLOC_INIT_ZVAL(dllist_array); - array_init(dllist_array); + ALLOC_INIT_ZVAL(dllist_array); + array_init(dllist_array); - while (current) { - next = current->next; + while (current) { + next = current->next; - add_index_zval(dllist_array, i, (zval *)current->data); - Z_ADDREF_P(current->data); - i++; + add_index_zval(dllist_array, i, (zval *)current->data); + Z_ADDREF_P(current->data); + i++; - current = next; + current = next; + } + + pnstr = spl_gen_private_prop_name(spl_ce_SplDoublyLinkedList, "dllist", sizeof("dllist")-1, &pnlen TSRMLS_CC); + add_assoc_zval_ex(&zrv, pnstr, pnlen+1, dllist_array); + efree(pnstr); } - pnstr = spl_gen_private_prop_name(spl_ce_SplDoublyLinkedList, "dllist", sizeof("dllist")-1, &pnlen TSRMLS_CC); - add_assoc_zval_ex(&zrv, pnstr, pnlen+1, dllist_array); - efree(pnstr); - - return rv; + return intern->debug_info; } /* }}}} */ Modified: php/php-src/branches/PHP_5_3/ext/spl/spl_heap.c =================================================================== --- php/php-src/branches/PHP_5_3/ext/spl/spl_heap.c 2009-08-13 20:19:31 UTC (rev 287265) +++ php/php-src/branches/PHP_5_3/ext/spl/spl_heap.c 2009-08-13 22:07:05 UTC (rev 287266) @@ -76,6 +76,7 @@ zend_class_entry *ce_get_iterator; zend_function *fptr_cmp; zend_function *fptr_count; + HashTable *debug_info; }; /* define an overloaded iterator structure */ @@ -370,6 +371,12 @@ spl_ptr_heap_destroy(intern->heap TSRMLS_CC); zval_ptr_dtor(&intern->retval); + + if (intern->debug_info != NULL) { + zend_hash_destroy(intern->debug_info); + efree(intern->debug_info); + } + efree(object); } /* }}} */ @@ -389,8 +396,9 @@ zend_object_std_init(&intern->std, class_type TSRMLS_CC); zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); - intern->flags = 0; - intern->fptr_cmp = NULL; + intern->flags = 0; + intern->fptr_cmp = NULL; + intern->debug_info = NULL; if (orig) { spl_heap_object *other = (spl_heap_object*)zend_object_store_get_object(orig TSRMLS_CC); @@ -514,43 +522,46 @@ static HashTable* spl_heap_object_get_debug_info_helper(zend_class_entry *ce, zval *obj, int *is_temp TSRMLS_DC) { /* {{{ */ spl_heap_object *intern = (spl_heap_object*)zend_object_store_get_object(obj TSRMLS_CC); - HashTable *rv; zval *tmp, zrv, *heap_array; char *pnstr; int pnlen; int i; - *is_temp = 1; + *is_temp = 0; - ALLOC_HASHTABLE(rv); - ZEND_INIT_SYMTABLE_EX(rv, zend_hash_num_elements(intern->std.properties) + 1, 0); + if (intern->debug_info == NULL) { + ALLOC_HASHTABLE(intern->debug_info); + ZEND_INIT_SYMTABLE_EX(intern->debug_info, zend_hash_num_elements(intern->std.properties) + 1, 0); + } - INIT_PZVAL(&zrv); - Z_ARRVAL(zrv) = rv; + if (intern->debug_info->nApplyCount == 0) { + INIT_PZVAL(&zrv); + Z_ARRVAL(zrv) = intern->debug_info; - zend_hash_copy(rv, intern->std.properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + zend_hash_copy(intern->debug_info, intern->std.properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); - pnstr = spl_gen_private_prop_name(ce, "flags", sizeof("flags")-1, &pnlen TSRMLS_CC); - add_assoc_long_ex(&zrv, pnstr, pnlen+1, intern->flags); - efree(pnstr); + pnstr = spl_gen_private_prop_name(ce, "flags", sizeof("flags")-1, &pnlen TSRMLS_CC); + add_assoc_long_ex(&zrv, pnstr, pnlen+1, intern->flags); + efree(pnstr); - pnstr = spl_gen_private_prop_name(ce, "isCorrupted", sizeof("isCorrupted")-1, &pnlen TSRMLS_CC); - add_assoc_bool_ex(&zrv, pnstr, pnlen+1, intern->heap->flags&SPL_HEAP_CORRUPTED); - efree(pnstr); + pnstr = spl_gen_private_prop_name(ce, "isCorrupted", sizeof("isCorrupted")-1, &pnlen TSRMLS_CC); + add_assoc_bool_ex(&zrv, pnstr, pnlen+1, intern->heap->flags&SPL_HEAP_CORRUPTED); + efree(pnstr); - ALLOC_INIT_ZVAL(heap_array); - array_init(heap_array); + ALLOC_INIT_ZVAL(heap_array); + array_init(heap_array); - for (i = 0; i < intern->heap->count; ++i) { - add_index_zval(heap_array, i, (zval *)intern->heap->elements[i]); - Z_ADDREF_P(intern->heap->elements[i]); + for (i = 0; i < intern->heap->count; ++i) { + add_index_zval(heap_array, i, (zval *)intern->heap->elements[i]); + Z_ADDREF_P(intern->heap->elements[i]); + } + + pnstr = spl_gen_private_prop_name(ce, "heap", sizeof("heap")-1, &pnlen TSRMLS_CC); + add_assoc_zval_ex(&zrv, pnstr, pnlen+1, heap_array); + efree(pnstr); } - pnstr = spl_gen_private_prop_name(ce, "heap", sizeof("heap")-1, &pnlen TSRMLS_CC); - add_assoc_zval_ex(&zrv, pnstr, pnlen+1, heap_array); - efree(pnstr); - - return rv; + return intern->debug_info; } /* }}} */ Modified: php/php-src/branches/PHP_5_3/ext/spl/spl_observer.c =================================================================== --- php/php-src/branches/PHP_5_3/ext/spl/spl_observer.c 2009-08-13 20:19:31 UTC (rev 287265) +++ php/php-src/branches/PHP_5_3/ext/spl/spl_observer.c 2009-08-13 22:07:05 UTC (rev 287266) @@ -84,6 +84,7 @@ long index; HashPosition pos; long flags; + HashTable *debug_info; } spl_SplObjectStorage; /* }}} */ /* {{{ storage is an assoc aray of [zend_object_value]=>[zval *obj, zval *inf] */ @@ -99,6 +100,11 @@ zend_object_std_dtor(&intern->std TSRMLS_CC); zend_hash_destroy(&intern->storage); + + if (intern->debug_info != NULL) { + zend_hash_destroy(intern->debug_info); + efree(intern->debug_info); + } efree(object); } /* }}} */ @@ -238,42 +244,46 @@ { spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(obj TSRMLS_CC); spl_SplObjectStorageElement *element; - HashTable *rv, *props; + HashTable *props; HashPosition pos; zval *tmp, *storage; char md5str[33]; int name_len; char *zname; - *is_temp = 1; + *is_temp = 0; props = Z_OBJPROP_P(obj); - ALLOC_HASHTABLE(rv); - ZEND_INIT_SYMTABLE_EX(rv, zend_hash_num_elements(props) + 1, 0); + if (intern->debug_info == NULL) { + ALLOC_HASHTABLE(intern->debug_info); + ZEND_INIT_SYMTABLE_EX(intern->debug_info, zend_hash_num_elements(props) + 1, 0); + } - zend_hash_copy(rv, props, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + if (intern->debug_info->nApplyCount == 0) { + zend_hash_copy(intern->debug_info, props, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); - MAKE_STD_ZVAL(storage); - array_init(storage); + MAKE_STD_ZVAL(storage); + array_init(storage); - zend_hash_internal_pointer_reset_ex(&intern->storage, &pos); - while (zend_hash_get_current_data_ex(&intern->storage, (void **)&element, &pos) == SUCCESS) { - php_spl_object_hash(element->obj, md5str TSRMLS_CC); - Z_ADDREF_P(element->obj); - Z_ADDREF_P(element->inf); - MAKE_STD_ZVAL(tmp); - array_init(tmp); - add_assoc_zval_ex(tmp, "obj", sizeof("obj"), element->obj); - add_assoc_zval_ex(tmp, "inf", sizeof("inf"), element->inf); - add_assoc_zval_ex(storage, md5str, 33, tmp); - zend_hash_move_forward_ex(&intern->storage, &pos); + zend_hash_internal_pointer_reset_ex(&intern->storage, &pos); + while (zend_hash_get_current_data_ex(&intern->storage, (void **)&element, &pos) == SUCCESS) { + php_spl_object_hash(element->obj, md5str TSRMLS_CC); + Z_ADDREF_P(element->obj); + Z_ADDREF_P(element->inf); + MAKE_STD_ZVAL(tmp); + array_init(tmp); + add_assoc_zval_ex(tmp, "obj", sizeof("obj"), element->obj); + add_assoc_zval_ex(tmp, "inf", sizeof("inf"), element->inf); + add_assoc_zval_ex(storage, md5str, 33, tmp); + zend_hash_move_forward_ex(&intern->storage, &pos); + } + + zname = spl_gen_private_prop_name(spl_ce_SplObjectStorage, "storage", sizeof("storage")-1, &name_len TSRMLS_CC); + zend_symtable_update(intern->debug_info, zname, name_len+1, &storage, sizeof(zval *), NULL); + efree(zname); } - zname = spl_gen_private_prop_name(spl_ce_SplObjectStorage, "storage", sizeof("storage")-1, &name_len TSRMLS_CC); - zend_symtable_update(rv, zname, name_len+1, &storage, sizeof(zval *), NULL); - efree(zname); - - return rv; + return intern->debug_info; } /* }}} */ Added: php/php-src/branches/PHP_5_3/ext/spl/tests/SplObjectStorage_var_dump.phpt =================================================================== --- php/php-src/branches/PHP_5_3/ext/spl/tests/SplObjectStorage_var_dump.phpt (rev 0) +++ php/php-src/branches/PHP_5_3/ext/spl/tests/SplObjectStorage_var_dump.phpt 2009-08-13 22:07:05 UTC (rev 287266) @@ -0,0 +1,35 @@ +--TEST-- +SPL: SplObjectStorage: recursive var_dump +--FILE-- +<?php +$o = new SplObjectStorage(); + +$o[new StdClass] = $o; + +var_dump($o); +--EXPECTF-- +object(SplObjectStorage)#1 (1) { + ["storage":"SplObjectStorage":private]=> + array(1) { + ["%s"]=> + array(2) { + ["obj"]=> + object(stdClass)#2 (0) { + } + ["inf"]=> + object(SplObjectStorage)#1 (1) { + ["storage":"SplObjectStorage":private]=> + array(1) { + ["%s"]=> + array(2) { + ["obj"]=> + object(stdClass)#2 (0) { + } + ["inf"]=> + *RECURSION* + } + } + } + } + } +} Added: php/php-src/branches/PHP_5_3/ext/spl/tests/array_027.phpt =================================================================== --- php/php-src/branches/PHP_5_3/ext/spl/tests/array_027.phpt (rev 0) +++ php/php-src/branches/PHP_5_3/ext/spl/tests/array_027.phpt 2009-08-13 22:07:05 UTC (rev 287266) @@ -0,0 +1,24 @@ +--TEST-- +SPL: ArrayObject revursive var_dump +--FILE-- +<?php +class AO extends ArrayObject { +} +$o = new AO(); +$o['plop'] = $o; + +var_dump($o); +--EXPECTF-- +object(AO)#1 (1) { + ["storage":"ArrayObject":private]=> + array(1) { + ["plop"]=> + object(AO)#1 (1) { + ["storage":"ArrayObject":private]=> + array(1) { + ["plop"]=> + *RECURSION* + } + } + } +} Added: php/php-src/branches/PHP_5_3/ext/spl/tests/dllist_012.phpt =================================================================== --- php/php-src/branches/PHP_5_3/ext/spl/tests/dllist_012.phpt (rev 0) +++ php/php-src/branches/PHP_5_3/ext/spl/tests/dllist_012.phpt 2009-08-13 22:07:05 UTC (rev 287266) @@ -0,0 +1,29 @@ +--TEST-- +SPL: DoublyLinkedList: recursive var_dump +--FILE-- +<?php +$a = new SplDoublyLinkedList; +$a[] = $a; + +var_dump($a); +?> +===DONE=== +--EXPECT-- +object(SplDoublyLinkedList)#1 (2) { + ["flags":"SplDoublyLinkedList":private]=> + int(0) + ["dllist":"SplDoublyLinkedList":private]=> + array(1) { + [0]=> + object(SplDoublyLinkedList)#1 (2) { + ["flags":"SplDoublyLinkedList":private]=> + int(0) + ["dllist":"SplDoublyLinkedList":private]=> + array(1) { + [0]=> + *RECURSION* + } + } + } +} +===DONE=== Added: php/php-src/branches/PHP_5_3/ext/spl/tests/heap_012.phpt =================================================================== --- php/php-src/branches/PHP_5_3/ext/spl/tests/heap_012.phpt (rev 0) +++ php/php-src/branches/PHP_5_3/ext/spl/tests/heap_012.phpt 2009-08-13 22:07:05 UTC (rev 287266) @@ -0,0 +1,32 @@ +--TEST-- +SPL: SplHeap recursive var_dump +--FILE-- +<?php +$a = new SplMaxHeap; +$a->insert($a); +var_dump($a) +?> +===DONE=== +--EXPECT-- +object(SplMaxHeap)#1 (3) { + ["flags":"SplHeap":private]=> + int(0) + ["isCorrupted":"SplHeap":private]=> + bool(false) + ["heap":"SplHeap":private]=> + array(1) { + [0]=> + object(SplMaxHeap)#1 (3) { + ["flags":"SplHeap":private]=> + int(0) + ["isCorrupted":"SplHeap":private]=> + bool(false) + ["heap":"SplHeap":private]=> + array(1) { + [0]=> + *RECURSION* + } + } + } +} +===DONE=== Modified: php/php-src/trunk/ext/spl/spl_array.c =================================================================== --- php/php-src/trunk/ext/spl/spl_array.c 2009-08-13 20:19:31 UTC (rev 287265) +++ php/php-src/trunk/ext/spl/spl_array.c 2009-08-13 22:07:05 UTC (rev 287266) @@ -77,6 +77,7 @@ zend_class_entry *ce_get_iterator; php_serialize_data_t *serialize_data; php_unserialize_data_t *unserialize_data; + HashTable *debug_info; } spl_array_object; static inline HashTable *spl_array_get_hash_table(spl_array_object* intern, int check_std_props TSRMLS_DC) { /* {{{ */ @@ -145,6 +146,11 @@ zval_ptr_dtor(&intern->array); zval_ptr_dtor(&intern->retval); + if (intern->debug_info != NULL) { + zend_hash_destroy(intern->debug_info); + efree(intern->debug_info); + } + efree(object); } /* }}} */ @@ -173,6 +179,7 @@ intern->ar_flags = 0; intern->serialize_data = NULL; intern->unserialize_data = NULL; + intern->debug_info = NULL; intern->ce_get_iterator = spl_ce_ArrayIterator; if (orig) { spl_array_object *other = (spl_array_object*)zend_object_store_get_object(orig TSRMLS_CC); @@ -681,32 +688,33 @@ static HashTable* spl_array_get_debug_info(zval *obj, int *is_temp TSRMLS_DC) /* {{{ */ { spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(obj TSRMLS_CC); - HashTable *rv; zval *tmp, *storage; int name_len; zstr zname; zend_class_entry *base; + *is_temp = 0; if (HASH_OF(intern->array) == intern->std.properties) { - *is_temp = 0; return intern->std.properties; } else { - *is_temp = 1; + if (intern->debug_info == NULL) { + ALLOC_HASHTABLE(intern->debug_info); + ZEND_INIT_SYMTABLE_EX(intern->debug_info, zend_hash_num_elements(intern->std.properties) + 1, 0); + } - ALLOC_HASHTABLE(rv); - ZEND_INIT_SYMTABLE_EX(rv, zend_hash_num_elements(intern->std.properties) + 1, 0); + if (intern->debug_info->nApplyCount == 0) { + zend_hash_copy(intern->debug_info, intern->std.properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + + storage = intern->array; + zval_add_ref(&storage); + + base = (Z_OBJ_HT_P(obj) == &spl_handler_ArrayIterator) ? spl_ce_ArrayIterator : spl_ce_ArrayObject; + zname = spl_gen_private_prop_name(base, "storage", sizeof("storage")-1, &name_len TSRMLS_CC); + zend_u_symtable_update(intern->debug_info, IS_UNICODE, zname, name_len+1, &storage, sizeof(zval *), NULL); + efree(zname.v); + } - zend_hash_copy(rv, intern->std.properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); - - storage = intern->array; - zval_add_ref(&storage); - - base = (Z_OBJ_HT_P(obj) == &spl_handler_ArrayIterator) ? spl_ce_ArrayIterator : spl_ce_ArrayObject; - zname = spl_gen_private_prop_name(base, "storage", sizeof("storage")-1, &name_len TSRMLS_CC); - zend_u_symtable_update(rv, IS_UNICODE, zname, name_len+1, &storage, sizeof(zval *), NULL); - efree(zname.v); - - return rv; + return intern->debug_info; } } /* }}} */ Modified: php/php-src/trunk/ext/spl/spl_dllist.c =================================================================== --- php/php-src/trunk/ext/spl/spl_dllist.c 2009-08-13 20:19:31 UTC (rev 287265) +++ php/php-src/trunk/ext/spl/spl_dllist.c 2009-08-13 22:07:05 UTC (rev 287266) @@ -94,6 +94,7 @@ zend_function *fptr_offset_del; zend_function *fptr_count; zend_class_entry *ce_get_iterator; + HashTable *debug_info; }; /* define an overloaded iterator structure */ @@ -353,6 +354,11 @@ SPL_LLIST_CHECK_DELREF(intern->traverse_pointer); zval_ptr_dtor(&intern->retval); + if (intern->debug_info != NULL) { + zend_hash_destroy(intern->debug_info); + efree(intern->debug_info); + } + efree(object); } /* }}} */ @@ -374,6 +380,7 @@ intern->flags = 0; intern->traverse_position = 0; + intern->debug_info = NULL; if (orig) { spl_dllist_object *other = (spl_dllist_object*)zend_object_store_get_object(orig TSRMLS_CC); @@ -498,44 +505,47 @@ { spl_dllist_object *intern = (spl_dllist_object*)zend_object_store_get_object(obj TSRMLS_CC); spl_ptr_llist_element *current = intern->llist->head, *next; - HashTable *rv; zval *tmp, zrv, *dllist_array; zstr pnstr; int pnlen; int i = 0;; - *is_temp = 1; + *is_temp = 0; - ALLOC_HASHTABLE(rv); - ZEND_INIT_SYMTABLE_EX(rv, zend_hash_num_elements(intern->std.properties) + 1, 0); + if (intern->debug_info == NULL) { + ALLOC_HASHTABLE(intern->debug_info); + ZEND_INIT_SYMTABLE_EX(intern->debug_info, zend_hash_num_elements(intern->std.properties) + 1, 0); + } - INIT_PZVAL(&zrv); - Z_ARRVAL(zrv) = rv; + if (intern->debug_info->nApplyCount == 0) { + INIT_PZVAL(&zrv); + Z_ARRVAL(zrv) = intern->debug_info; - zend_hash_copy(rv, intern->std.properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + zend_hash_copy(intern->debug_info, intern->std.properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); - pnstr = spl_gen_private_prop_name(spl_ce_SplDoublyLinkedList, "flags", sizeof("flags")-1, &pnlen TSRMLS_CC); - add_u_assoc_long_ex(&zrv, IS_UNICODE, pnstr, pnlen+1, intern->flags); - efree(pnstr.v); + pnstr = spl_gen_private_prop_name(spl_ce_SplDoublyLinkedList, "flags", sizeof("flags")-1, &pnlen TSRMLS_CC); + add_u_assoc_long_ex(&zrv, IS_UNICODE, pnstr, pnlen+1, intern->flags); + efree(pnstr.v); - ALLOC_INIT_ZVAL(dllist_array); - array_init(dllist_array); + ALLOC_INIT_ZVAL(dllist_array); + array_init(dllist_array); - while (current) { - next = current->next; + while (current) { + next = current->next; - add_index_zval(dllist_array, i, (zval *)current->data); - Z_ADDREF_P(current->data); - i++; + add_index_zval(dllist_array, i, (zval *)current->data); + Z_ADDREF_P(current->data); + i++; - current = next; + current = next; + } + + pnstr = spl_gen_private_prop_name(spl_ce_SplDoublyLinkedList, "dllist", sizeof("dllist")-1, &pnlen TSRMLS_CC); + add_u_assoc_zval_ex(&zrv, IS_UNICODE, pnstr, pnlen+1, dllist_array); + efree(pnstr.v); } - pnstr = spl_gen_private_prop_name(spl_ce_SplDoublyLinkedList, "dllist", sizeof("dllist")-1, &pnlen TSRMLS_CC); - add_u_assoc_zval_ex(&zrv, IS_UNICODE, pnstr, pnlen+1, dllist_array); - efree(pnstr.v); - - return rv; + return intern->debug_info; } /* }}}} */ Modified: php/php-src/trunk/ext/spl/spl_heap.c =================================================================== --- php/php-src/trunk/ext/spl/spl_heap.c 2009-08-13 20:19:31 UTC (rev 287265) +++ php/php-src/trunk/ext/spl/spl_heap.c 2009-08-13 22:07:05 UTC (rev 287266) @@ -76,6 +76,7 @@ zend_class_entry *ce_get_iterator; zend_function *fptr_cmp; zend_function *fptr_count; + HashTable *debug_info; }; /* define an overloaded iterator structure */ @@ -370,6 +371,12 @@ spl_ptr_heap_destroy(intern->heap TSRMLS_CC); zval_ptr_dtor(&intern->retval); + + if(intern->debug_info != NULL) { + zend_hash_destroy(intern->debug_info); + efree(intern->debug_info); + } + efree(object); } /* }}} */ @@ -389,8 +396,9 @@ zend_object_std_init(&intern->std, class_type TSRMLS_CC); zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); - intern->flags = 0; - intern->fptr_cmp = NULL; + intern->flags = 0; + intern->fptr_cmp = NULL; + intern->debug_info = NULL; if (orig) { spl_heap_object *other = (spl_heap_object*)zend_object_store_get_object(orig TSRMLS_CC); @@ -514,43 +522,46 @@ static HashTable* spl_heap_object_get_debug_info_helper(zend_class_entry *ce, zval *obj, int *is_temp TSRMLS_DC) { /* {{{ */ spl_heap_object *intern = (spl_heap_object*)zend_object_store_get_object(obj TSRMLS_CC); - HashTable *rv; zval *tmp, zrv, *heap_array; zstr pnstr; int pnlen; int i; - *is_temp = 1; + *is_temp = 0; - ALLOC_HASHTABLE(rv); - ZEND_INIT_SYMTABLE_EX(rv, zend_hash_num_elements(intern->std.properties) + 1, 0); + if (intern->debug_info == NULL) { + ALLOC_HASHTABLE(intern->debug_info); + ZEND_INIT_SYMTABLE_EX(intern->debug_info, zend_hash_num_elements(intern->std.properties) + 1, 0); + } - INIT_PZVAL(&zrv); - Z_ARRVAL(zrv) = rv; + if (intern->debug_info->nApplyCount == 0) { + INIT_PZVAL(&zrv); + Z_ARRVAL(zrv) = intern->debug_info; - zend_hash_copy(rv, intern->std.properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + zend_hash_copy(intern->debug_info, intern->std.properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); - pnstr = spl_gen_private_prop_name(ce, "flags", sizeof("flags")-1, &pnlen TSRMLS_CC); - add_u_assoc_long_ex(&zrv, IS_UNICODE, pnstr, pnlen+1, intern->flags); - efree(pnstr.v); + pnstr = spl_gen_private_prop_name(ce, "flags", sizeof("flags")-1, &pnlen TSRMLS_CC); + add_u_assoc_long_ex(&zrv, IS_UNICODE, pnstr, pnlen+1, intern->flags); + efree(pnstr.v); - pnstr = spl_gen_private_prop_name(ce, "isCorrupted", sizeof("isCorrupted")-1, &pnlen TSRMLS_CC); - add_u_assoc_bool_ex(&zrv, IS_UNICODE, pnstr, pnlen+1, intern->heap->flags&SPL_HEAP_CORRUPTED); - efree(pnstr.v); + pnstr = spl_gen_private_prop_name(ce, "isCorrupted", sizeof("isCorrupted")-1, &pnlen TSRMLS_CC); + add_u_assoc_bool_ex(&zrv, IS_UNICODE, pnstr, pnlen+1, intern->heap->flags&SPL_HEAP_CORRUPTED); + efree(pnstr.v); - ALLOC_INIT_ZVAL(heap_array); - array_init(heap_array); + ALLOC_INIT_ZVAL(heap_array); + array_init(heap_array); - for (i = 0; i < intern->heap->count; ++i) { - add_index_zval(heap_array, i, (zval *)intern->heap->elements[i]); - Z_ADDREF_P(intern->heap->elements[i]); + for (i = 0; i < intern->heap->count; ++i) { + add_index_zval(heap_array, i, (zval *)intern->heap->elements[i]); + Z_ADDREF_P(intern->heap->elements[i]); + } + + pnstr = spl_gen_private_prop_name(ce, "heap", sizeof("heap")-1, &pnlen TSRMLS_CC); + add_u_assoc_zval_ex(&zrv, IS_UNICODE, pnstr, pnlen+1, heap_array); + efree(pnstr.v); } - pnstr = spl_gen_private_prop_name(ce, "heap", sizeof("heap")-1, &pnlen TSRMLS_CC); - add_u_assoc_zval_ex(&zrv, IS_UNICODE, pnstr, pnlen+1, heap_array); - efree(pnstr.v); - - return rv; + return intern->debug_info; } /* }}} */ Modified: php/php-src/trunk/ext/spl/spl_observer.c =================================================================== --- php/php-src/trunk/ext/spl/spl_observer.c 2009-08-13 20:19:31 UTC (rev 287265) +++ php/php-src/trunk/ext/spl/spl_observer.c 2009-08-13 22:07:05 UTC (rev 287266) @@ -84,6 +84,7 @@ long index; HashPosition pos; long flags; + HashTable *debug_info; } spl_SplObjectStorage; /* }}} */ /* {{{ storage is an assoc aray of [zend_object_value]=>[zval *obj, zval *inf] */ @@ -100,6 +101,13 @@ zend_hash_destroy(&intern->storage); + if (intern->debug_info != NULL) { + zend_hash_destroy(intern->debug_info); + efree(intern->debug_info); + + } + + efree(object); } /* }}} */ @@ -239,42 +247,46 @@ { spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(obj TSRMLS_CC); spl_SplObjectStorageElement *element; - HashTable *rv, *props; + HashTable *props; HashPosition pos; zval *tmp, *storage; char md5str[33]; int name_len; zstr zname; - *is_temp = 1; + *is_temp = 0; props = Z_OBJPROP_P(obj); - ALLOC_HASHTABLE(rv); - ZEND_INIT_SYMTABLE_EX(rv, zend_hash_num_elements(props) + 1, 0); + if (intern->debug_info == NULL) { + ALLOC_HASHTABLE(intern->debug_info); + ZEND_INIT_SYMTABLE_EX(intern->debug_info, zend_hash_num_elements(props) + 1, 0); + } - zend_hash_copy(rv, props, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + if (intern->debug_info->nApplyCount == 0) { + zend_hash_copy(intern->debug_info, props, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); - MAKE_STD_ZVAL(storage); - array_init(storage); + MAKE_STD_ZVAL(storage); + array_init(storage); - zend_hash_internal_pointer_reset_ex(&intern->storage, &pos); - while (zend_hash_get_current_data_ex(&intern->storage, (void **)&element, &pos) == SUCCESS) { - php_spl_object_hash(element->obj, md5str TSRMLS_CC); - Z_ADDREF_P(element->obj); - Z_ADDREF_P(element->inf); - MAKE_STD_ZVAL(tmp); - array_init(tmp); - add_assoc_zval_ex(tmp, "obj", sizeof("obj"), element->obj); - add_assoc_zval_ex(tmp, "inf", sizeof("inf"), element->inf); - add_assoc_zval_ex(storage, md5str, 33, tmp); - zend_hash_move_forward_ex(&intern->storage, &pos); + zend_hash_internal_pointer_reset_ex(&intern->storage, &pos); + while (zend_hash_get_current_data_ex(&intern->storage, (void **)&element, &pos) == SUCCESS) { + php_spl_object_hash(element->obj, md5str TSRMLS_CC); + Z_ADDREF_P(element->obj); + Z_ADDREF_P(element->inf); + MAKE_STD_ZVAL(tmp); + array_init(tmp); + add_assoc_zval_ex(tmp, "obj", sizeof("obj"), element->obj); + add_assoc_zval_ex(tmp, "inf", sizeof("inf"), element->inf); + add_assoc_zval_ex(storage, md5str, 33, tmp); + zend_hash_move_forward_ex(&intern->storage, &pos); + } + + zname = spl_gen_private_prop_name(spl_ce_SplObjectStorage, "storage", sizeof("storage")-1, &name_len TSRMLS_CC); + zend_u_symtable_update(intern->debug_info, IS_UNICODE, zname, name_len+1, &storage, sizeof(zval *), NULL); + efree(zname.v); } - zname = spl_gen_private_prop_name(spl_ce_SplObjectStorage, "storage", sizeof("storage")-1, &name_len TSRMLS_CC); - zend_u_symtable_update(rv, IS_UNICODE, zname, name_len+1, &storage, sizeof(zval *), NULL); - efree(zname.v); - - return rv; + return intern->debug_info; } /* }}} */ Added: php/php-src/trunk/ext/spl/tests/SplObjectStorage_var_dump.phpt =================================================================== --- php/php-src/trunk/ext/spl/tests/SplObjectStorage_var_dump.phpt (rev 0) +++ php/php-src/trunk/ext/spl/tests/SplObjectStorage_var_dump.phpt 2009-08-13 22:07:05 UTC (rev 287266) @@ -0,0 +1,35 @@ +--TEST-- +SPL: SplObjectStorage: recursive var_dump +--FILE-- +<?php +$o = new SplObjectStorage(); + +$o[new StdClass] = $o; + +var_dump($o); +--EXPECTF-- +object(SplObjectStorage)#1 (1) { + [u"storage":u"SplObjectStorage":private]=> + array(1) { + ["%s"]=> + array(2) { + ["obj"]=> + object(stdClass)#2 (0) { + } + ["inf"]=> + object(SplObjectStorage)#1 (1) { + [u"storage":u"SplObjectStorage":private]=> + array(1) { + ["%s"]=> + array(2) { + ["obj"]=> + object(stdClass)#2 (0) { + } + ["inf"]=> + *RECURSION* + } + } + } + } + } +} Added: php/php-src/trunk/ext/spl/tests/array_027.phpt =================================================================== --- php/php-src/trunk/ext/spl/tests/array_027.phpt (rev 0) +++ php/php-src/trunk/ext/spl/tests/array_027.phpt 2009-08-13 22:07:05 UTC (rev 287266) @@ -0,0 +1,24 @@ +--TEST-- +SPL: ArrayObject revursive var_dump +--FILE-- +<?php +class AO extends ArrayObject { +} +$o = new AO(); +$o['plop'] = $o; + +var_dump($o); +--EXPECTF-- +object(AO)#1 (1) { + [u"storage":u"ArrayObject":private]=> + array(1) { + [u"plop"]=> + object(AO)#1 (1) { + [u"storage":u"ArrayObject":private]=> + array(1) { + [u"plop"]=> + *RECURSION* + } + } + } +} Added: php/php-src/trunk/ext/spl/tests/dllist_012.phpt =================================================================== --- php/php-src/trunk/ext/spl/tests/dllist_012.phpt (rev 0) +++ php/php-src/trunk/ext/spl/tests/dllist_012.phpt 2009-08-13 22:07:05 UTC (rev 287266) @@ -0,0 +1,29 @@ +--TEST-- +SPL: DoublyLinkedList: recursive var_dump +--FILE-- +<?php +$a = new SplDoublyLinkedList; +$a[] = $a; + +var_dump($a); +?> +===DONE=== +--EXPECT-- +object(SplDoublyLinkedList)#1 (2) { + [u"flags":u"SplDoublyLinkedList":private]=> + int(0) + [u"dllist":u"SplDoublyLinkedList":private]=> + array(1) { + [0]=> + object(SplDoublyLinkedList)#1 (2) { + [u"flags":u"SplDoublyLinkedList":private]=> + int(0) + [u"dllist":u"SplDoublyLinkedList":private]=> + array(1) { + [0]=> + *RECURSION* + } + } + } +} +===DONE=== Added: php/php-src/trunk/ext/spl/tests/heap_012.phpt =================================================================== --- php/php-src/trunk/ext/spl/tests/heap_012.phpt (rev 0) +++ php/php-src/trunk/ext/spl/tests/heap_012.phpt 2009-08-13 22:07:05 UTC (rev 287266) @@ -0,0 +1,32 @@ +--TEST-- +SPL: SplHeap recursive var_dump +--FILE-- +<?php +$a = new SplMaxHeap; +$a->insert($a); +var_dump($a) +?> +===DONE=== +--EXPECT-- +object(SplMaxHeap)#1 (3) { + [u"flags":u"SplHeap":private]=> + int(0) + [u"isCorrupted":u"SplHeap":private]=> + bool(false) + [u"heap":u"SplHeap":private]=> + array(1) { + [0]=> + object(SplMaxHeap)#1 (3) { + [u"flags":u"SplHeap":private]=> + int(0) + [u"isCorrupted":u"SplHeap":private]=> + bool(false) + [u"heap":u"SplHeap":private]=> + array(1) { + [0]=> + *RECURSION* + } + } + } +} +===DONE===
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php