Skip to content

Commit dc764bf

Browse files
committed
Use object apply count in var_dump / print_r
Instead of using the array apply count on the debug_info array, use the object apply count for recursion detection when dumping. This handles recursion in a more generic way and does not require each debug_info handler to deal with this. This allows returning a temporary debug_info array, instead of having to store it in the object (thus delaying destruction of the values). Switch SPL debug_info handlers to use a temporary array.
1 parent 3dcad2e commit dc764bf

File tree

6 files changed

+102
-143
lines changed

6 files changed

+102
-143
lines changed

Zend/zend.c

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -296,17 +296,18 @@ ZEND_API void zend_print_flat_zval_r(zval *expr) /* {{{ */
296296
zend_printf("%s Object (", class_name->val);
297297
zend_string_release(class_name);
298298

299+
if (Z_OBJ_APPLY_COUNT_P(expr) > 0) {
300+
ZEND_PUTS(" *RECURSION*");
301+
return;
302+
}
303+
299304
if (Z_OBJ_HANDLER_P(expr, get_properties)) {
300305
properties = Z_OBJPROP_P(expr);
301306
}
302307
if (properties) {
303-
if (++properties->u.v.nApplyCount>1) {
304-
ZEND_PUTS(" *RECURSION*");
305-
properties->u.v.nApplyCount--;
306-
return;
307-
}
308+
Z_OBJ_INC_APPLY_COUNT_P(expr);
308309
print_flat_hash(properties);
309-
properties->u.v.nApplyCount--;
310+
Z_OBJ_DEC_APPLY_COUNT_P(expr);
310311
}
311312
ZEND_PUTS(")");
312313
break;
@@ -351,16 +352,18 @@ ZEND_API void zend_print_zval_r_ex(zend_write_func_t write_func, zval *expr, int
351352
zend_string_release(class_name);
352353

353354
ZEND_PUTS_EX(" Object\n");
354-
if ((properties = Z_OBJDEBUG_P(expr, is_temp)) == NULL) {
355-
break;
356-
}
357-
if (++properties->u.v.nApplyCount>1) {
355+
if (Z_OBJ_APPLY_COUNT_P(expr) > 0) {
358356
ZEND_PUTS_EX(" *RECURSION*");
359-
properties->u.v.nApplyCount--;
360357
return;
361358
}
359+
if ((properties = Z_OBJDEBUG_P(expr, is_temp)) == NULL) {
360+
break;
361+
}
362+
363+
Z_OBJ_INC_APPLY_COUNT_P(expr);
362364
print_hash(write_func, properties, indent, 1);
363-
properties->u.v.nApplyCount--;
365+
Z_OBJ_DEC_APPLY_COUNT_P(expr);
366+
364367
if (is_temp) {
365368
zend_hash_destroy(properties);
366369
FREE_HASHTABLE(properties);

ext/spl/spl_array.c

Lines changed: 14 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ typedef struct _spl_array_object {
7373
zend_function *fptr_offset_del;
7474
zend_function *fptr_count;
7575
zend_class_entry* ce_get_iterator;
76-
HashTable *debug_info;
7776
unsigned char nApplyCount;
7877
zend_object std;
7978
} spl_array_object;
@@ -131,11 +130,6 @@ static void spl_array_object_free_storage(zend_object *object)
131130
zend_object_std_dtor(&intern->std);
132131

133132
zval_ptr_dtor(&intern->array);
134-
135-
if (intern->debug_info != NULL) {
136-
zend_hash_destroy(intern->debug_info);
137-
efree(intern->debug_info);
138-
}
139133
}
140134
/* }}} */
141135

@@ -154,7 +148,6 @@ static zend_object *spl_array_object_new_ex(zend_class_entry *class_type, zval *
154148
object_properties_init(&intern->std, class_type);
155149

156150
intern->ar_flags = 0;
157-
intern->debug_info = NULL;
158151
intern->ce_get_iterator = spl_ce_ArrayIterator;
159152
if (orig) {
160153
spl_array_object *other = Z_SPLARRAY_P(orig);
@@ -806,34 +799,31 @@ static HashTable* spl_array_get_debug_info(zval *obj, int *is_temp) /* {{{ */
806799
zend_class_entry *base;
807800
spl_array_object *intern = Z_SPLARRAY_P(obj);
808801

809-
*is_temp = 0;
810-
811802
if (!intern->std.properties) {
812803
rebuild_object_properties(&intern->std);
813804
}
814805

815806
if (HASH_OF(&intern->array) == intern->std.properties) {
807+
*is_temp = 0;
816808
return intern->std.properties;
817809
} else {
818-
if (intern->debug_info == NULL) {
819-
ALLOC_HASHTABLE(intern->debug_info);
820-
ZEND_INIT_SYMTABLE_EX(intern->debug_info, zend_hash_num_elements(intern->std.properties) + 1, 0);
821-
}
810+
HashTable *debug_info;
811+
*is_temp = 1;
822812

823-
if (intern->debug_info->u.v.nApplyCount == 0) {
824-
zend_hash_clean(intern->debug_info);
825-
zend_hash_copy(intern->debug_info, intern->std.properties, (copy_ctor_func_t) zval_add_ref);
813+
ALLOC_HASHTABLE(debug_info);
814+
ZEND_INIT_SYMTABLE_EX(debug_info, zend_hash_num_elements(intern->std.properties) + 1, 0);
815+
zend_hash_copy(debug_info, intern->std.properties, (copy_ctor_func_t) zval_add_ref);
826816

827-
storage = &intern->array;
828-
Z_TRY_ADDREF_P(storage);
817+
storage = &intern->array;
818+
Z_TRY_ADDREF_P(storage);
829819

830-
base = (Z_OBJ_HT_P(obj) == &spl_handler_ArrayIterator) ? spl_ce_ArrayIterator : spl_ce_ArrayObject;
831-
zname = spl_gen_private_prop_name(base, "storage", sizeof("storage")-1);
832-
zend_symtable_update(intern->debug_info, zname, storage);
833-
zend_string_release(zname);
834-
}
820+
base = Z_OBJ_HT_P(obj) == &spl_handler_ArrayIterator
821+
? spl_ce_ArrayIterator : spl_ce_ArrayObject;
822+
zname = spl_gen_private_prop_name(base, "storage", sizeof("storage")-1);
823+
zend_symtable_update(debug_info, zname, storage);
824+
zend_string_release(zname);
835825

836-
return intern->debug_info;
826+
return debug_info;
837827
}
838828
}
839829
/* }}} */

ext/spl/spl_dllist.c

Lines changed: 24 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ struct _spl_dllist_object {
9393
zend_function *fptr_offset_del;
9494
zend_function *fptr_count;
9595
zend_class_entry *ce_get_iterator;
96-
HashTable *debug_info;
9796
zend_object std;
9897
};
9998

@@ -357,11 +356,6 @@ static void spl_dllist_object_free_storage(zend_object *object) /* {{{ */
357356

358357
spl_ptr_llist_destroy(intern->llist);
359358
SPL_LLIST_CHECK_DELREF(intern->traverse_pointer);
360-
361-
if (intern->debug_info != NULL) {
362-
zend_hash_destroy(intern->debug_info);
363-
efree(intern->debug_info);
364-
}
365359
}
366360
/* }}} */
367361

@@ -380,7 +374,6 @@ static zend_object *spl_dllist_object_new_ex(zend_class_entry *class_type, zval
380374

381375
intern->flags = 0;
382376
intern->traverse_position = 0;
383-
intern->debug_info = NULL;
384377

385378
if (orig) {
386379
spl_dllist_object *other = Z_SPLDLLIST_P(orig);
@@ -500,46 +493,41 @@ static HashTable* spl_dllist_object_get_debug_info(zval *obj, int *is_temp) /* {
500493
zval tmp, dllist_array;
501494
zend_string *pnstr;
502495
int i = 0;
496+
HashTable *debug_info;
497+
*is_temp = 1;
503498

504-
*is_temp = 0;
505-
506-
if (intern->debug_info == NULL) {
507-
ALLOC_HASHTABLE(intern->debug_info);
508-
zend_hash_init(intern->debug_info, 1, NULL, ZVAL_PTR_DTOR, 0);
499+
if (!intern->std.properties) {
500+
rebuild_object_properties(&intern->std);
509501
}
510502

511-
if (intern->debug_info->u.v.nApplyCount == 0) {
512-
513-
if (!intern->std.properties) {
514-
rebuild_object_properties(&intern->std);
515-
}
516-
zend_hash_copy(intern->debug_info, intern->std.properties, (copy_ctor_func_t) zval_add_ref);
517-
518-
pnstr = spl_gen_private_prop_name(spl_ce_SplDoublyLinkedList, "flags", sizeof("flags")-1);
519-
ZVAL_LONG(&tmp, intern->flags);
520-
zend_hash_add(intern->debug_info, pnstr, &tmp);
521-
zend_string_release(pnstr);
503+
ALLOC_HASHTABLE(debug_info);
504+
zend_hash_init(debug_info, 1, NULL, ZVAL_PTR_DTOR, 0);
505+
zend_hash_copy(debug_info, intern->std.properties, (copy_ctor_func_t) zval_add_ref);
522506

523-
array_init(&dllist_array);
507+
pnstr = spl_gen_private_prop_name(spl_ce_SplDoublyLinkedList, "flags", sizeof("flags")-1);
508+
ZVAL_LONG(&tmp, intern->flags);
509+
zend_hash_add(debug_info, pnstr, &tmp);
510+
zend_string_release(pnstr);
524511

525-
while (current) {
526-
next = current->next;
512+
array_init(&dllist_array);
527513

528-
add_index_zval(&dllist_array, i, &current->data);
529-
if (Z_REFCOUNTED(current->data)) {
530-
Z_ADDREF(current->data);
531-
}
532-
i++;
514+
while (current) {
515+
next = current->next;
533516

534-
current = next;
517+
add_index_zval(&dllist_array, i, &current->data);
518+
if (Z_REFCOUNTED(current->data)) {
519+
Z_ADDREF(current->data);
535520
}
521+
i++;
536522

537-
pnstr = spl_gen_private_prop_name(spl_ce_SplDoublyLinkedList, "dllist", sizeof("dllist")-1);
538-
zend_hash_add(intern->debug_info, pnstr, &dllist_array);
539-
zend_string_release(pnstr);
523+
current = next;
540524
}
541525

542-
return intern->debug_info;
526+
pnstr = spl_gen_private_prop_name(spl_ce_SplDoublyLinkedList, "dllist", sizeof("dllist")-1);
527+
zend_hash_add(debug_info, pnstr, &dllist_array);
528+
zend_string_release(pnstr);
529+
530+
return debug_info;
543531
}
544532
/* }}}} */
545533

ext/spl/spl_heap.c

Lines changed: 23 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ struct _spl_heap_object {
7373
zend_class_entry *ce_get_iterator;
7474
zend_function *fptr_cmp;
7575
zend_function *fptr_count;
76-
HashTable *debug_info;
7776
zend_object std;
7877
};
7978

@@ -369,11 +368,6 @@ static void spl_heap_object_free_storage(zend_object *object) /* {{{ */
369368
}
370369

371370
spl_ptr_heap_destroy(intern->heap);
372-
373-
if (intern->debug_info != NULL) {
374-
zend_hash_destroy(intern->debug_info);
375-
efree(intern->debug_info);
376-
}
377371
}
378372
/* }}} */
379373

@@ -390,7 +384,6 @@ static zend_object *spl_heap_object_new_ex(zend_class_entry *class_type, zval *o
390384

391385
intern->flags = 0;
392386
intern->fptr_cmp = NULL;
393-
intern->debug_info = NULL;
394387

395388
if (orig) {
396389
spl_heap_object *other = Z_SPLHEAP_P(orig);
@@ -506,48 +499,43 @@ static HashTable* spl_heap_object_get_debug_info_helper(zend_class_entry *ce, zv
506499
spl_heap_object *intern = Z_SPLHEAP_P(obj);
507500
zval tmp, heap_array;
508501
zend_string *pnstr;
502+
HashTable *debug_info;
509503
int i;
510504

511-
*is_temp = 0;
505+
*is_temp = 1;
512506

513507
if (!intern->std.properties) {
514508
rebuild_object_properties(&intern->std);
515509
}
516510

517-
if (intern->debug_info == NULL) {
518-
ALLOC_HASHTABLE(intern->debug_info);
519-
ZEND_INIT_SYMTABLE_EX(intern->debug_info, zend_hash_num_elements(intern->std.properties) + 1, 0);
520-
}
521-
522-
if (intern->debug_info->u.v.nApplyCount == 0) {
523-
524-
zend_hash_copy(intern->debug_info, intern->std.properties, (copy_ctor_func_t) zval_add_ref);
511+
ALLOC_HASHTABLE(debug_info);
512+
ZEND_INIT_SYMTABLE_EX(debug_info, zend_hash_num_elements(intern->std.properties) + 1, 0);
513+
zend_hash_copy(debug_info, intern->std.properties, (copy_ctor_func_t) zval_add_ref);
525514

526-
pnstr = spl_gen_private_prop_name(ce, "flags", sizeof("flags")-1);
527-
ZVAL_LONG(&tmp, intern->flags);
528-
zend_hash_update(intern->debug_info, pnstr, &tmp);
529-
zend_string_release(pnstr);
515+
pnstr = spl_gen_private_prop_name(ce, "flags", sizeof("flags")-1);
516+
ZVAL_LONG(&tmp, intern->flags);
517+
zend_hash_update(debug_info, pnstr, &tmp);
518+
zend_string_release(pnstr);
530519

531-
pnstr = spl_gen_private_prop_name(ce, "isCorrupted", sizeof("isCorrupted")-1);
532-
ZVAL_BOOL(&tmp, intern->heap->flags&SPL_HEAP_CORRUPTED);
533-
zend_hash_update(intern->debug_info, pnstr, &tmp);
534-
zend_string_release(pnstr);
520+
pnstr = spl_gen_private_prop_name(ce, "isCorrupted", sizeof("isCorrupted")-1);
521+
ZVAL_BOOL(&tmp, intern->heap->flags&SPL_HEAP_CORRUPTED);
522+
zend_hash_update(debug_info, pnstr, &tmp);
523+
zend_string_release(pnstr);
535524

536-
array_init(&heap_array);
525+
array_init(&heap_array);
537526

538-
for (i = 0; i < intern->heap->count; ++i) {
539-
add_index_zval(&heap_array, i, &intern->heap->elements[i]);
540-
if (Z_REFCOUNTED(intern->heap->elements[i])) {
541-
Z_ADDREF(intern->heap->elements[i]);
542-
}
527+
for (i = 0; i < intern->heap->count; ++i) {
528+
add_index_zval(&heap_array, i, &intern->heap->elements[i]);
529+
if (Z_REFCOUNTED(intern->heap->elements[i])) {
530+
Z_ADDREF(intern->heap->elements[i]);
543531
}
544-
545-
pnstr = spl_gen_private_prop_name(ce, "heap", sizeof("heap")-1);
546-
zend_hash_update(intern->debug_info, pnstr, &heap_array);
547-
zend_string_release(pnstr);
548532
}
549533

550-
return intern->debug_info;
534+
pnstr = spl_gen_private_prop_name(ce, "heap", sizeof("heap")-1);
535+
zend_hash_update(debug_info, pnstr, &heap_array);
536+
zend_string_release(pnstr);
537+
538+
return debug_info;
551539
}
552540
/* }}} */
553541

0 commit comments

Comments
 (0)