mirror of
https://github.com/php/php-src.git
synced 2025-08-18 15:08:55 +02:00
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.
This commit is contained in:
parent
aa7ed0788c
commit
94e3087be7
1 changed files with 21 additions and 11 deletions
|
@ -58,11 +58,16 @@ static void text_iter_cp_get_current_data(text_iter_obj* object TSRMLS_DC)
|
|||
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 @@ static void text_iter_cp_move_forward(text_iter_obj* object TSRMLS_DC)
|
|||
{
|
||||
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 @@ static void text_iterator_free_storage(void *object TSRMLS_DC)
|
|||
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 @@ static zend_object_value text_iterator_new(zend_class_entry *class_type TSRMLS_D
|
|||
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();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue