Hello Andrei, actually thinking twice we don't need a flag. If something implements Iterator we shouldn't allow foreach by reference anyway because the iterator signature is "mixed current()" and not "mixed ¤t()". And since both direct and manual iteration should be compatible we should just disallow it in the same manner we needed to disallow ArrayAccess reference handling. Something that only implements Traverable might however still do foreach by reference. So the change is probably quite small.
best regards marcus Andi? Saturday, February 4, 2006, 12:51:53 AM, you wrote: > Hello Andrei, > maybe internal c-level iterators can have a flag that disallows > foreach by reference? > regards > marcus > Saturday, February 4, 2006, 12:50:42 AM, you wrote: >> andrei Fri Feb 3 23:50:42 2006 UTC >> Modified files: >> /php-src/ext/unicode unicode_iterators.c >> Log: >> Gah. In order to avoid memory corruption when using references in >> foreach() this code is necessary. But it makes iterator 6x slower. We >> should keep thinking about how to optimize it. >> >> >> http://cvs.php.net/viewcvs.cgi/php-src/ext/unicode/unicode_iterators.c?r1=1.6&r2=1.7&diff_format=u >> Index: php-src/ext/unicode/unicode_iterators.c >> diff -u php-src/ext/unicode/unicode_iterators.c:1.6 >> php-src/ext/unicode/unicode_iterators.c:1.7 >> --- php-src/ext/unicode/unicode_iterators.c:1.6 Fri Feb 3 21:53:05 >> 2006 >> +++ php-src/ext/unicode/unicode_iterators.c Fri Feb 3 23:50:42 2006 >> @@ -14,7 +14,7 @@ >> +----------------------------------------------------------------------+ >> */ >> >> -/* $Id: unicode_iterators.c,v 1.6 2006/02/03 21:53:05 andrei Exp $ */ >> +/* $Id: unicode_iterators.c,v 1.7 2006/02/03 23:50:42 andrei Exp $ */ >> >> >> #include "php.h" >> @@ -58,11 +58,16 @@ >> UChar32 cp; >> int32_t tmp, buf_len; >> >> - tmp = object->offset; >> - U16_NEXT(object->text, tmp, object->text_len, cp); >> - buf_len = zend_codepoint_to_uchar(cp, Z_USTRVAL_P(object->current)); >> - Z_USTRVAL_P(object->current)[buf_len] = 0; >> - Z_USTRLEN_P(object->current) = buf_len; >> + if (!object->current) { >> + MAKE_STD_ZVAL(object->current); >> + Z_USTRVAL_P(object->current) = eumalloc(3); >> + Z_TYPE_P(object->current) = IS_UNICODE; >> + tmp = object->offset; >> + U16_NEXT(object->text, tmp, object->text_len, cp); >> + buf_len = zend_codepoint_to_uchar(cp, >> Z_USTRVAL_P(object->current)); >> + Z_USTRVAL_P(object->current)[buf_len] = 0; >> + Z_USTRLEN_P(object->current) = buf_len; >> + } >> } >> >> static int text_iter_cp_get_current_key(text_iter_obj* object TSRMLS_DC) >> @@ -74,12 +79,20 @@ >> { >> U16_FWD_1(object->text, object->offset, object->text_len); >> object->index++; >> + if (object->current) { >> + zval_ptr_dtor(&object->current); >> + object->current = NULL; >> + } >> } >> >> static void text_iter_cp_rewind(text_iter_obj *object TSRMLS_DC) >> { >> object->offset = 0; >> object->index = 0; >> + if (object->current) { >> + zval_ptr_dtor(&object->current); >> + object->current = NULL; >> + } >> } >> >> >> @@ -169,8 +182,9 @@ >> if (intern->text) { >> efree(intern->text); >> } >> - ZVAL_DELREF(intern->current); >> - zval_ptr_dtor(&intern->current); >> + if (intern->current) { >> + zval_ptr_dtor(&intern->current); >> + } >> efree(object); >> } >> >> @@ -189,10 +203,6 @@ >> zend_hash_copy(intern->std.properties, >> &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) >> &tmp, sizeof(zval *)); >> >> intern->type = ITER_CODE_POINT; >> - MAKE_STD_ZVAL(intern->current); /* pre-allocate buffer for codepoint >> */ >> - Z_USTRVAL_P(intern->current) = eumalloc(3); >> - Z_TYPE_P(intern->current) = IS_UNICODE; >> - ZVAL_ADDREF(intern->current); >> >> retval.handle = zend_objects_store_put(intern, >> (zend_objects_store_dtor_t)zend_objects_destroy_object, >> (zend_objects_free_object_storage_t) text_iterator_free_storage, NULL >> TSRMLS_CC); >> retval.handlers = zend_get_std_object_handlers(); > Best regards, > Marcus Best regards, Marcus -- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php