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