From: Xinchen Hui Date: Fri, 28 Feb 2014 09:43:19 +0000 (+0800) Subject: Refactored spl_filesystem_iterator X-Git-Tag: POST_PHPNG_MERGE~412^2~488 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=990c923ef438b639cd8384f5f796a621767104b4;p=php Refactored spl_filesystem_iterator --- diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index 604aca7e81..46855ef957 100644 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -123,15 +123,10 @@ static void spl_filesystem_object_free_storage(zend_object *object TSRMLS_DC) /* break; } - { - zend_object_iterator *iterator; - iterator = (zend_object_iterator*) - spl_filesystem_object_to_iterator(intern); - if (!ZVAL_IS_UNDEF(&iterator->data)) { - ZVAL_UNDEF(&iterator->data); - zend_iterator_dtor(iterator TSRMLS_CC); - } - } + //???if (intern->it) { + //zend_iterator_dtor(intern->it TSRMLS_CC); + //} + efree(object); } /* }}} */ @@ -158,9 +153,8 @@ static zend_object *spl_filesystem_object_new_ex(zend_class_entry *class_type TS zend_object_std_init(&intern->std, class_type TSRMLS_CC); object_properties_init(&intern->std, class_type); - zend_iterator_init(&intern->it.intern TSRMLS_CC); - intern->std.handlers = &spl_filesystem_object_handlers; + return &intern->std; } /* }}} */ @@ -635,7 +629,7 @@ static HashTable *spl_filesystem_object_get_debug_info(zval *obj, int *is_temp T if (intern->u.dir.sub_path) { ZVAL_STRINGL(&tmp, intern->u.dir.sub_path, intern->u.dir.sub_path_len); } else { - ZVAL_STRINGL(&tmp, "", 0); + ZVAL_STR(&tmp, STR_EMPTY_ALLOC()); } zend_symtable_update(rv, pnstr, &tmp); STR_RELEASE(pnstr); @@ -1646,16 +1640,11 @@ zend_object_iterator *spl_filesystem_dir_get_iterator(zend_class_entry *ce, zval } dir_object = (spl_filesystem_object*)Z_OBJ_P(object); iterator = spl_filesystem_object_to_iterator(dir_object); - - Z_ADDREF_P(object); - /* initialize iterator if it wasn't gotten before */ - if (ZVAL_IS_UNDEF(&iterator->intern.data)) { - ZVAL_COPY_VALUE(&iterator->intern.data, object); - iterator->intern.funcs = &spl_filesystem_dir_it_funcs; - /* ->current must be initialized; rewind doesn't set it and valid - * doesn't check whether it's set */ - iterator->current = *object; - } + ZVAL_COPY(&iterator->intern.data, object); + iterator->intern.funcs = &spl_filesystem_dir_it_funcs; + /* ->current must be initialized; rewind doesn't set it and valid + * doesn't check whether it's set */ + iterator->current = *object; return &iterator->intern; } @@ -1670,6 +1659,7 @@ static void spl_filesystem_dir_it_dtor(zend_object_iterator *iter TSRMLS_DC) zval *object = &iterator->intern.data; zval_ptr_dtor(object); } + efree(iter); /* Otherwise we were called from the owning object free storage handler as * it sets * iterator->intern.data to NULL. @@ -1849,14 +1839,10 @@ zend_object_iterator *spl_filesystem_tree_get_iterator(zend_class_entry *ce, zva zend_error(E_ERROR, "An iterator cannot be used with foreach by reference"); } dir_object = (spl_filesystem_object*)Z_OBJ_P(object); - iterator = spl_filesystem_object_to_iterator(dir_object); + iterator = spl_filesystem_object_to_iterator(dir_object); - Z_ADDREF_P(object); - /* initialize iterator if wasn't gotten before */ - if (ZVAL_IS_UNDEF(&iterator->intern.data)) { - ZVAL_COPY_VALUE(&iterator->intern.data, object); - iterator->intern.funcs = &spl_filesystem_tree_it_funcs; - } + ZVAL_COPY(&iterator->intern.data, object); + iterator->intern.funcs = &spl_filesystem_tree_it_funcs; return &iterator->intern; } diff --git a/ext/spl/spl_directory.h b/ext/spl/spl_directory.h index 0ce7815d42..72c701d117 100644 --- a/ext/spl/spl_directory.h +++ b/ext/spl/spl_directory.h @@ -56,6 +56,7 @@ typedef struct _spl_other_handler { typedef struct { zend_object_iterator intern; zval current; + void *object; } spl_filesystem_iterator; struct _spl_filesystem_object { @@ -101,17 +102,24 @@ struct _spl_filesystem_object { char escape; } file; } u; - spl_filesystem_iterator it; + spl_filesystem_iterator *it; }; -static inline spl_filesystem_iterator* spl_filesystem_object_to_iterator(spl_filesystem_object *obj) +static inline spl_filesystem_iterator* spl_filesystem_object_to_iterator(spl_filesystem_object *obj TSRMLS_DC) { - return &obj->it; + if (obj->it) { + zend_iterator_dtor(&obj->it->intern TSRMLS_CC); + } + + obj->it = ecalloc(1, sizeof(spl_filesystem_iterator)); + obj->it->object = (void *)obj; + zend_iterator_init(&obj->it->intern TSRMLS_CC); + return obj->it; } -static inline spl_filesystem_object* spl_filesystem_iterator_to_object(spl_filesystem_iterator *it) +static inline spl_filesystem_object* spl_filesystem_iterator_to_object(spl_filesystem_iterator *it TSRMLS_DC) { - return (spl_filesystem_object*)((char*)it - XtOffsetOf(spl_filesystem_object, it)); + return (spl_filesystem_object*)it->object; } #define SPL_FILE_OBJECT_DROP_NEW_LINE 0x00000001 /* drop new lines */ diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c index dccf508e7e..be2f266709 100644 --- a/ext/spl/spl_iterators.c +++ b/ext/spl/spl_iterators.c @@ -325,9 +325,8 @@ next_step: } object->iterators = erealloc(object->iterators, sizeof(spl_sub_iterator) * (++object->level+1)); sub_iter = ce->get_iterator(ce, &child, 0 TSRMLS_CC); - Z_ADDREF(child); + ZVAL_COPY(&object->iterators[object->level].zobject, &child); object->iterators[object->level].iterator = sub_iter; - object->iterators[object->level].zobject = child; object->iterators[object->level].ce = ce; object->iterators[object->level].state = RS_START; if (sub_iter->funcs->rewind) { @@ -839,7 +838,7 @@ static union _zend_function *spl_recursive_it_get_method(zval *object_ptr, zend_ if (!function_handler) { if ((function_handler = zend_hash_find_ptr(&Z_OBJCE_P(zobj)->function_table, method)) == NULL) { if (Z_OBJ_HT_P(zobj)->get_method) { - object_ptr = zobj; + *object_ptr = *zobj; function_handler = Z_OBJ_HT_P(object_ptr)->get_method(object_ptr, method, key TSRMLS_CC); } }