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 -- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php