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

Reply via email to