Commit: 6b68f44e6b46dffd7fe029eca7afc37f1fa57347 Author: Nikita Popov <ni...@php.net> Sun, 29 Sep 2013 20:18:12 +0200 Parents: 1d1fb69c8b703b1d3af0db30a6869f0140d37a51 Branches: PHP-5.5 master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=6b68f44e6b46dffd7fe029eca7afc37f1fa57347 Log: Fix bug #64979: Wrong behavior of static variables in closure generators Bugs: https://bugs.php.net/64979 Changed paths: M NEWS M Zend/tests/bug64979.phpt M Zend/zend_generators.c Diff: diff --git a/NEWS b/NEWS index 45b2647..1b1f9c4 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,10 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? 2013, PHP 5.5.5 +- Core: + . Fixed bug #64979 (Wrong behavior of static variables in closure generators). + (Nikita) + - CLI server: . Fixed bug #65633 (built-in server treat some http headers as case-sensitive). (Adam) diff --git a/Zend/tests/bug64979.phpt b/Zend/tests/bug64979.phpt index 09de555..5bc8e5a 100644 --- a/Zend/tests/bug64979.phpt +++ b/Zend/tests/bug64979.phpt @@ -1,15 +1,13 @@ --TEST-- -Bug #64578 (Closures with static variables can be generators) ---XFAIL-- -Bug #64979 not fixed yet. +Bug #64979 (Wrong behavior of static variables in closure generators) --FILE-- <?php function new_closure_gen() { - return function() { - static $foo = 0; - yield ++$foo; - }; + return function() { + static $foo = 0; + yield ++$foo; + }; } $closure1 = new_closure_gen(); @@ -20,9 +18,9 @@ $gen2 = $closure1(); $gen3 = $closure2(); foreach (array($gen1, $gen2, $gen3) as $gen) { - foreach ($gen as $val) { - print "$val\n"; - } + foreach ($gen as $val) { + var_dump($val); + } } ?> diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c index 1a805bb..0af20f4 100644 --- a/Zend/zend_generators.c +++ b/Zend/zend_generators.c @@ -226,6 +226,16 @@ static zend_object_value zend_generator_create(zend_class_entry *class_type TSRM } /* }}} */ +static void copy_closure_static_var(zval **var TSRMLS_DC, int num_args, va_list args, zend_hash_key *key) /* {{{ */ +{ + HashTable *target = va_arg(args, HashTable *); + + SEPARATE_ZVAL_TO_MAKE_IS_REF(var); + Z_ADDREF_PP(var); + zend_hash_quick_update(target, key->arKey, key->nKeyLength, key->h, var, sizeof(zval *), NULL); +} +/* }}} */ + /* Requires globals EG(scope), EG(current_scope), EG(This), * EG(active_symbol_table) and EG(current_execute_data). */ ZEND_API zval *zend_generator_create_zval(zend_op_array *op_array TSRMLS_DC) /* {{{ */ @@ -242,7 +252,23 @@ ZEND_API zval *zend_generator_create_zval(zend_op_array *op_array TSRMLS_DC) /* if (op_array->fn_flags & ZEND_ACC_CLOSURE) { zend_op_array *op_array_copy = (zend_op_array*)emalloc(sizeof(zend_op_array)); *op_array_copy = *op_array; - function_add_ref((zend_function *) op_array_copy); + + (*op_array->refcount)++; + op_array->run_time_cache = NULL; + if (op_array->static_variables) { + ALLOC_HASHTABLE(op_array_copy->static_variables); + zend_hash_init( + op_array_copy->static_variables, + zend_hash_num_elements(op_array->static_variables), + NULL, ZVAL_PTR_DTOR, 0 + ); + zend_hash_apply_with_arguments( + op_array->static_variables TSRMLS_CC, + (apply_func_args_t) copy_closure_static_var, + 1, op_array_copy->static_variables + ); + } + op_array = op_array_copy; } -- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php