Skip to content

Commit 1265850

Browse files
committed
Add zend_iterator_dtor
1 parent a5ce7d5 commit 1265850

File tree

5 files changed

+60
-49
lines changed

5 files changed

+60
-49
lines changed

Zend/zend_iterators.c

+9
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,15 @@ ZEND_API void zend_iterator_init(zend_object_iterator *iter TSRMLS_DC)
7171
iter->std.handlers = &iterator_object_handlers;
7272
}
7373

74+
ZEND_API void zend_iterator_dtor(zend_object_iterator *iter TSRMLS_DC)
75+
{
76+
if (--iter->std.gc.refcount > 0) {
77+
return;
78+
}
79+
80+
zend_objects_store_del(&iter->std TSRMLS_CC);
81+
}
82+
7483
ZEND_API enum zend_object_iterator_kind zend_iterator_unwrap(
7584
zval *array_ptr, zend_object_iterator **iter TSRMLS_DC)
7685
{

Zend/zend_iterators.h

+1
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ ZEND_API enum zend_object_iterator_kind zend_iterator_unwrap(zval *array_ptr, ze
8484

8585
/* given an iterator, wrap it up as a zval for use by the engine opcodes */
8686
ZEND_API void zend_iterator_init(zend_object_iterator *iter TSRMLS_DC);
87+
ZEND_API void zend_iterator_dtor(zend_object_iterator *iter TSRMLS_DC);
8788

8889
ZEND_API void zend_register_iterator_wrapper(TSRMLS_D);
8990
END_EXTERN_C()

ext/spl/spl_directory.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ static void spl_filesystem_object_free_storage(zend_object *object TSRMLS_DC) /*
129129
spl_filesystem_object_to_iterator(intern);
130130
if (!ZVAL_IS_UNDEF(&iterator->data)) {
131131
ZVAL_UNDEF(&iterator->data);
132-
iterator->funcs->dtor(iterator TSRMLS_CC);
132+
zend_iterator_dtor(iterator TSRMLS_CC);
133133
}
134134
}
135135
efree(object);

ext/spl/spl_iterators.c

+48-47
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ static void spl_recursive_it_dtor(zend_object_iterator *_iter TSRMLS_DC)
146146

147147
while (object->level > 0) {
148148
sub_iter = object->iterators[object->level].iterator;
149-
sub_iter->funcs->dtor(sub_iter TSRMLS_CC);
149+
zend_iterator_dtor(sub_iter TSRMLS_CC);
150150
zval_ptr_dtor(&object->iterators[object->level--].zobject);
151151
}
152152
object->iterators = erealloc(object->iterators, sizeof(spl_sub_iterator));
@@ -161,7 +161,7 @@ static int spl_recursive_it_valid_ex(spl_recursive_it_object *object, zval *zthi
161161
zend_object_iterator *sub_iter;
162162
int level = object->level;
163163

164-
while (level >=0) {
164+
while (level >= 0) {
165165
sub_iter = object->iterators[level].iterator;
166166
if (sub_iter->funcs->valid(sub_iter TSRMLS_CC) == SUCCESS) {
167167
return SUCCESS;
@@ -357,7 +357,7 @@ static void spl_recursive_it_move_forward_ex(spl_recursive_it_object *object, zv
357357
}
358358
}
359359
}
360-
iterator->funcs->dtor(iterator TSRMLS_CC);
360+
zend_iterator_dtor(iterator TSRMLS_CC);
361361
zval_ptr_dtor(&object->iterators[object->level].zobject);
362362
object->level--;
363363
} else {
@@ -376,7 +376,7 @@ static void spl_recursive_it_rewind_ex(spl_recursive_it_object *object, zval *zt
376376

377377
while (object->level) {
378378
sub_iter = object->iterators[object->level].iterator;
379-
sub_iter->funcs->dtor(sub_iter TSRMLS_CC);
379+
zend_iterator_dtor(sub_iter TSRMLS_CC);
380380
zval_ptr_dtor(&object->iterators[object->level--].zobject);
381381
if (!EG(exception) && (!object->endChildren || object->endChildren->common.scope != spl_ce_RecursiveIteratorIterator)) {
382382
zend_call_method_with_0_params(zthis, object->ce, &object->endChildren, "endchildren", NULL);
@@ -438,17 +438,17 @@ zend_object_iterator_funcs spl_recursive_it_iterator_funcs = {
438438

439439
static void spl_recursive_it_it_construct(INTERNAL_FUNCTION_PARAMETERS, zend_class_entry *ce_base, zend_class_entry *ce_inner, recursive_it_it_type rit_type)
440440
{
441-
zval *object = getThis();
442-
spl_recursive_it_object *intern;
443-
zval *iterator;
444-
zend_class_entry *ce_iterator;
445-
long mode, flags;
446-
int inc_refcount = 1;
447-
zend_error_handling error_handling;
441+
zval *object = getThis();
442+
spl_recursive_it_object *intern;
443+
zval *iterator;
444+
zend_class_entry *ce_iterator;
445+
long mode, flags;
446+
int inc_refcount = 1;
447+
zend_error_handling error_handling;
448448

449449
zend_replace_error_handling(EH_THROW, spl_ce_InvalidArgumentException, &error_handling TSRMLS_CC);
450450

451-
switch(rit_type) {
451+
switch (rit_type) {
452452
case RIT_RecursiveTreeIterator: {
453453

454454
zval caching_it, caching_it_flags, *user_caching_it_flags = NULL;
@@ -542,12 +542,14 @@ static void spl_recursive_it_it_construct(INTERNAL_FUNCTION_PARAMETERS, zend_cla
542542
if (intern->nextElement->common.scope == ce_base) {
543543
intern->nextElement = NULL;
544544
}
545+
545546
ce_iterator = Z_OBJCE_P(iterator); /* respect inheritance, don't use spl_ce_RecursiveIterator */
546547
intern->iterators[0].iterator = ce_iterator->get_iterator(ce_iterator, iterator, 0 TSRMLS_CC);
547548
if (inc_refcount) {
548-
Z_ADDREF_P(iterator);
549+
ZVAL_COPY(&intern->iterators[0].zobject, iterator);
550+
} else {
551+
ZVAL_COPY_VALUE(&intern->iterators[0].zobject, iterator);
549552
}
550-
intern->iterators[0].zobject = *iterator;
551553
intern->iterators[0].ce = ce_iterator;
552554
intern->iterators[0].state = RS_START;
553555

@@ -558,7 +560,7 @@ static void spl_recursive_it_it_construct(INTERNAL_FUNCTION_PARAMETERS, zend_cla
558560

559561
while (intern->level >= 0) {
560562
sub_iter = intern->iterators[intern->level].iterator;
561-
sub_iter->funcs->dtor(sub_iter TSRMLS_CC);
563+
zend_iterator_dtor(sub_iter TSRMLS_CC);
562564
zval_ptr_dtor(&intern->iterators[intern->level--].zobject);
563565
}
564566
efree(intern->iterators);
@@ -857,7 +859,7 @@ static void spl_RecursiveIteratorIterator_dtor(zend_object *_object TSRMLS_DC)
857859
if (object->iterators) {
858860
while (object->level >= 0) {
859861
sub_iter = object->iterators[object->level].iterator;
860-
sub_iter->funcs->dtor(sub_iter TSRMLS_CC);
862+
zend_iterator_dtor(sub_iter TSRMLS_CC);
861863
zval_ptr_dtor(&object->iterators[object->level--].zobject);
862864
}
863865
efree(object->iterators);
@@ -1282,14 +1284,14 @@ static union _zend_function *spl_dual_it_get_method(zval *object_ptr, zend_strin
12821284
function_handler = std_object_handlers.get_method(object_ptr, method, key TSRMLS_CC);
12831285
if (!function_handler && intern->inner.ce) {
12841286
if ((function_handler = zend_hash_find_ptr(&intern->inner.ce->function_table, method)) == NULL) {
1285-
if (Z_OBJ_HT_P(intern->inner.zobject)->get_method) {
1287+
if (Z_OBJ_HT(intern->inner.zobject)->get_method) {
12861288
//!!! maybe we really need a zval ** here?
12871289
//*object_ptr = &intern->inner.zobject?
1288-
object_ptr = intern->inner.zobject;
1290+
object_ptr = &intern->inner.zobject;
12891291
function_handler = Z_OBJ_HT_P(object_ptr)->get_method(object_ptr, method, key TSRMLS_CC);
12901292
}
12911293
} else {
1292-
object_ptr = intern->inner.zobject;
1294+
object_ptr = &intern->inner.zobject;
12931295
}
12941296
}
12951297
return function_handler;
@@ -1519,9 +1521,11 @@ static spl_dual_it_object* spl_dual_it_construct(INTERNAL_FUNCTION_PARAMETERS, z
15191521
zend_restore_error_handling(&error_handling TSRMLS_CC);
15201522

15211523
if (inc_refcount) {
1522-
Z_ADDREF_P(zobject);
1524+
ZVAL_COPY(&intern->inner.zobject, zobject);
1525+
} else {
1526+
ZVAL_COPY_VALUE(&intern->inner.zobject, zobject);
15231527
}
1524-
intern->inner.zobject = zobject;
1528+
15251529
intern->inner.ce = dit_type == DIT_IteratorIterator ? ce : Z_OBJCE_P(zobject);
15261530
intern->inner.object = Z_OBJ_P(zobject);
15271531
intern->inner.iterator = intern->inner.ce->get_iterator(intern->inner.ce, zobject, 0 TSRMLS_CC);
@@ -1558,8 +1562,8 @@ SPL_METHOD(dual_it, getInnerIterator)
15581562

15591563
SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis());
15601564

1561-
if (intern->inner.zobject) {
1562-
RETVAL_ZVAL(intern->inner.zobject, 1, 0);
1565+
if (!ZVAL_IS_UNDEF(&intern->inner.zobject)) {
1566+
RETVAL_ZVAL(&intern->inner.zobject, 1, 0);
15631567
} else {
15641568
RETURN_NULL();
15651569
}
@@ -1843,7 +1847,7 @@ SPL_METHOD(RecursiveFilterIterator, hasChildren)
18431847

18441848
SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis());
18451849

1846-
zend_call_method_with_0_params(intern->inner.zobject, intern->inner.ce, NULL, "haschildren", &retval);
1850+
zend_call_method_with_0_params(&intern->inner.zobject, intern->inner.ce, NULL, "haschildren", &retval);
18471851
if (Z_TYPE(retval) != IS_UNDEF) {
18481852
RETURN_ZVAL(&retval, 0, 1);
18491853
} else {
@@ -1864,7 +1868,7 @@ SPL_METHOD(RecursiveFilterIterator, getChildren)
18641868

18651869
SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis());
18661870

1867-
zend_call_method_with_0_params(intern->inner.zobject, intern->inner.ce, NULL, "getchildren", &retval);
1871+
zend_call_method_with_0_params(&intern->inner.zobject, intern->inner.ce, NULL, "getchildren", &retval);
18681872
if (!EG(exception) && Z_TYPE(retval) != IS_UNDEF) {
18691873
spl_instantiate_arg_ex1(Z_OBJCE_P(getThis()), return_value, &retval TSRMLS_CC);
18701874
}
@@ -1884,7 +1888,7 @@ SPL_METHOD(RecursiveCallbackFilterIterator, getChildren)
18841888

18851889
intern = (spl_dual_it_object*)Z_OBJ_P(getThis());
18861890

1887-
zend_call_method_with_0_params(intern->inner.zobject, intern->inner.ce, NULL, "getchildren", &retval);
1891+
zend_call_method_with_0_params(&intern->inner.zobject, intern->inner.ce, NULL, "getchildren", &retval);
18881892
if (!EG(exception) && Z_TYPE(retval) != IS_UNDEF) {
18891893
spl_instantiate_arg_ex2(Z_OBJCE_P(getThis()), return_value, &retval, &intern->u.cbfilter->fci.function_name TSRMLS_CC);
18901894
}
@@ -1925,7 +1929,7 @@ SPL_METHOD(CallbackFilterIterator, accept)
19251929

19261930
ZVAL_COPY_VALUE(&params[0], &intern->current.data);
19271931
ZVAL_COPY_VALUE(&params[1], &intern->current.key);
1928-
ZVAL_COPY_VALUE(&params[2], intern->inner.zobject);
1932+
ZVAL_COPY_VALUE(&params[2], &intern->inner.zobject);
19291933

19301934
fci->retval = &result;
19311935
fci->param_count = 3;
@@ -2181,7 +2185,7 @@ SPL_METHOD(RecursiveRegexIterator, getChildren)
21812185

21822186
SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis());
21832187

2184-
zend_call_method_with_0_params(intern->inner.zobject, intern->inner.ce, NULL, "getchildren", &retval);
2188+
zend_call_method_with_0_params(&intern->inner.zobject, intern->inner.ce, NULL, "getchildren", &retval);
21852189
if (!EG(exception)) {
21862190
ZVAL_STR(&regex, STR_COPY(intern->u.regex.regex));
21872191
spl_instantiate_arg_ex2(Z_OBJCE_P(getThis()), return_value, &retval, &regex TSRMLS_CC);
@@ -2195,15 +2199,15 @@ SPL_METHOD(RecursiveRegexIterator, getChildren)
21952199
/* {{{ spl_dual_it_dtor */
21962200
static void spl_dual_it_dtor(zend_object *_object TSRMLS_DC)
21972201
{
2198-
spl_dual_it_object *object = (spl_dual_it_object *)_object;
2202+
spl_dual_it_object *object = (spl_dual_it_object *)_object;
21992203

22002204
/* call standard dtor */
22012205
zend_objects_destroy_object(_object TSRMLS_CC);
22022206

22032207
spl_dual_it_free(object TSRMLS_CC);
22042208

22052209
if (object->inner.iterator) {
2206-
object->inner.iterator->funcs->dtor(object->inner.iterator TSRMLS_CC);
2210+
zend_iterator_dtor(object->inner.iterator TSRMLS_CC);
22072211
}
22082212
}
22092213
/* }}} */
@@ -2214,12 +2218,12 @@ static void spl_dual_it_free_storage(zend_object *_object TSRMLS_DC)
22142218
spl_dual_it_object *object = (spl_dual_it_object *)_object;
22152219

22162220

2217-
if (object->inner.zobject) {
2218-
zval_ptr_dtor(object->inner.zobject);
2221+
if (!ZVAL_IS_UNDEF(&object->inner.zobject)) {
2222+
zval_ptr_dtor(&object->inner.zobject);
22192223
}
22202224

22212225
if (object->dit_type == DIT_AppendIterator) {
2222-
object->u.append.iterator->funcs->dtor(object->u.append.iterator TSRMLS_CC);
2226+
zend_iterator_dtor(object->u.append.iterator TSRMLS_CC);
22232227
if (Z_TYPE(object->u.append.zarrayit) != IS_UNDEF) {
22242228
zval_ptr_dtor(&object->u.append.zarrayit);
22252229
}
@@ -2408,7 +2412,7 @@ static inline void spl_limit_it_seek(spl_dual_it_object *intern, long pos TSRMLS
24082412
if (pos != intern->current.pos && instanceof_function(intern->inner.ce, spl_ce_SeekableIterator TSRMLS_CC)) {
24092413
ZVAL_LONG(&zpos, pos);
24102414
spl_dual_it_free(intern TSRMLS_CC);
2411-
zend_call_method_with_1_params(intern->inner.zobject, intern->inner.ce, NULL, "seek", NULL, &zpos);
2415+
zend_call_method_with_1_params(&intern->inner.zobject, intern->inner.ce, NULL, "seek", NULL, &zpos);
24122416
zval_ptr_dtor(&zpos);
24132417
if (!EG(exception)) {
24142418
intern->current.pos = pos;
@@ -2560,7 +2564,7 @@ static inline void spl_caching_it_next(spl_dual_it_object *intern TSRMLS_DC)
25602564
/* Recursion ? */
25612565
if (intern->dit_type == DIT_RecursiveCachingIterator) {
25622566
zval retval, zchildren, zflags;
2563-
zend_call_method_with_0_params(intern->inner.zobject, intern->inner.ce, NULL, "haschildren", &retval);
2567+
zend_call_method_with_0_params(&intern->inner.zobject, intern->inner.ce, NULL, "haschildren", &retval);
25642568
if (EG(exception)) {
25652569
zval_ptr_dtor(&retval);
25662570
if (intern->u.caching.flags & CIT_CATCH_GET_CHILD) {
@@ -2570,7 +2574,7 @@ static inline void spl_caching_it_next(spl_dual_it_object *intern TSRMLS_DC)
25702574
}
25712575
} else {
25722576
if (zend_is_true(&retval TSRMLS_CC)) {
2573-
zend_call_method_with_0_params(intern->inner.zobject, intern->inner.ce, NULL, "getchildren", &zchildren);
2577+
zend_call_method_with_0_params(&intern->inner.zobject, intern->inner.ce, NULL, "getchildren", &zchildren);
25742578
if (EG(exception)) {
25752579
zval_ptr_dtor(&zchildren);
25762580
if (intern->u.caching.flags & CIT_CATCH_GET_CHILD) {
@@ -2599,7 +2603,7 @@ static inline void spl_caching_it_next(spl_dual_it_object *intern TSRMLS_DC)
25992603
int use_copy;
26002604
zval expr_copy;
26012605
if (intern->u.caching.flags & CIT_TOSTRING_USE_INNER) {
2602-
ZVAL_COPY_VALUE(&intern->u.caching.zstr, intern->inner.zobject);
2606+
ZVAL_COPY_VALUE(&intern->u.caching.zstr, &intern->inner.zobject);
26032607
} else {
26042608
ZVAL_COPY_VALUE(&intern->u.caching.zstr, &intern->current.data);
26052609
}
@@ -3217,24 +3221,21 @@ int spl_append_it_next_iterator(spl_dual_it_object *intern TSRMLS_DC) /* {{{*/
32173221
{
32183222
spl_dual_it_free(intern TSRMLS_CC);
32193223

3220-
if (intern->inner.zobject) {
3221-
zval_ptr_dtor(intern->inner.zobject);
3222-
intern->inner.zobject = NULL;
3224+
if (!ZVAL_IS_UNDEF(&intern->inner.zobject)) {
3225+
zval_ptr_dtor(&intern->inner.zobject);
3226+
ZVAL_UNDEF(&intern->inner.zobject);
32233227
intern->inner.ce = NULL;
3224-
intern->inner.object = NULL;
32253228
if (intern->inner.iterator) {
3226-
intern->inner.iterator->funcs->dtor(intern->inner.iterator TSRMLS_CC);
3229+
zend_iterator_dtor(intern->inner.iterator TSRMLS_CC);
32273230
intern->inner.iterator = NULL;
32283231
}
32293232
}
32303233
if (intern->u.append.iterator->funcs->valid(intern->u.append.iterator TSRMLS_CC) == SUCCESS) {
32313234
zval *it;
32323235

32333236
it = intern->u.append.iterator->funcs->get_current_data(intern->u.append.iterator TSRMLS_CC);
3234-
Z_ADDREF_P(it);
3235-
intern->inner.zobject = it;
3237+
ZVAL_COPY(&intern->inner.zobject, it);
32363238
intern->inner.ce = Z_OBJCE_P(it);
3237-
intern->inner.object = Z_OBJ_P(it);
32383239
intern->inner.iterator = intern->inner.ce->get_iterator(intern->inner.ce, it, 0 TSRMLS_CC);
32393240
spl_dual_it_rewind(intern TSRMLS_CC);
32403241
return SUCCESS;
@@ -3289,7 +3290,7 @@ SPL_METHOD(AppendIterator, append)
32893290
}
32903291
do {
32913292
spl_append_it_next_iterator(intern TSRMLS_CC);
3292-
} while (intern->inner.zobject != it);
3293+
} while (Z_OBJ(intern->inner.zobject) != Z_OBJCE_P(it));
32933294
spl_append_it_fetch(intern TSRMLS_CC);
32943295
}
32953296
} /* }}} */
@@ -3426,7 +3427,7 @@ PHPAPI int spl_iterator_apply(zval *obj, spl_iterator_apply_func_t apply_func, v
34263427

34273428
done:
34283429
if (iter) {
3429-
iter->funcs->dtor(iter TSRMLS_CC);
3430+
zend_iterator_dtor(iter TSRMLS_CC);
34303431
}
34313432
return EG(exception) ? FAILURE : SUCCESS;
34323433
}

ext/spl/spl_iterators.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ typedef struct _spl_cbfilter_it_intern {
126126
typedef struct _spl_dual_it_object {
127127
zend_object std;
128128
struct {
129-
zval *zobject;
129+
zval zobject;
130130
zend_class_entry *ce;
131131
zend_object *object;
132132
zend_object_iterator *iterator;

0 commit comments

Comments
 (0)