]> granicus.if.org Git - php/commitdiff
Add zend_iterator_dtor
authorXinchen Hui <laruence@gmail.com>
Fri, 28 Feb 2014 07:03:43 +0000 (15:03 +0800)
committerXinchen Hui <laruence@gmail.com>
Fri, 28 Feb 2014 07:03:43 +0000 (15:03 +0800)
Zend/zend_iterators.c
Zend/zend_iterators.h
ext/spl/spl_directory.c
ext/spl/spl_iterators.c
ext/spl/spl_iterators.h

index 5514c8bba8e1a47c637e060852c2225c9724bd2c..b378f04d232718cc3b6f02d0f5b0fde586bc926d 100644 (file)
@@ -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)
 {
index 9343382efd795147ee674aed4721442a78b53ab8..09346aee902d7e73e8b30a4a97886978e5fbec3e 100644 (file)
@@ -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()
index 19edadd1bf2ea5fc2b20225ab02f196eaeb8fd1c..fcfeb33f07b2e3704783fc0c47d638b51cd741c6 100644 (file)
@@ -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);
index f4575d8350fb7d5bb264135b5c9302d197f7268d..3d682153d32eaf67a500d895ee46efe533816787 100644 (file)
@@ -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(&params[0], &intern->current.data);
        ZVAL_COPY_VALUE(&params[1], &intern->current.key);
-       ZVAL_COPY_VALUE(&params[2], intern->inner.zobject);
+       ZVAL_COPY_VALUE(&params[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(&regex, STR_COPY(intern->u.regex.regex));
                spl_instantiate_arg_ex2(Z_OBJCE_P(getThis()), return_value, &retval, &regex 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;
 }
index 1da5b851819c923f57a7fc92e832c3f24a4c9aff..78eb67eebe14cfdbb116c9bc8c628a5e98338294 100644 (file)
@@ -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;