gron Tue, 08 Jun 2010 15:56:36 +0000 Revision: http://svn.php.net/viewvc?view=revision&revision=300283
Log: Fixed issue with statics in traits. #Please review this change, I moved the routine which copies statics from the closure code to zend_variables.c #Please also have a look to check whether the TSRMLS_DC is correct, and whether it fits with the rest in zend_variables, because there you are using some macro magic and I am not exactly sure what the reason is for that. Changed paths: A php/php-src/trunk/Zend/tests/traits/language012.phpt A php/php-src/trunk/Zend/tests/traits/language013.phpt U php/php-src/trunk/Zend/zend_closures.c U php/php-src/trunk/Zend/zend_compile.c U php/php-src/trunk/Zend/zend_variables.c U php/php-src/trunk/Zend/zend_variables.h Added: php/php-src/trunk/Zend/tests/traits/language012.phpt =================================================================== --- php/php-src/trunk/Zend/tests/traits/language012.phpt (rev 0) +++ php/php-src/trunk/Zend/tests/traits/language012.phpt 2010-06-08 15:56:36 UTC (rev 300283) @@ -0,0 +1,27 @@ +--TEST-- +Statics should work in traits, too. +--FILE-- +<?php +error_reporting(E_ALL); + +trait Counter { + public function inc() { + static $c = 0; + $c = $c + 1; + echo "$c\n"; + } +} + + +class C1 { + use Counter; +} + +$o = new C1(); +$o->inc(); +$o->inc(); + +?> +--EXPECTF-- +1 +2 Added: php/php-src/trunk/Zend/tests/traits/language013.phpt =================================================================== --- php/php-src/trunk/Zend/tests/traits/language013.phpt (rev 0) +++ php/php-src/trunk/Zend/tests/traits/language013.phpt 2010-06-08 15:56:36 UTC (rev 300283) @@ -0,0 +1,37 @@ +--TEST-- +Statics work like expected for language-based copy'n'paste. No link between methods from the same trait. +--FILE-- +<?php +error_reporting(E_ALL); + +trait Counter { + public function inc() { + static $c = 0; + $c = $c + 1; + echo "$c\n"; + } +} + + +class C1 { + use Counter; +} + +class C2 { + use Counter; +} + +$o = new C1(); +$o->inc(); +$o->inc(); + +$p = new C2(); +$p->inc(); +$p->inc(); + +?> +--EXPECTF-- +1 +2 +1 +2 Modified: php/php-src/trunk/Zend/zend_closures.c =================================================================== --- php/php-src/trunk/Zend/zend_closures.c 2010-06-08 15:47:51 UTC (rev 300282) +++ php/php-src/trunk/Zend/zend_closures.c 2010-06-08 15:56:36 UTC (rev 300283) @@ -398,43 +398,6 @@ } /* }}} */ -static int zval_copy_static_var(zval **p TSRMLS_DC, int num_args, va_list args, zend_hash_key *key) /* {{{ */ -{ - HashTable *target = va_arg(args, HashTable*); - zend_bool is_ref; - - if (Z_TYPE_PP(p) & (IS_LEXICAL_VAR|IS_LEXICAL_REF)) { - is_ref = Z_TYPE_PP(p) & IS_LEXICAL_REF; - - if (!EG(active_symbol_table)) { - zend_rebuild_symbol_table(TSRMLS_C); - } - if (zend_hash_quick_find(EG(active_symbol_table), key->arKey, key->nKeyLength, key->h, (void **) &p) == FAILURE) { - if (is_ref) { - zval *tmp; - - ALLOC_INIT_ZVAL(tmp); - Z_SET_ISREF_P(tmp); - zend_hash_quick_add(EG(active_symbol_table), key->arKey, key->nKeyLength, key->h, &tmp, sizeof(zval*), (void**)&p); - } else { - p = &EG(uninitialized_zval_ptr); - zend_error(E_NOTICE,"Undefined variable: %s", key->arKey); - } - } else { - if (is_ref) { - SEPARATE_ZVAL_TO_MAKE_IS_REF(p); - } else if (Z_ISREF_PP(p)) { - SEPARATE_ZVAL(p); - } - } - } - if (zend_hash_quick_add(target, key->arKey, key->nKeyLength, key->h, p, sizeof(zval*), NULL) == SUCCESS) { - Z_ADDREF_PP(p); - } - return ZEND_HASH_APPLY_KEEP; -} -/* }}} */ - ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_entry *scope, zval *this_ptr TSRMLS_DC) /* {{{ */ { zend_closure *closure; Modified: php/php-src/trunk/Zend/zend_compile.c =================================================================== --- php/php-src/trunk/Zend/zend_compile.c 2010-06-08 15:47:51 UTC (rev 300282) +++ php/php-src/trunk/Zend/zend_compile.c 2010-06-08 15:56:36 UTC (rev 300283) @@ -3476,8 +3476,9 @@ zval tmpZval; ALLOC_HASHTABLE(tmpHash); - zend_hash_init(tmpHash, 2, NULL, ZVAL_PTR_DTOR, 0); - zend_hash_copy(tmpHash, fe->op_array.static_variables, ZVAL_COPY_CTOR, &tmpZval, sizeof(zval)); + zend_hash_init(tmpHash, zend_hash_num_elements(fe->op_array.static_variables), NULL, ZVAL_PTR_DTOR, 0); + zend_hash_apply_with_arguments(tmpHash TSRMLS_CC, (apply_func_args_t)zval_copy_static_var, 1, fe->op_array.static_variables); + fe->op_array.static_variables = tmpHash; } Modified: php/php-src/trunk/Zend/zend_variables.c =================================================================== --- php/php-src/trunk/Zend/zend_variables.c 2010-06-08 15:47:51 UTC (rev 300282) +++ php/php-src/trunk/Zend/zend_variables.c 2010-06-08 15:56:36 UTC (rev 300283) @@ -188,6 +188,43 @@ } #endif +ZEND_API int zval_copy_static_var(zval **p TSRMLS_DC, int num_args, va_list args, zend_hash_key *key) /* {{{ */ +{ + HashTable *target = va_arg(args, HashTable*); + zend_bool is_ref; + + if (Z_TYPE_PP(p) & (IS_LEXICAL_VAR|IS_LEXICAL_REF)) { + is_ref = Z_TYPE_PP(p) & IS_LEXICAL_REF; + + if (!EG(active_symbol_table)) { + zend_rebuild_symbol_table(TSRMLS_C); + } + if (zend_hash_quick_find(EG(active_symbol_table), key->arKey, key->nKeyLength, key->h, (void **) &p) == FAILURE) { + if (is_ref) { + zval *tmp; + + ALLOC_INIT_ZVAL(tmp); + Z_SET_ISREF_P(tmp); + zend_hash_quick_add(EG(active_symbol_table), key->arKey, key->nKeyLength, key->h, &tmp, sizeof(zval*), (void**)&p); + } else { + p = &EG(uninitialized_zval_ptr); + zend_error(E_NOTICE,"Undefined variable: %s", key->arKey); + } + } else { + if (is_ref) { + SEPARATE_ZVAL_TO_MAKE_IS_REF(p); + } else if (Z_ISREF_PP(p)) { + SEPARATE_ZVAL(p); + } + } + } + if (zend_hash_quick_add(target, key->arKey, key->nKeyLength, key->h, p, sizeof(zval*), NULL) == SUCCESS) { + Z_ADDREF_PP(p); + } + return ZEND_HASH_APPLY_KEEP; +} +/* }}} */ + /* * Local variables: * tab-width: 4 Modified: php/php-src/trunk/Zend/zend_variables.h =================================================================== --- php/php-src/trunk/Zend/zend_variables.h 2010-06-08 15:47:51 UTC (rev 300282) +++ php/php-src/trunk/Zend/zend_variables.h 2010-06-08 15:56:36 UTC (rev 300283) @@ -45,6 +45,7 @@ _zval_copy_ctor_func(zvalue ZEND_FILE_LINE_RELAY_CC); } +ZEND_API int zval_copy_static_var(zval **p TSRMLS_DC, int num_args, va_list args, zend_hash_key *key); ZEND_API int zend_print_variable(zval *var); ZEND_API void _zval_ptr_dtor(zval **zval_ptr ZEND_FILE_LINE_DC);
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php