diff options
-rw-r--r-- | Zend/zend_iterators.c | 9 | ||||
-rw-r--r-- | Zend/zend_iterators.h | 1 | ||||
-rw-r--r-- | ext/spl/spl_directory.c | 2 | ||||
-rw-r--r-- | ext/spl/spl_iterators.c | 95 | ||||
-rw-r--r-- | ext/spl/spl_iterators.h | 2 |
5 files changed, 60 insertions, 49 deletions
diff --git a/Zend/zend_iterators.c b/Zend/zend_iterators.c index 5514c8bba8..b378f04d23 100644 --- a/Zend/zend_iterators.c +++ b/Zend/zend_iterators.c @@ -71,6 +71,15 @@ ZEND_API void zend_iterator_init(zend_object_iterator *iter TSRMLS_DC) iter->std.handlers = &iterator_object_handlers; } +ZEND_API void zend_iterator_dtor(zend_object_iterator *iter TSRMLS_DC) +{ + if (--iter->std.gc.refcount > 0) { + return; + } + + zend_objects_store_del(&iter->std TSRMLS_CC); +} + ZEND_API enum zend_object_iterator_kind zend_iterator_unwrap( zval *array_ptr, zend_object_iterator **iter TSRMLS_DC) { diff --git a/Zend/zend_iterators.h b/Zend/zend_iterators.h index 9343382efd..09346aee90 100644 --- a/Zend/zend_iterators.h +++ b/Zend/zend_iterators.h @@ -84,6 +84,7 @@ ZEND_API enum zend_object_iterator_kind zend_iterator_unwrap(zval *array_ptr, ze /* given an iterator, wrap it up as a zval for use by the engine opcodes */ ZEND_API void zend_iterator_init(zend_object_iterator *iter TSRMLS_DC); +ZEND_API void zend_iterator_dtor(zend_object_iterator *iter TSRMLS_DC); ZEND_API void zend_register_iterator_wrapper(TSRMLS_D); END_EXTERN_C() diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index 19edadd1bf..fcfeb33f07 100644 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -129,7 +129,7 @@ static void spl_filesystem_object_free_storage(zend_object *object TSRMLS_DC) /* spl_filesystem_object_to_iterator(intern); if (!ZVAL_IS_UNDEF(&iterator->data)) { ZVAL_UNDEF(&iterator->data); - iterator->funcs->dtor(iterator TSRMLS_CC); + zend_iterator_dtor(iterator TSRMLS_CC); } } efree(object); diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c index f4575d8350..3d682153d3 100644 --- a/ext/spl/spl_iterators.c +++ b/ext/spl/spl_iterators.c @@ -146,7 +146,7 @@ static void spl_recursive_it_dtor(zend_object_iterator *_iter TSRMLS_DC) while (object->level > 0) { sub_iter = object->iterators[object->level].iterator; - sub_iter->funcs->dtor(sub_iter TSRMLS_CC); + zend_iterator_dtor(sub_iter TSRMLS_CC); zval_ptr_dtor(&object->iterators[object->level--].zobject); } 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 zend_object_iterator *sub_iter; int level = object->level; - while (level >=0) { + while (level >= 0) { sub_iter = object->iterators[level].iterator; if (sub_iter->funcs->valid(sub_iter TSRMLS_CC) == SUCCESS) { return SUCCESS; @@ -357,7 +357,7 @@ next_step: } } } - iterator->funcs->dtor(iterator TSRMLS_CC); + zend_iterator_dtor(iterator TSRMLS_CC); zval_ptr_dtor(&object->iterators[object->level].zobject); object->level--; } else { @@ -376,7 +376,7 @@ static void spl_recursive_it_rewind_ex(spl_recursive_it_object *object, zval *zt while (object->level) { sub_iter = object->iterators[object->level].iterator; - sub_iter->funcs->dtor(sub_iter TSRMLS_CC); + zend_iterator_dtor(sub_iter TSRMLS_CC); zval_ptr_dtor(&object->iterators[object->level--].zobject); if (!EG(exception) && (!object->endChildren || object->endChildren->common.scope != spl_ce_RecursiveIteratorIterator)) { 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 = { 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) { - zval *object = getThis(); - spl_recursive_it_object *intern; - zval *iterator; - zend_class_entry *ce_iterator; - long mode, flags; - int inc_refcount = 1; - zend_error_handling error_handling; + zval *object = getThis(); + spl_recursive_it_object *intern; + zval *iterator; + zend_class_entry *ce_iterator; + long mode, flags; + int inc_refcount = 1; + zend_error_handling error_handling; zend_replace_error_handling(EH_THROW, spl_ce_InvalidArgumentException, &error_handling TSRMLS_CC); - switch(rit_type) { + switch (rit_type) { case RIT_RecursiveTreeIterator: { 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 if (intern->nextElement->common.scope == ce_base) { intern->nextElement = NULL; } + ce_iterator = Z_OBJCE_P(iterator); /* respect inheritance, don't use spl_ce_RecursiveIterator */ intern->iterators[0].iterator = ce_iterator->get_iterator(ce_iterator, iterator, 0 TSRMLS_CC); if (inc_refcount) { - Z_ADDREF_P(iterator); + ZVAL_COPY(&intern->iterators[0].zobject, iterator); + } else { + ZVAL_COPY_VALUE(&intern->iterators[0].zobject, iterator); } - intern->iterators[0].zobject = *iterator; intern->iterators[0].ce = ce_iterator; intern->iterators[0].state = RS_START; @@ -558,7 +560,7 @@ static void spl_recursive_it_it_construct(INTERNAL_FUNCTION_PARAMETERS, zend_cla while (intern->level >= 0) { sub_iter = intern->iterators[intern->level].iterator; - sub_iter->funcs->dtor(sub_iter TSRMLS_CC); + zend_iterator_dtor(sub_iter TSRMLS_CC); zval_ptr_dtor(&intern->iterators[intern->level--].zobject); } efree(intern->iterators); @@ -857,7 +859,7 @@ static void spl_RecursiveIteratorIterator_dtor(zend_object *_object TSRMLS_DC) if (object->iterators) { while (object->level >= 0) { sub_iter = object->iterators[object->level].iterator; - sub_iter->funcs->dtor(sub_iter TSRMLS_CC); + zend_iterator_dtor(sub_iter TSRMLS_CC); zval_ptr_dtor(&object->iterators[object->level--].zobject); } efree(object->iterators); @@ -1282,14 +1284,14 @@ static union _zend_function *spl_dual_it_get_method(zval *object_ptr, zend_strin function_handler = std_object_handlers.get_method(object_ptr, method, key TSRMLS_CC); if (!function_handler && intern->inner.ce) { if ((function_handler = zend_hash_find_ptr(&intern->inner.ce->function_table, method)) == NULL) { - if (Z_OBJ_HT_P(intern->inner.zobject)->get_method) { + if (Z_OBJ_HT(intern->inner.zobject)->get_method) { //!!! maybe we really need a zval ** here? //*object_ptr = &intern->inner.zobject? - object_ptr = intern->inner.zobject; + object_ptr = &intern->inner.zobject; function_handler = Z_OBJ_HT_P(object_ptr)->get_method(object_ptr, method, key TSRMLS_CC); } } else { - object_ptr = intern->inner.zobject; + object_ptr = &intern->inner.zobject; } } return function_handler; @@ -1519,9 +1521,11 @@ static spl_dual_it_object* spl_dual_it_construct(INTERNAL_FUNCTION_PARAMETERS, z zend_restore_error_handling(&error_handling TSRMLS_CC); if (inc_refcount) { - Z_ADDREF_P(zobject); + ZVAL_COPY(&intern->inner.zobject, zobject); + } else { + ZVAL_COPY_VALUE(&intern->inner.zobject, zobject); } - intern->inner.zobject = zobject; + intern->inner.ce = dit_type == DIT_IteratorIterator ? ce : Z_OBJCE_P(zobject); intern->inner.object = Z_OBJ_P(zobject); intern->inner.iterator = intern->inner.ce->get_iterator(intern->inner.ce, zobject, 0 TSRMLS_CC); @@ -1558,8 +1562,8 @@ SPL_METHOD(dual_it, getInnerIterator) SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); - if (intern->inner.zobject) { - RETVAL_ZVAL(intern->inner.zobject, 1, 0); + if (!ZVAL_IS_UNDEF(&intern->inner.zobject)) { + RETVAL_ZVAL(&intern->inner.zobject, 1, 0); } else { RETURN_NULL(); } @@ -1843,7 +1847,7 @@ SPL_METHOD(RecursiveFilterIterator, hasChildren) SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); - zend_call_method_with_0_params(intern->inner.zobject, intern->inner.ce, NULL, "haschildren", &retval); + zend_call_method_with_0_params(&intern->inner.zobject, intern->inner.ce, NULL, "haschildren", &retval); if (Z_TYPE(retval) != IS_UNDEF) { RETURN_ZVAL(&retval, 0, 1); } else { @@ -1864,7 +1868,7 @@ SPL_METHOD(RecursiveFilterIterator, getChildren) SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); - zend_call_method_with_0_params(intern->inner.zobject, intern->inner.ce, NULL, "getchildren", &retval); + zend_call_method_with_0_params(&intern->inner.zobject, intern->inner.ce, NULL, "getchildren", &retval); if (!EG(exception) && Z_TYPE(retval) != IS_UNDEF) { spl_instantiate_arg_ex1(Z_OBJCE_P(getThis()), return_value, &retval TSRMLS_CC); } @@ -1884,7 +1888,7 @@ SPL_METHOD(RecursiveCallbackFilterIterator, getChildren) intern = (spl_dual_it_object*)Z_OBJ_P(getThis()); - zend_call_method_with_0_params(intern->inner.zobject, intern->inner.ce, NULL, "getchildren", &retval); + zend_call_method_with_0_params(&intern->inner.zobject, intern->inner.ce, NULL, "getchildren", &retval); if (!EG(exception) && Z_TYPE(retval) != IS_UNDEF) { spl_instantiate_arg_ex2(Z_OBJCE_P(getThis()), return_value, &retval, &intern->u.cbfilter->fci.function_name TSRMLS_CC); } @@ -1925,7 +1929,7 @@ SPL_METHOD(CallbackFilterIterator, accept) ZVAL_COPY_VALUE(¶ms[0], &intern->current.data); ZVAL_COPY_VALUE(¶ms[1], &intern->current.key); - ZVAL_COPY_VALUE(¶ms[2], intern->inner.zobject); + ZVAL_COPY_VALUE(¶ms[2], &intern->inner.zobject); fci->retval = &result; fci->param_count = 3; @@ -2181,7 +2185,7 @@ SPL_METHOD(RecursiveRegexIterator, getChildren) SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); - zend_call_method_with_0_params(intern->inner.zobject, intern->inner.ce, NULL, "getchildren", &retval); + zend_call_method_with_0_params(&intern->inner.zobject, intern->inner.ce, NULL, "getchildren", &retval); if (!EG(exception)) { ZVAL_STR(®ex, STR_COPY(intern->u.regex.regex)); spl_instantiate_arg_ex2(Z_OBJCE_P(getThis()), return_value, &retval, ®ex TSRMLS_CC); @@ -2195,7 +2199,7 @@ SPL_METHOD(RecursiveRegexIterator, getChildren) /* {{{ spl_dual_it_dtor */ static void spl_dual_it_dtor(zend_object *_object TSRMLS_DC) { - spl_dual_it_object *object = (spl_dual_it_object *)_object; + spl_dual_it_object *object = (spl_dual_it_object *)_object; /* call standard dtor */ zend_objects_destroy_object(_object TSRMLS_CC); @@ -2203,7 +2207,7 @@ static void spl_dual_it_dtor(zend_object *_object TSRMLS_DC) spl_dual_it_free(object TSRMLS_CC); if (object->inner.iterator) { - object->inner.iterator->funcs->dtor(object->inner.iterator TSRMLS_CC); + zend_iterator_dtor(object->inner.iterator TSRMLS_CC); } } /* }}} */ @@ -2214,12 +2218,12 @@ static void spl_dual_it_free_storage(zend_object *_object TSRMLS_DC) spl_dual_it_object *object = (spl_dual_it_object *)_object; - if (object->inner.zobject) { - zval_ptr_dtor(object->inner.zobject); + if (!ZVAL_IS_UNDEF(&object->inner.zobject)) { + zval_ptr_dtor(&object->inner.zobject); } if (object->dit_type == DIT_AppendIterator) { - object->u.append.iterator->funcs->dtor(object->u.append.iterator TSRMLS_CC); + zend_iterator_dtor(object->u.append.iterator TSRMLS_CC); if (Z_TYPE(object->u.append.zarrayit) != IS_UNDEF) { zval_ptr_dtor(&object->u.append.zarrayit); } @@ -2408,7 +2412,7 @@ static inline void spl_limit_it_seek(spl_dual_it_object *intern, long pos TSRMLS if (pos != intern->current.pos && instanceof_function(intern->inner.ce, spl_ce_SeekableIterator TSRMLS_CC)) { ZVAL_LONG(&zpos, pos); spl_dual_it_free(intern TSRMLS_CC); - zend_call_method_with_1_params(intern->inner.zobject, intern->inner.ce, NULL, "seek", NULL, &zpos); + zend_call_method_with_1_params(&intern->inner.zobject, intern->inner.ce, NULL, "seek", NULL, &zpos); zval_ptr_dtor(&zpos); if (!EG(exception)) { intern->current.pos = pos; @@ -2560,7 +2564,7 @@ static inline void spl_caching_it_next(spl_dual_it_object *intern TSRMLS_DC) /* Recursion ? */ if (intern->dit_type == DIT_RecursiveCachingIterator) { zval retval, zchildren, zflags; - zend_call_method_with_0_params(intern->inner.zobject, intern->inner.ce, NULL, "haschildren", &retval); + zend_call_method_with_0_params(&intern->inner.zobject, intern->inner.ce, NULL, "haschildren", &retval); if (EG(exception)) { zval_ptr_dtor(&retval); 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) } } else { if (zend_is_true(&retval TSRMLS_CC)) { - zend_call_method_with_0_params(intern->inner.zobject, intern->inner.ce, NULL, "getchildren", &zchildren); + zend_call_method_with_0_params(&intern->inner.zobject, intern->inner.ce, NULL, "getchildren", &zchildren); if (EG(exception)) { zval_ptr_dtor(&zchildren); 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) int use_copy; zval expr_copy; if (intern->u.caching.flags & CIT_TOSTRING_USE_INNER) { - ZVAL_COPY_VALUE(&intern->u.caching.zstr, intern->inner.zobject); + ZVAL_COPY_VALUE(&intern->u.caching.zstr, &intern->inner.zobject); } else { ZVAL_COPY_VALUE(&intern->u.caching.zstr, &intern->current.data); } @@ -3217,13 +3221,12 @@ int spl_append_it_next_iterator(spl_dual_it_object *intern TSRMLS_DC) /* {{{*/ { spl_dual_it_free(intern TSRMLS_CC); - if (intern->inner.zobject) { - zval_ptr_dtor(intern->inner.zobject); - intern->inner.zobject = NULL; + if (!ZVAL_IS_UNDEF(&intern->inner.zobject)) { + zval_ptr_dtor(&intern->inner.zobject); + ZVAL_UNDEF(&intern->inner.zobject); intern->inner.ce = NULL; - intern->inner.object = NULL; if (intern->inner.iterator) { - intern->inner.iterator->funcs->dtor(intern->inner.iterator TSRMLS_CC); + zend_iterator_dtor(intern->inner.iterator TSRMLS_CC); intern->inner.iterator = NULL; } } @@ -3231,10 +3234,8 @@ int spl_append_it_next_iterator(spl_dual_it_object *intern TSRMLS_DC) /* {{{*/ zval *it; it = intern->u.append.iterator->funcs->get_current_data(intern->u.append.iterator TSRMLS_CC); - Z_ADDREF_P(it); - intern->inner.zobject = it; + ZVAL_COPY(&intern->inner.zobject, it); intern->inner.ce = Z_OBJCE_P(it); - intern->inner.object = Z_OBJ_P(it); intern->inner.iterator = intern->inner.ce->get_iterator(intern->inner.ce, it, 0 TSRMLS_CC); spl_dual_it_rewind(intern TSRMLS_CC); return SUCCESS; @@ -3289,7 +3290,7 @@ SPL_METHOD(AppendIterator, append) } do { spl_append_it_next_iterator(intern TSRMLS_CC); - } while (intern->inner.zobject != it); + } while (Z_OBJ(intern->inner.zobject) != Z_OBJCE_P(it)); spl_append_it_fetch(intern TSRMLS_CC); } } /* }}} */ @@ -3426,7 +3427,7 @@ PHPAPI int spl_iterator_apply(zval *obj, spl_iterator_apply_func_t apply_func, v done: if (iter) { - iter->funcs->dtor(iter TSRMLS_CC); + zend_iterator_dtor(iter TSRMLS_CC); } return EG(exception) ? FAILURE : SUCCESS; } diff --git a/ext/spl/spl_iterators.h b/ext/spl/spl_iterators.h index 1da5b85181..78eb67eebe 100644 --- a/ext/spl/spl_iterators.h +++ b/ext/spl/spl_iterators.h @@ -126,7 +126,7 @@ typedef struct _spl_cbfilter_it_intern { typedef struct _spl_dual_it_object { zend_object std; struct { - zval *zobject; + zval zobject; zend_class_entry *ce; zend_object *object; zend_object_iterator *iterator; |