]> granicus.if.org Git - php/commitdiff
Fixed issue with statics in traits.
authorStefan Marr <gron@php.net>
Tue, 8 Jun 2010 15:56:36 +0000 (15:56 +0000)
committerStefan Marr <gron@php.net>
Tue, 8 Jun 2010 15:56:36 +0000 (15:56 +0000)
#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.

Zend/tests/traits/language012.phpt [new file with mode: 0644]
Zend/tests/traits/language013.phpt [new file with mode: 0644]
Zend/zend_closures.c
Zend/zend_compile.c
Zend/zend_variables.c
Zend/zend_variables.h

diff --git a/Zend/tests/traits/language012.phpt b/Zend/tests/traits/language012.phpt
new file mode 100644 (file)
index 0000000..481dd64
--- /dev/null
@@ -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
diff --git a/Zend/tests/traits/language013.phpt b/Zend/tests/traits/language013.phpt
new file mode 100644 (file)
index 0000000..a55cbbe
--- /dev/null
@@ -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
index 20cbd9066959c7f4cd02d28fa1f2d1ca4454e9c6..b40b9222db418db6931e8b8198808c3332ea4689 100644 (file)
@@ -398,43 +398,6 @@ void zend_register_closure_ce(TSRMLS_D) /* {{{ */
 }
 /* }}} */
 
-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;
index 879a1dab66544efd70d22706e460da2a970f5830..87e494110b7936917841a81f8bb6d354a2ff2e80 100644 (file)
@@ -3476,8 +3476,9 @@ static void zend_traits_duplicate_function(zend_function *fe, char *newname)
                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;
        }
 
index f6f1ea728e0e06db5c4c6bfc397bb28b010dd844..67b08b480291be5232f5a179738cd08729f25848 100644 (file)
@@ -188,6 +188,43 @@ ZEND_API void _zval_internal_ptr_dtor_wrapper(zval **zval_ptr)
 }
 #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
index 87016433337f38f41350729dfcdc887b80437994..baf905fa5cdff61bde66563f838802c81a13ca25 100644 (file)
@@ -45,6 +45,7 @@ static zend_always_inline void _zval_copy_ctor(zval *zvalue ZEND_FILE_LINE_DC)
        _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);