]> granicus.if.org Git - php/commitdiff
Fix static variable behavior with inheritance
authorNikita Popov <nikita.ppv@gmail.com>
Wed, 17 Feb 2021 09:47:30 +0000 (10:47 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Thu, 18 Feb 2021 10:18:19 +0000 (11:18 +0100)
When a method is inherited, the static variables will now always
use the initial values, rather than the values at the time of
inheritance. As such, behavior no longer depends on whether
inheritance happens before or after a method has been called.

This is implemented by always keeping static_variables as the
original values, and static_variables_ptr as the modified copy.

Closes GH-6705.

19 files changed:
UPGRADING
Zend/tests/anon/015.phpt
Zend/tests/anon/016.phpt
Zend/tests/closure_bindTo_preserves_used_variables.phpt [new file with mode: 0644]
Zend/tests/method_static_var.phpt
Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_execute_API.c
Zend/zend_inheritance.c
Zend/zend_language_scanner.l
Zend/zend_opcode.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h
ext/opcache/ZendAccelerator.c
ext/opcache/tests/preload_method_static_vars.phpt
ext/opcache/zend_accelerator_util_funcs.c
ext/opcache/zend_file_cache.c
ext/opcache/zend_persist.c
ext/reflection/php_reflection.c

index 5d72233e904ea5ce90f82820ef119c1b19ec1b24..0bc8f818085bc2aff8d2a90325dbb3e536e974a3 100644 (file)
--- a/UPGRADING
+++ b/UPGRADING
@@ -37,6 +37,28 @@ PHP 8.1 UPGRADE NOTES
         //             is deprecated
 
     RFC: https://wiki.php.net/rfc/deprecate_null_to_scalar_internal_arg
+  . When a method using static variables is inherited, the inherited method
+    will now initialize the static variables to their original values, rather
+    than the values at the time of inheritance:
+
+        class A {
+            public function counter() {
+                static $counter = 0;
+                $counter++;
+                return $counter;
+            }
+        }
+
+        var_dump((new A)->counter()); // int(1)
+
+        eval('class B extends A {}'); // eval() to prevent early binding.
+
+        var_dump((new B)->counter()); // int(1), previously int(2)
+        var_dump((new A)->counter()); // int(2)
+        var_dump((new B)->counter()); // int(2), previously int(3)
+
+    Previously the behavior would be different depending on whether A::counter()
+    was called before class B was declared, or after it was declared.
 
 - Fileinfo:
   . The fileinfo functions now accept and return, respectively, finfo objects
index 324ebe880aebdb0ce21fff32b9f96e38c739312b..f55c4b26052596f4ee96c8950d7376874fdf689b 100644 (file)
@@ -19,10 +19,7 @@ var_dump($d->foo(24));
 var_dump($c->foo());
 ?>
 --EXPECT--
-array(1) {
-  [0]=>
-  int(42)
-}
+NULL
 array(1) {
   [0]=>
   int(24)
index 4cde6dfeaba2b9ec16b5e21490980840285c805e..a5607cda74e1ab2ed764b9de8bcf4b4f07581c6e 100644 (file)
@@ -19,11 +19,7 @@ var_dump($d->foo(24));
 var_dump($c->foo());
 ?>
 --EXPECT--
-array(1) {
-  [0]=>
-  object(stdClass)#2 (0) {
-  }
-}
+NULL
 array(1) {
   [0]=>
   int(24)
diff --git a/Zend/tests/closure_bindTo_preserves_used_variables.phpt b/Zend/tests/closure_bindTo_preserves_used_variables.phpt
new file mode 100644 (file)
index 0000000..cec68ea
--- /dev/null
@@ -0,0 +1,17 @@
+--TEST--
+Closure::bindTo() should preserve used variables
+--FILE--
+<?php
+
+$var = 0;
+$fn = function() use($var) {
+    var_dump($var);
+};
+$fn();
+$fn = $fn->bindTo(null, null);
+$fn();
+
+?>
+--EXPECT--
+int(0)
+int(0)
index 06574732d75609848d6612cd6bc34cfec932f010..f92e6d3a5d3f6a8d2c3666879c28cf4509673c94 100644 (file)
@@ -3,8 +3,6 @@ Initial value of static var in method depends on the include time of the class d
 --FILE--
 <?php
 
-/* The current behavior is probably a bug, but we should still test how it currently works. */
-
 class Foo {
     public static function test() {
         static $i = 0;
@@ -22,5 +20,5 @@ Bar::test();
 --EXPECT--
 int(1)
 int(2)
+int(1)
 int(2)
-int(3)
index 5d566b43a5a384e21104b5b04bdadf04efd83c8d..d76b8f74ec83859dcfa4bc045e0472ac788c2e04 100644 (file)
@@ -1029,28 +1029,32 @@ static uint32_t zend_add_try_element(uint32_t try_op) /* {{{ */
 }
 /* }}} */
 
+void zend_init_static_variables_map_ptr(zend_op_array *op_array)
+{
+       if (op_array->static_variables) {
+               ZEND_MAP_PTR_INIT(op_array->static_variables_ptr,
+                       zend_arena_alloc(&CG(arena), sizeof(HashTable *)));
+               ZEND_MAP_PTR_SET(op_array->static_variables_ptr, NULL);
+       }
+}
+
 ZEND_API void function_add_ref(zend_function *function) /* {{{ */
 {
        if (function->type == ZEND_USER_FUNCTION) {
                zend_op_array *op_array = &function->op_array;
-
                if (op_array->refcount) {
                        (*op_array->refcount)++;
                }
-               if (op_array->static_variables
-                       && !(GC_FLAGS(op_array->static_variables) & IS_ARRAY_IMMUTABLE)) {
-                       GC_ADDREF(op_array->static_variables);
-               }
 
                if (CG(compiler_options) & ZEND_COMPILE_PRELOAD) {
                        ZEND_ASSERT(op_array->fn_flags & ZEND_ACC_PRELOADED);
                        ZEND_MAP_PTR_NEW(op_array->run_time_cache);
-                       ZEND_MAP_PTR_NEW(op_array->static_variables_ptr);
                } else {
-                       ZEND_MAP_PTR_INIT(op_array->static_variables_ptr, &op_array->static_variables);
-                       ZEND_MAP_PTR_INIT(op_array->run_time_cache, zend_arena_alloc(&CG(arena), sizeof(void*)));
+                       ZEND_MAP_PTR_INIT(op_array->run_time_cache, zend_arena_alloc(&CG(arena), sizeof(void *)));
                        ZEND_MAP_PTR_SET(op_array->run_time_cache, NULL);
                }
+
+               zend_init_static_variables_map_ptr(op_array);
        }
 
        if (function->common.function_name) {
@@ -7021,9 +7025,8 @@ void zend_compile_func_decl(znode *result, zend_ast *ast, bool toplevel) /* {{{
        if (CG(compiler_options) & ZEND_COMPILE_PRELOAD) {
                op_array->fn_flags |= ZEND_ACC_PRELOADED;
                ZEND_MAP_PTR_NEW(op_array->run_time_cache);
-               ZEND_MAP_PTR_NEW(op_array->static_variables_ptr);
        } else {
-               ZEND_MAP_PTR_INIT(op_array->run_time_cache, zend_arena_alloc(&CG(arena), sizeof(void*)));
+               ZEND_MAP_PTR_INIT(op_array->run_time_cache, zend_arena_alloc(&CG(arena), sizeof(void *)));
                ZEND_MAP_PTR_SET(op_array->run_time_cache, NULL);
        }
 
@@ -7112,6 +7115,7 @@ void zend_compile_func_decl(znode *result, zend_ast *ast, bool toplevel) /* {{{
        zend_do_extended_stmt();
        zend_emit_final_return(0);
 
+       zend_init_static_variables_map_ptr(op_array);
        pass_two(CG(active_op_array));
        zend_oparray_context_end(&orig_oparray_context);
 
index fbab084b2b4171fbd45c091e13c77129b960440c..ce4b50aaee3c2a63eebeb1fbba1e90a083fd160c 100644 (file)
@@ -795,6 +795,7 @@ void zend_verify_namespace(void);
 void zend_resolve_goto_label(zend_op_array *op_array, zend_op *opline);
 
 ZEND_API void function_add_ref(zend_function *function);
+void zend_init_static_variables_map_ptr(zend_op_array *op_array);
 
 #define INITIAL_OP_ARRAY_SIZE 64
 
index 7c32f3a7fbf559165051db10c3ebb87031be6baa..1d484934e3e09b85423467187288163a8625e399 100644 (file)
@@ -285,10 +285,10 @@ void shutdown_executor(void) /* {{{ */
                        if (op_array->type == ZEND_INTERNAL_FUNCTION) {
                                break;
                        }
-                       if (op_array->static_variables) {
+                       if (ZEND_MAP_PTR(op_array->static_variables_ptr)) {
                                HashTable *ht = ZEND_MAP_PTR_GET(op_array->static_variables_ptr);
                                if (ht) {
-                                       zend_array_release(ht);
+                                       zend_array_destroy(ht);
                                        ZEND_MAP_PTR_SET(op_array->static_variables_ptr, NULL);
                                }
                        }
@@ -308,10 +308,10 @@ void shutdown_executor(void) /* {{{ */
                                zend_op_array *op_array;
                                ZEND_HASH_FOREACH_PTR(&ce->function_table, op_array) {
                                        if (op_array->type == ZEND_USER_FUNCTION) {
-                                               if (op_array->static_variables) {
+                                               if (ZEND_MAP_PTR(op_array->static_variables_ptr)) {
                                                        HashTable *ht = ZEND_MAP_PTR_GET(op_array->static_variables_ptr);
                                                        if (ht) {
-                                                               zend_array_release(ht);
+                                                               zend_array_destroy(ht);
                                                                ZEND_MAP_PTR_SET(op_array->static_variables_ptr, NULL);
                                                        }
                                                }
index 2c0b7a9f64248cd1b85d69249260aa2550e8c745..75f5536eaa561a4dfbb8ac0af070e10ab5d4f8e4 100644 (file)
@@ -89,28 +89,10 @@ static zend_function *zend_duplicate_internal_function(zend_function *func, zend
 
 static zend_function *zend_duplicate_user_function(zend_function *func) /* {{{ */
 {
-       zend_function *new_function;
-
-       new_function = zend_arena_alloc(&CG(arena), sizeof(zend_op_array));
-       memcpy(new_function, func, sizeof(zend_op_array));
-
-       if (CG(compiler_options) & ZEND_COMPILE_PRELOAD) {
-               ZEND_ASSERT(new_function->op_array.fn_flags & ZEND_ACC_PRELOADED);
-               ZEND_MAP_PTR_NEW(new_function->op_array.static_variables_ptr);
-       } else {
-               ZEND_MAP_PTR_INIT(new_function->op_array.static_variables_ptr, &new_function->op_array.static_variables);
-       }
-
-       HashTable *static_properties_ptr = ZEND_MAP_PTR_GET(func->op_array.static_variables_ptr);
-       if (static_properties_ptr) {
-               /* See: Zend/tests/method_static_var.phpt */
-               ZEND_MAP_PTR_SET(new_function->op_array.static_variables_ptr, static_properties_ptr);
-               GC_TRY_ADDREF(static_properties_ptr);
-       } else {
-               GC_TRY_ADDREF(new_function->op_array.static_variables);
-       }
-
-       return new_function;
+       zend_op_array *new_op_array = zend_arena_alloc(&CG(arena), sizeof(zend_op_array));
+       memcpy(new_op_array, func, sizeof(zend_op_array));
+       zend_init_static_variables_map_ptr(new_op_array);
+       return (zend_function *) new_op_array;
 }
 /* }}} */
 
@@ -2504,12 +2486,17 @@ static zend_class_entry *zend_lazy_class_load(zend_class_entry *pce)
                for (; p != end; p++) {
                        zend_op_array *op_array, *new_op_array;
                        void ***run_time_cache_ptr;
+                       size_t alloc_size;
 
                        op_array = Z_PTR(p->val);
                        ZEND_ASSERT(op_array->type == ZEND_USER_FUNCTION);
                        ZEND_ASSERT(op_array->scope == pce);
                        ZEND_ASSERT(op_array->prototype == NULL);
-                       new_op_array = zend_arena_alloc(&CG(arena), sizeof(zend_op_array) + sizeof(void*));
+                       alloc_size = sizeof(zend_op_array) + sizeof(void *);
+                       if (op_array->static_variables) {
+                               alloc_size += sizeof(HashTable *);
+                       }
+                       new_op_array = zend_arena_alloc(&CG(arena), alloc_size);
                        Z_PTR(p->val) = new_op_array;
                        memcpy(new_op_array, op_array, sizeof(zend_op_array));
                        run_time_cache_ptr = (void***)(new_op_array + 1);
@@ -2517,7 +2504,11 @@ static zend_class_entry *zend_lazy_class_load(zend_class_entry *pce)
                        new_op_array->fn_flags &= ~ZEND_ACC_IMMUTABLE;
                        new_op_array->scope = ce;
                        ZEND_MAP_PTR_INIT(new_op_array->run_time_cache, run_time_cache_ptr);
-                       ZEND_MAP_PTR_INIT(new_op_array->static_variables_ptr, &new_op_array->static_variables);
+                       if (op_array->static_variables) {
+                               HashTable **static_variables_ptr = (HashTable **) (run_time_cache_ptr + 1);
+                               *static_variables_ptr = NULL;
+                               ZEND_MAP_PTR_INIT(new_op_array->static_variables_ptr, static_variables_ptr);
+                       }
 
                        zend_update_inherited_handler(constructor);
                        zend_update_inherited_handler(destructor);
index 6f2889aac86162be0bad6cf3ae585528c084c80b..36de6aea37f521e2c3852a657b8dc1ccd2dd1100 100644 (file)
@@ -636,6 +636,7 @@ static zend_op_array *zend_compile(int type)
                zend_emit_final_return(type == ZEND_USER_FUNCTION);
                op_array->line_start = 1;
                op_array->line_end = last_lineno;
+               zend_init_static_variables_map_ptr(op_array);
                pass_two(op_array);
                zend_oparray_context_end(&original_oparray_context);
                zend_file_context_end(&original_file_context);
index abb75b8026c51eb61d9262fae27c326af62ce860..ac9cc5f7041bced4bf27e469acff6af88cddd82e 100644 (file)
@@ -77,7 +77,7 @@ void init_op_array(zend_op_array *op_array, zend_uchar type, int initial_ops_siz
        op_array->last_live_range = 0;
 
        op_array->static_variables = NULL;
-       ZEND_MAP_PTR_INIT(op_array->static_variables_ptr, &op_array->static_variables);
+       ZEND_MAP_PTR_INIT(op_array->static_variables_ptr, NULL);
        op_array->last_try_catch = 0;
 
        op_array->fn_flags = 0;
@@ -515,12 +515,10 @@ ZEND_API void destroy_op_array(zend_op_array *op_array)
 {
        uint32_t i;
 
-       if (op_array->static_variables) {
+       if (ZEND_MAP_PTR(op_array->static_variables_ptr)) {
                HashTable *ht = ZEND_MAP_PTR_GET(op_array->static_variables_ptr);
-               if (ht && !(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
-                       if (GC_DELREF(ht) == 0) {
-                               zend_array_destroy(ht);
-                       }
+               if (ht) {
+                       zend_array_destroy(ht);
                }
        }
 
@@ -599,6 +597,9 @@ ZEND_API void destroy_op_array(zend_op_array *op_array)
                }
                efree(arg_info);
        }
+       if (op_array->static_variables) {
+               zend_array_destroy(op_array->static_variables);
+       }
 }
 
 static void zend_update_extended_stmts(zend_op_array *op_array)
index 251a6a40f765d3f29317a9b8f423fa4f465d0f65..b78f8ad61e54ed7d7a2d0e299b8f3204d0fddd41 100644 (file)
@@ -8659,16 +8659,10 @@ ZEND_VM_HANDLER(183, ZEND_BIND_STATIC, CV, UNUSED, REF)
 
        ht = ZEND_MAP_PTR_GET(EX(func)->op_array.static_variables_ptr);
        if (!ht) {
-               ZEND_ASSERT(EX(func)->op_array.fn_flags & (ZEND_ACC_IMMUTABLE|ZEND_ACC_PRELOADED));
                ht = zend_array_dup(EX(func)->op_array.static_variables);
                ZEND_MAP_PTR_SET(EX(func)->op_array.static_variables_ptr, ht);
-       } else if (GC_REFCOUNT(ht) > 1) {
-               if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
-                       GC_DELREF(ht);
-               }
-               ht = zend_array_dup(ht);
-               ZEND_MAP_PTR_SET(EX(func)->op_array.static_variables_ptr, ht);
        }
+       ZEND_ASSERT(GC_REFCOUNT(ht) == 1);
 
        value = (zval*)((char*)ht->arData + (opline->extended_value & ~(ZEND_BIND_REF|ZEND_BIND_IMPLICIT)));
 
index 9e02145585c3b82b0c812a081c886849b24085f1..419de3fa264638993225ae1c5a476ac406a8d40d 100644 (file)
@@ -47468,16 +47468,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BIND_STATIC_SPEC_CV_UNUSED_HAN
 
        ht = ZEND_MAP_PTR_GET(EX(func)->op_array.static_variables_ptr);
        if (!ht) {
-               ZEND_ASSERT(EX(func)->op_array.fn_flags & (ZEND_ACC_IMMUTABLE|ZEND_ACC_PRELOADED));
                ht = zend_array_dup(EX(func)->op_array.static_variables);
                ZEND_MAP_PTR_SET(EX(func)->op_array.static_variables_ptr, ht);
-       } else if (GC_REFCOUNT(ht) > 1) {
-               if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
-                       GC_DELREF(ht);
-               }
-               ht = zend_array_dup(ht);
-               ZEND_MAP_PTR_SET(EX(func)->op_array.static_variables_ptr, ht);
        }
+       ZEND_ASSERT(GC_REFCOUNT(ht) == 1);
 
        value = (zval*)((char*)ht->arData + (opline->extended_value & ~(ZEND_BIND_REF|ZEND_BIND_IMPLICIT)));
 
index 49efc3a431a434a0043d617ec8d167b7ee9cfab9..c2e5690273f94e52339a127c5d04ce6912c65de3 100644 (file)
@@ -2323,27 +2323,6 @@ static zend_class_entry* zend_accel_inheritance_cache_get(zend_class_entry *ce,
        return NULL;
 }
 
-static bool is_array_cacheable(zval *zv)
-{
-       zval *p;
-
-       ZEND_HASH_FOREACH_VAL(Z_ARR_P(zv), p) {
-               if (Z_REFCOUNTED_P(p)) {
-                       if (Z_TYPE_P(p) == IS_ARRAY) {
-                               if (!is_array_cacheable(p)) {
-                                       /* Can't cache */
-                                       return 0;
-                               }
-                       } else if (Z_TYPE_P(p) == IS_OBJECT || Z_TYPE_P(p) == IS_RESOURCE || Z_TYPE_P(p) == IS_REFERENCE) {
-                               /* Can't cache */
-                               return 0;
-                       }
-               }
-       } ZEND_HASH_FOREACH_END();
-
-       return 1;
-}
-
 static zend_class_entry* zend_accel_inheritance_cache_add(zend_class_entry *ce, zend_class_entry *proto, zend_class_entry *parent, zend_class_entry **traits_and_interfaces, HashTable *dependencies)
 {
        zend_persistent_script dummy;
@@ -2369,44 +2348,6 @@ static zend_class_entry* zend_accel_inheritance_cache_add(zend_class_entry *ce,
                }
        }
 
-       if (ce->ce_flags & ZEND_HAS_STATIC_IN_METHODS) {
-               zend_op_array *op_array;
-               zval *zv;
-
-               ZEND_HASH_FOREACH_PTR(&ce->function_table, op_array) {
-                       if (op_array->type == ZEND_USER_FUNCTION
-                        && op_array->static_variables
-                        && !(GC_FLAGS(op_array->static_variables) & IS_ARRAY_IMMUTABLE)) {
-                               if (UNEXPECTED(GC_REFCOUNT(op_array->static_variables) > 1)) {
-                                       GC_DELREF(op_array->static_variables);
-                                       op_array->static_variables = zend_array_dup(op_array->static_variables);
-                               }
-                               ZEND_HASH_FOREACH_VAL(op_array->static_variables, zv) {
-                                       if (Z_ISREF_P(zv)) {
-                                               zend_reference *ref = Z_REF_P(zv);
-
-                                               ZVAL_COPY_VALUE(zv, &ref->val);
-                                               if (GC_DELREF(ref) == 0) {
-                                                       efree_size(ref, sizeof(zend_reference));
-                                               }
-                                       }
-                                       if (Z_REFCOUNTED_P(zv)) {
-                                               if (Z_TYPE_P(zv) == IS_ARRAY) {
-                                                       if (!is_array_cacheable(zv)) {
-                                                               /* Can't cache */
-                                                               return NULL;
-                                                       }
-                                                       SEPARATE_ARRAY(zv);
-                                               } else if (Z_TYPE_P(zv) == IS_OBJECT || Z_TYPE_P(zv) == IS_RESOURCE) {
-                                                       /* Can't cache */
-                                                       return NULL;
-                                               }
-                                       }
-                               } ZEND_HASH_FOREACH_END();
-                       }
-               } ZEND_HASH_FOREACH_END();
-       }
-
        SHM_UNPROTECT();
        zend_shared_alloc_lock();
 
@@ -3692,11 +3633,6 @@ static zend_op_array *preload_compile_file(zend_file_handle *file_handle, int ty
 //???          efree(op_array->refcount);
                op_array->refcount = NULL;
 
-               if (op_array->static_variables &&
-                   !(GC_FLAGS(op_array->static_variables) & IS_ARRAY_IMMUTABLE)) {
-                       GC_ADDREF(op_array->static_variables);
-               }
-
                zend_hash_add_ptr(preload_scripts, script->script.filename, script);
        }
 
index f3d211793c7bf46c7f2b1d3511698bd98f28af55..05716c91e52ab1b5976fa72216bb1ad02495206a 100644 (file)
@@ -18,8 +18,8 @@ Bar::test();
 --EXPECT--
 int(1)
 int(2)
+int(1)
 int(2)
-int(3)
 
 int(1)
 int(1)
index f17f7e80768aa5980615eaed8845b53a27048c4b..327e8a4d55467b36aeca3db1feb00c49e183577a 100644 (file)
@@ -219,7 +219,6 @@ zend_op_array* zend_accel_load_script(zend_persistent_script *persistent_script,
 
        op_array = (zend_op_array *) emalloc(sizeof(zend_op_array));
        *op_array = persistent_script->script.main_op_array;
-       ZEND_MAP_PTR_INIT(op_array->static_variables_ptr, &op_array->static_variables);
 
        if (zend_hash_num_elements(&persistent_script->script.function_table) > 0) {
                zend_accel_function_hash_copy(CG(function_table), &persistent_script->script.function_table);
index 4ebb23fb84a787c91f3d43e0ffcd558b7ae5057e..79487978647fc139b7478cf80f936d285712d5a0 100644 (file)
@@ -1234,12 +1234,16 @@ static void zend_file_cache_unserialize_op_array(zend_op_array           *op_arr
                if (op_array->static_variables) {
                        ZEND_MAP_PTR_NEW(op_array->static_variables_ptr);
                } else {
-                       ZEND_MAP_PTR_INIT(op_array->static_variables_ptr, &op_array->static_variables);
+                       ZEND_MAP_PTR_INIT(op_array->static_variables_ptr, NULL);
                }
                ZEND_MAP_PTR_NEW(op_array->run_time_cache);
        } else {
                op_array->fn_flags &= ~ZEND_ACC_IMMUTABLE;
-               ZEND_MAP_PTR_INIT(op_array->static_variables_ptr, &op_array->static_variables);
+               if (op_array->static_variables) {
+                       ZEND_MAP_PTR_INIT(op_array->static_variables_ptr,
+                               zend_arena_alloc(&CG(arena), sizeof(HashTable *)));
+                       ZEND_MAP_PTR_SET(op_array->static_variables_ptr, NULL);
+               }
                if (op_array != &script->script.main_op_array) {
                        ZEND_MAP_PTR_INIT(op_array->run_time_cache, zend_arena_alloc(&CG(arena), sizeof(void*)));
                        ZEND_MAP_PTR_SET(op_array->run_time_cache, NULL);
index ea6fa096b645d04fe91b256aa2d2124965aae93d..5e406ec4b6b6d181eb08a24ecca3924da513eadf 100644 (file)
@@ -686,8 +686,6 @@ static void zend_persist_op_array(zval *zv)
                if (op_array->static_variables) {
                        ZEND_MAP_PTR_NEW(op_array->static_variables_ptr);
                }
-       } else {
-               ZEND_MAP_PTR_INIT(op_array->static_variables_ptr, &op_array->static_variables);
        }
 }
 
@@ -757,8 +755,8 @@ static void zend_persist_class_method(zval *zv, zend_class_entry *ce)
        } else {
                if (ce->ce_flags & ZEND_ACC_IMMUTABLE) {
                        ZEND_MAP_PTR_INIT(op_array->run_time_cache, NULL);
+                       ZEND_MAP_PTR_INIT(op_array->static_variables_ptr, NULL);
                }
-               ZEND_MAP_PTR_INIT(op_array->static_variables_ptr, &op_array->static_variables);
        }
 }
 
@@ -1277,9 +1275,10 @@ zend_persistent_script *zend_accel_script_persist(zend_persistent_script *script
        zend_persist_op_array_ex(&script->script.main_op_array, script);
        if (!script->corrupted) {
                ZEND_MAP_PTR_INIT(script->script.main_op_array.run_time_cache, NULL);
+               if (script->script.main_op_array.static_variables) {
+                       ZEND_MAP_PTR_NEW(script->script.main_op_array.static_variables_ptr);
+               }
        }
-       ZEND_MAP_PTR_INIT(script->script.main_op_array.static_variables_ptr,
-               &script->script.main_op_array.static_variables);
        zend_persist_warnings(script);
 
        if (for_shm) {
index 2f1a358518df80add2c48dd591ac3a57f6b277d8..bd487972ec075e61c3ffd3d85e0046124c7b5b2c 100644 (file)
@@ -1796,7 +1796,6 @@ ZEND_METHOD(ReflectionFunctionAbstract, getStaticVariables)
                array_init(return_value);
                ht = ZEND_MAP_PTR_GET(fptr->op_array.static_variables_ptr);
                if (!ht) {
-                       ZEND_ASSERT(fptr->op_array.fn_flags & ZEND_ACC_IMMUTABLE);
                        ht = zend_array_dup(fptr->op_array.static_variables);
                        ZEND_MAP_PTR_SET(fptr->op_array.static_variables_ptr, ht);
                }