@@ -85,6 +85,8 @@ typedef struct _spl_sub_iterator {
85
85
zval zobject ;
86
86
zend_class_entry * ce ;
87
87
RecursiveIteratorState state ;
88
+ zend_function * haschildren ;
89
+ zend_function * getchildren ;
88
90
} spl_sub_iterator ;
89
91
90
92
typedef struct _spl_recursive_it_object {
@@ -222,7 +224,6 @@ static void spl_recursive_it_get_current_key(zend_object_iterator *iter, zval *k
222
224
static void spl_recursive_it_move_forward_ex (spl_recursive_it_object * object , zval * zthis )
223
225
{
224
226
zend_object_iterator * iterator ;
225
- zval * zobject ;
226
227
zend_class_entry * ce ;
227
228
zval retval , child ;
228
229
zend_object_iterator * sub_iter ;
@@ -251,12 +252,14 @@ static void spl_recursive_it_move_forward_ex(spl_recursive_it_object *object, zv
251
252
object -> iterators [object -> level ].state = RS_TEST ;
252
253
/* break; */
253
254
case RS_TEST :
254
- ce = object -> iterators [object -> level ].ce ;
255
- zobject = & object -> iterators [object -> level ].zobject ;
256
255
if (object -> callHasChildren ) {
257
256
zend_call_method_with_0_params (Z_OBJ_P (zthis ), object -> ce , & object -> callHasChildren , "callHasChildren" , & retval );
258
257
} else {
259
- zend_call_method_with_0_params (Z_OBJ_P (zobject ), ce , NULL , "haschildren" , & retval );
258
+ zend_class_entry * ce = object -> iterators [object -> level ].ce ;
259
+ zend_object * obj = Z_OBJ (object -> iterators [object -> level ].zobject );
260
+ zend_function * * cache = & object -> iterators [object -> level ].haschildren ;
261
+
262
+ zend_call_method_with_0_params (obj , ce , cache , "haschildren" , & retval );
260
263
}
261
264
if (EG (exception )) {
262
265
if (!(object -> flags & RIT_CATCH_GET_CHILD )) {
@@ -313,12 +316,14 @@ static void spl_recursive_it_move_forward_ex(spl_recursive_it_object *object, zv
313
316
}
314
317
return /* self */ ;
315
318
case RS_CHILD :
316
- ce = object -> iterators [object -> level ].ce ;
317
- zobject = & object -> iterators [object -> level ].zobject ;
318
319
if (object -> callGetChildren ) {
319
320
zend_call_method_with_0_params (Z_OBJ_P (zthis ), object -> ce , & object -> callGetChildren , "callGetChildren" , & child );
320
321
} else {
321
- zend_call_method_with_0_params (Z_OBJ_P (zobject ), ce , NULL , "getchildren" , & child );
322
+ zend_class_entry * ce = object -> iterators [object -> level ].ce ;
323
+ zend_object * obj = Z_OBJ (object -> iterators [object -> level ].zobject );
324
+ zend_function * * cache = & object -> iterators [object -> level ].getchildren ;
325
+
326
+ zend_call_method_with_0_params (obj , ce , cache , "getchildren" , & child );
322
327
}
323
328
324
329
if (EG (exception )) {
@@ -350,6 +355,16 @@ static void spl_recursive_it_move_forward_ex(spl_recursive_it_object *object, zv
350
355
object -> iterators [object -> level ].iterator = sub_iter ;
351
356
object -> iterators [object -> level ].ce = ce ;
352
357
object -> iterators [object -> level ].state = RS_START ;
358
+ if (object -> level > 0
359
+ && object -> iterators [object -> level - 1 ].ce == 0 ) {
360
+ object -> iterators [object -> level ].haschildren =
361
+ object -> iterators [object -> level - 1 ].haschildren ;
362
+ object -> iterators [object -> level ].getchildren =
363
+ object -> iterators [object -> level - 1 ].getchildren ;
364
+ } else {
365
+ object -> iterators [object -> level ].haschildren = NULL ;
366
+ object -> iterators [object -> level ].getchildren = NULL ;
367
+ }
353
368
if (sub_iter -> funcs -> rewind ) {
354
369
sub_iter -> funcs -> rewind (sub_iter );
355
370
}
@@ -572,6 +587,8 @@ static void spl_recursive_it_it_construct(INTERNAL_FUNCTION_PARAMETERS, zend_cla
572
587
ZVAL_OBJ (& intern -> iterators [0 ].zobject , Z_OBJ_P (iterator ));
573
588
intern -> iterators [0 ].ce = ce_iterator ;
574
589
intern -> iterators [0 ].state = RS_START ;
590
+ intern -> iterators [0 ].haschildren = NULL ;
591
+ intern -> iterators [0 ].getchildren = NULL ;
575
592
576
593
zend_restore_error_handling (& error_handling );
577
594
@@ -761,7 +778,7 @@ PHP_METHOD(RecursiveIteratorIterator, callHasChildren)
761
778
if (Z_TYPE_P (zobject ) == IS_UNDEF ) {
762
779
RETURN_FALSE ;
763
780
} else {
764
- zend_call_method_with_0_params (Z_OBJ_P (zobject ), ce , NULL , "haschildren" , return_value );
781
+ zend_call_method_with_0_params (Z_OBJ_P (zobject ), ce , & object -> iterators [ object -> level ]. haschildren , "haschildren" , return_value );
765
782
if (Z_TYPE_P (return_value ) == IS_UNDEF ) {
766
783
RETURN_FALSE ;
767
784
}
@@ -785,7 +802,7 @@ PHP_METHOD(RecursiveIteratorIterator, callGetChildren)
785
802
if (Z_TYPE_P (zobject ) == IS_UNDEF ) {
786
803
return ;
787
804
} else {
788
- zend_call_method_with_0_params (Z_OBJ_P (zobject ), ce , NULL , "getchildren" , return_value );
805
+ zend_call_method_with_0_params (Z_OBJ_P (zobject ), ce , & object -> iterators [ object -> level ]. getchildren , "getchildren" , return_value );
789
806
if (Z_TYPE_P (return_value ) == IS_UNDEF ) {
790
807
RETURN_NULL ();
791
808
}
0 commit comments