Fixed iterators API. zend_iterator_init() has to be used in each get_iterator() callback.

This commit is contained in:
Dmitry Stogov 2014-02-26 15:01:08 +04:00
parent a4a86df3c0
commit 495551aa8c
12 changed files with 45 additions and 23 deletions

View file

@ -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;

View file

@ -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;

View file

@ -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(

View file

@ -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()

View file

@ -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();

View file

@ -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) {

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;