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 &current()".
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

Reply via email to