Skip to content

Instantly share code, notes, and snippets.

@dstogov
Created February 10, 2021 09:44
Show Gist options
  • Save dstogov/5f6b6f797a67b7fb3cefac05f9a8b9f0 to your computer and use it in GitHub Desktop.
Save dstogov/5f6b6f797a67b7fb3cefac05f9a8b9f0 to your computer and use it in GitHub Desktop.
diff --git a/Zend/tests/anon/015.phpt b/Zend/tests/anon/015.phpt
index 324ebe880a..f55c4b2605 100644
--- a/Zend/tests/anon/015.phpt
+++ b/Zend/tests/anon/015.phpt
@@ -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)
diff --git a/Zend/tests/anon/016.phpt b/Zend/tests/anon/016.phpt
index 4cde6dfeab..a5607cda74 100644
--- a/Zend/tests/anon/016.phpt
+++ b/Zend/tests/anon/016.phpt
@@ -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/method_static_var.phpt b/Zend/tests/method_static_var.phpt
index 06574732d7..60cbf22c0c 100644
--- a/Zend/tests/method_static_var.phpt
+++ b/Zend/tests/method_static_var.phpt
@@ -22,5 +22,5 @@ Bar::test();
--EXPECT--
int(1)
int(2)
+int(1)
int(2)
-int(3)
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index d617547f81..d66ab5eae5 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -7088,6 +7088,18 @@ void zend_compile_func_decl(znode *result, zend_ast *ast, bool toplevel) /* {{{
zend_check_magic_method_implementation(
CG(active_class_entry), (zend_function *) op_array, method_lcname, E_COMPILE_ERROR);
zend_string_release_ex(method_lcname, 0);
+
+ if (CG(active_op_array)->static_variables) {
+ /* This separates default and run-time values of static variables
+ * to prevent capturing of run-time values during inheritance.
+ * This cheanges behavior of the following tests:
+ * - Zend/tests/method_static_var.phpt
+ * - Zend/tests/anon/015.phpt
+ * - Zend/tests/anon/016.phpt
+ * - ext/opcache/tests/preload_method_static_vars.phpt
+ */
+ GC_ADDREF(CG(active_op_array)->static_variables);
+ }
}
/* put the implicit return on the really last line */
diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c
index 32d03acb4a..8e9b0e67ef 100644
--- a/Zend/zend_inheritance.c
+++ b/Zend/zend_inheritance.c
@@ -101,14 +101,7 @@ static zend_function *zend_duplicate_user_function(zend_function *func) /* {{{ *
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);
- }
+ GC_TRY_ADDREF(new_function->op_array.static_variables);
return new_function;
}
diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c
index 9819e7acdd..94dda90e8c 100644
--- a/ext/opcache/ZendAccelerator.c
+++ b/ext/opcache/ZendAccelerator.c
@@ -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();
diff --git a/ext/opcache/tests/preload_method_static_vars.phpt b/ext/opcache/tests/preload_method_static_vars.phpt
index f3d211793c..05716c91e5 100644
--- a/ext/opcache/tests/preload_method_static_vars.phpt
+++ b/ext/opcache/tests/preload_method_static_vars.phpt
@@ -18,8 +18,8 @@ Bar::test();
--EXPECT--
int(1)
int(2)
+int(1)
int(2)
-int(3)
int(1)
int(1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment