From: Dmitry Stogov Date: Wed, 26 Feb 2014 11:01:08 +0000 (+0400) Subject: Fixed iterators API. zend_iterator_init() has to be used in each get_iterator() callback. X-Git-Tag: POST_PHPNG_MERGE~412^2~516 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=495551aa8c3d66ee16ab91c1fb97329f10c0632c;p=php Fixed iterators API. zend_iterator_init() has to be used in each get_iterator() callback. --- diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c index f1affbc01e..78cb346eb7 100644 --- a/Zend/zend_generators.c +++ b/Zend/zend_generators.c @@ -675,19 +675,7 @@ zend_object_iterator *zend_generator_get_iterator(zend_class_entry *ce, zval *ob iterator = &generator->iterator; -//??? -#if 1 - iterator->intern.std.gc.refcount = 1; - iterator->intern.std.gc.u.v.type = IS_OBJECT; - iterator->intern.std.gc.u.v.flags = 0; - iterator->intern.std.gc.u.v.buffer = 0; - iterator->intern.std.ce = NULL; - iterator->intern.std.properties = NULL; - iterator->intern.std.guards = NULL; - zend_objects_store_put(&iterator->intern.std); -#else - zend_object_std_init(&iterator->intern.std, ???); -#endif + zend_iterator_init(&iterator->intern TSRMLS_CC); iterator->intern.funcs = &zend_generator_iterator_functions; iterator->intern.data = (void *) generator; diff --git a/Zend/zend_interfaces.c b/Zend/zend_interfaces.c index 87b3f723c0..2beeb1d439 100644 --- a/Zend/zend_interfaces.c +++ b/Zend/zend_interfaces.c @@ -259,6 +259,8 @@ static zend_object_iterator *zend_user_it_get_iterator(zend_class_entry *ce, zva iterator = emalloc(sizeof(zend_user_iterator)); + zend_iterator_init((zend_object_iterator*)iterator TSRMLS_CC); + Z_ADDREF_P(object); iterator->it.data = (void*)object; iterator->it.funcs = ce->iterator_funcs.funcs; diff --git a/Zend/zend_iterators.c b/Zend/zend_iterators.c index 7610aadfc8..5514c8bba8 100644 --- a/Zend/zend_iterators.c +++ b/Zend/zend_iterators.c @@ -65,11 +65,10 @@ static void iter_wrapper_dtor(zend_object *object TSRMLS_DC) iter->funcs->dtor(iter TSRMLS_CC); } -ZEND_API void zend_iterator_wrap(zend_object_iterator *iter, zval *wrapped TSRMLS_DC) +ZEND_API void zend_iterator_init(zend_object_iterator *iter TSRMLS_DC) { - ZVAL_OBJ(wrapped, &iter->std); - //??? hack (it would be better implement it in anothe way) - Z_OBJ_HT_P(wrapped) = &iterator_object_handlers; + zend_object_std_init(&iter->std, &zend_iterator_class_entry); + iter->std.handlers = &iterator_object_handlers; } ZEND_API enum zend_object_iterator_kind zend_iterator_unwrap( diff --git a/Zend/zend_iterators.h b/Zend/zend_iterators.h index 0ab5bef82a..d6cba7c892 100644 --- a/Zend/zend_iterators.h +++ b/Zend/zend_iterators.h @@ -83,7 +83,7 @@ BEGIN_EXTERN_C() ZEND_API enum zend_object_iterator_kind zend_iterator_unwrap(zval *array_ptr, zend_object_iterator **iter TSRMLS_DC); /* given an iterator, wrap it up as a zval for use by the engine opcodes */ -ZEND_API void zend_iterator_wrap(zend_object_iterator *iter, zval *zv TSRMLS_DC); +ZEND_API void zend_iterator_init(zend_object_iterator *iter TSRMLS_DC); ZEND_API void zend_register_iterator_wrapper(TSRMLS_D); END_EXTERN_C() diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index a469bc539b..3e377470a4 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -4253,7 +4253,10 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY) FREE_OP1_IF_VAR(); } if (iter && EXPECTED(EG(exception) == NULL)) { - zend_iterator_wrap(iter, array_ptr TSRMLS_CC); + zval iterator; + + array_ptr = &iterator; + ZVAL_OBJ(array_ptr, &iter->std); } else { if (OP1_TYPE == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) { FREE_OP1_VAR_PTR(); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 3b322b86c5..51ec30e733 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -3044,7 +3044,10 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_A } if (iter && EXPECTED(EG(exception) == NULL)) { - zend_iterator_wrap(iter, array_ptr TSRMLS_CC); + zval iterator; + + array_ptr = &iterator; + ZVAL_OBJ(array_ptr, &iter->std); } else { if (IS_CONST == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) { @@ -8095,7 +8098,10 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG } if (iter && EXPECTED(EG(exception) == NULL)) { - zend_iterator_wrap(iter, array_ptr TSRMLS_CC); + zval iterator; + + array_ptr = &iterator; + ZVAL_OBJ(array_ptr, &iter->std); } else { if (IS_TMP_VAR == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) { @@ -13198,7 +13204,10 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG zval_ptr_dtor_nogc(free_op1.var); } if (iter && EXPECTED(EG(exception) == NULL)) { - zend_iterator_wrap(iter, array_ptr TSRMLS_CC); + zval iterator; + + array_ptr = &iterator; + ZVAL_OBJ(array_ptr, &iter->std); } else { if (IS_VAR == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) { if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; @@ -30089,7 +30098,10 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS } if (iter && EXPECTED(EG(exception) == NULL)) { - zend_iterator_wrap(iter, array_ptr TSRMLS_CC); + zval iterator; + + array_ptr = &iterator; + ZVAL_OBJ(array_ptr, &iter->std); } else { if (IS_CV == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) { diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 05dccf4f8e..1489ac8184 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -1976,6 +1976,8 @@ zend_object_iterator *date_object_period_get_iterator(zend_class_entry *ce, zval zend_error(E_ERROR, "An iterator cannot be used with foreach by reference"); } + zend_iterator_init((zend_object_iterator*)iterator TSRMLS_CC); + Z_ADDREF_P(object); iterator->intern.data = (void*) dpobj; iterator->intern.funcs = &date_period_it_funcs; diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c index e272a145e5..e552ca8fb4 100644 --- a/ext/spl/spl_array.c +++ b/ext/spl/spl_array.c @@ -1148,6 +1148,8 @@ zend_object_iterator *spl_array_get_iterator(zend_class_entry *ce, zval *object, iterator = emalloc(sizeof(spl_array_it)); + zend_iterator_init((zend_object_iterator*)iterator TSRMLS_CC); + Z_ADDREF_P(object); iterator->intern.it.data = (void*)object; iterator->intern.it.funcs = &spl_array_it_funcs; diff --git a/ext/spl/spl_dllist.c b/ext/spl/spl_dllist.c index fbe249456e..99863626bc 100644 --- a/ext/spl/spl_dllist.c +++ b/ext/spl/spl_dllist.c @@ -1291,6 +1291,9 @@ zend_object_iterator *spl_dllist_get_iterator(zend_class_entry *ce, zval *object Z_ADDREF_P(object); iterator = emalloc(sizeof(spl_dllist_it)); + + zend_iterator_init((zend_object_iterator*)iterator TSRMLS_CC); + iterator->intern.it.data = (void*)object; iterator->intern.it.funcs = &spl_dllist_it_funcs; iterator->intern.ce = ce; diff --git a/ext/spl/spl_fixedarray.c b/ext/spl/spl_fixedarray.c index 075df9b2b7..9e5e8b590c 100644 --- a/ext/spl/spl_fixedarray.c +++ b/ext/spl/spl_fixedarray.c @@ -1052,6 +1052,9 @@ zend_object_iterator *spl_fixedarray_get_iterator(zend_class_entry *ce, zval *ob Z_ADDREF_P(object); iterator = emalloc(sizeof(spl_fixedarray_it)); + + zend_iterator_init((zend_object_iterator*)iterator TSRMLS_CC); + iterator->intern.it.data = object; iterator->intern.it.funcs = &spl_fixedarray_it_funcs; iterator->intern.ce = ce; diff --git a/ext/spl/spl_heap.c b/ext/spl/spl_heap.c index 9159000799..2afee6cd49 100644 --- a/ext/spl/spl_heap.c +++ b/ext/spl/spl_heap.c @@ -1091,6 +1091,9 @@ zend_object_iterator *spl_heap_get_iterator(zend_class_entry *ce, zval *object, Z_ADDREF_P(object); iterator = emalloc(sizeof(spl_heap_it)); + + zend_iterator_init((zend_object_iterator*)iterator TSRMLS_CC); + iterator->intern.it.data = (void*)object; iterator->intern.it.funcs = &spl_heap_it_funcs; iterator->intern.ce = ce; @@ -1115,6 +1118,9 @@ zend_object_iterator *spl_pqueue_get_iterator(zend_class_entry *ce, zval *object Z_ADDREF_P(object); iterator = emalloc(sizeof(spl_heap_it)); + + zend_iterator_init((zend_object_iterator*)iterator TSRMLS_CC); + iterator->intern.it.data = (void*)object; iterator->intern.it.funcs = &spl_pqueue_it_funcs; iterator->intern.ce = ce; diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c index 81d1ecc4bc..2891f3ce9b 100644 --- a/ext/spl/spl_iterators.c +++ b/ext/spl/spl_iterators.c @@ -423,6 +423,8 @@ static zend_object_iterator *spl_recursive_it_get_iterator(zend_class_entry *ce, "the parent constructor has not been called"); } + zend_iterator_init((zend_object_iterator*)iterator TSRMLS_CC); + Z_ADDREF_P(zobject); iterator->intern.data = (void*)object; iterator->intern.funcs = ce->iterator_funcs.funcs;