Skip to content

Fix static variable behavior with inheritance #6705

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 11 commits into from

Conversation

nikic
Copy link
Member

@nikic nikic commented Feb 17, 2021

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 no always keeping static_variables as the original values, and static_variables_ptr as the modified copy.

@dstogov
Copy link
Member

dstogov commented Feb 17, 2021

Everything except of closure related changes looks clear.
Please try to fix Laravel/Simphony related bug and ping me.
This change may affect some apps and should be reflected in UPGRADING doc.

To make it clearer that these arrays cannot be shared and cannot
be immutable.
We should only ever set this to a non-null value if there are
static_variables. Make sure this is the case in lazy class loading
as well.
@@ -38,6 +38,7 @@ typedef struct _zend_closure {
zend_function func;
zval this_ptr;
zend_class_entry *called_scope;
HashTable *static_variables;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand way we need this new "static_variables" and can't reuse "func.static_variables" and "static_variables_ptr".

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the changes in this file turned out to be unnecessary. I've reverted them.

@@ -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);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably, won't need special map_ptr handling for preloading now. I'll check this, after you merge the PR.


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*));
new_op_array = zend_arena_alloc(&CG(arena), sizeof(zend_op_array) + 2 * sizeof(void*));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need to allocate additional word if op_array->static_variables == NULL.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

!(GC_FLAGS(op_array->static_variables) & IS_ARRAY_IMMUTABLE)) {
GC_ADDREF(op_array->static_variables);
if (op_array->static_variables) {
GC_TRY_ADDREF(op_array->static_variables);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need this increment? I guess, we did this to trigger CoW and keep original values.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this addref is not needed anymore. I've dropped it.

@php-pulls php-pulls closed this in 5d160e3 Feb 18, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants