diff options
-rw-r--r-- | Zend/zend_API.c | 74 | ||||
-rw-r--r-- | Zend/zend_compile.c | 26 | ||||
-rw-r--r-- | Zend/zend_vm_def.h | 4 | ||||
-rw-r--r-- | Zend/zend_vm_execute.h | 48 | ||||
-rw-r--r-- | ext/reflection/php_reflection.c | 2 |
5 files changed, 101 insertions, 53 deletions
diff --git a/Zend/zend_API.c b/Zend/zend_API.c index de9db824a7..85cf32e32c 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -1140,10 +1140,42 @@ static int zval_update_class_constant(zval *pp, int is_static, int offset TSRMLS ZEND_API void zend_update_class_constants(zend_class_entry *class_type TSRMLS_DC) /* {{{ */ { - if ((class_type->ce_flags & ZEND_ACC_CONSTANTS_UPDATED) == 0 || (!CE_STATIC_MEMBERS(class_type) && class_type->default_static_members_count)) { + int i; + + /* initialize static members of internal class */ + if (!CE_STATIC_MEMBERS(class_type) && class_type->default_static_members_count) { + zval *p; + + if (class_type->parent) { + zend_update_class_constants(class_type->parent TSRMLS_CC); + } +#if ZTS + CG(static_members_table)[(zend_intptr_t)(class_type->static_members_table)] = emalloc(sizeof(zval*) * class_type->default_static_members_count); +#else + class_type->static_members_table = emalloc(sizeof(zval*) * class_type->default_static_members_count); +#endif + for (i = 0; i < class_type->default_static_members_count; i++) { + p = &class_type->default_static_members_table[i]; + if (Z_ISREF_P(p) && + class_type->parent && + i < class_type->parent->default_static_members_count && + p == &class_type->parent->default_static_members_table[i] && + Z_TYPE(CE_STATIC_MEMBERS(class_type->parent)[i]) != IS_UNDEF + ) { + zval *q = &CE_STATIC_MEMBERS(class_type->parent)[i]; + + ZVAL_NEW_REF(q, q); + ZVAL_COPY_VALUE(&CE_STATIC_MEMBERS(class_type)[i], q); + Z_ADDREF_P(q); + } else { + ZVAL_DUP(&CE_STATIC_MEMBERS(class_type)[i], p); + } + } + } + + if ((class_type->ce_flags & ZEND_ACC_CONSTANTS_UPDATED) == 0) { zend_class_entry **scope = EG(in_execution)?&EG(scope):&CG(active_class_entry); zend_class_entry *old_scope = *scope; - int i; zval *val; *scope = class_type; @@ -1158,36 +1190,6 @@ ZEND_API void zend_update_class_constants(zend_class_entry *class_type TSRMLS_DC } } - if (!CE_STATIC_MEMBERS(class_type) && class_type->default_static_members_count) { - zval *p; - - if (class_type->parent) { - zend_update_class_constants(class_type->parent TSRMLS_CC); - } -#if ZTS - CG(static_members_table)[(zend_intptr_t)(class_type->static_members_table)] = emalloc(sizeof(zval*) * class_type->default_static_members_count); -#else - class_type->static_members_table = emalloc(sizeof(zval*) * class_type->default_static_members_count); -#endif - for (i = 0; i < class_type->default_static_members_count; i++) { - p = &class_type->default_static_members_table[i]; - if (Z_ISREF_P(p) && - class_type->parent && - i < class_type->parent->default_static_members_count && - p == &class_type->parent->default_static_members_table[i] && - Z_TYPE(CE_STATIC_MEMBERS(class_type->parent)[i]) != IS_UNDEF - ) { - zval *q = &CE_STATIC_MEMBERS(class_type->parent)[i]; - - ZVAL_NEW_REF(q, q); - ZVAL_COPY_VALUE(&CE_STATIC_MEMBERS(class_type)[i], q); - Z_ADDREF_P(q); - } else { - ZVAL_DUP(&CE_STATIC_MEMBERS(class_type)[i], p); - } - } - } - for (i = 0; i < class_type->default_static_members_count; i++) { zval_update_class_constant(&CE_STATIC_MEMBERS(class_type)[i], 1, i TSRMLS_CC); } @@ -2616,7 +2618,7 @@ static zend_class_entry *do_register_internal_class(zend_class_entry *orig_class class_entry->type = ZEND_INTERNAL_CLASS; zend_initialize_class_data(class_entry, 0 TSRMLS_CC); - class_entry->ce_flags = ce_flags; + class_entry->ce_flags = ce_flags | ZEND_ACC_CONSTANTS_UPDATED; class_entry->info.internal.module = EG(current_module); if (class_entry->info.internal.builtin_functions) { @@ -3548,6 +3550,9 @@ ZEND_API int zend_declare_property_ex(zend_class_entry *ce, zend_string *name, z { zend_property_info property_info, *property_info_ptr; + if (Z_CONSTANT_P(property)) { + ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED; + } if (!(access_type & ZEND_ACC_PPP_MASK)) { access_type |= ZEND_ACC_PUBLIC; } @@ -3681,6 +3686,9 @@ ZEND_API int zend_declare_property_stringl(zend_class_entry *ce, const char *nam ZEND_API int zend_declare_class_constant(zend_class_entry *ce, const char *name, size_t name_length, zval *value TSRMLS_DC) /* {{{ */ { + if (Z_CONSTANT_P(value)) { + ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED; + } return zend_hash_str_update(&ce->constants_table, name, name_length, value) ? SUCCESS : FAILURE; } diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 910707bcb0..f950af6877 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -3719,6 +3719,9 @@ static void do_inherit_class_constant(zend_string *name, zval *zv, zend_class_en ZVAL_NEW_REF(zv, zv); } } + if (Z_CONSTANT_P(Z_REFVAL_P(zv))) { + ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED; + } if (zend_hash_add(&ce->constants_table, name, zv)) { Z_ADDREF_P(zv); } @@ -3766,11 +3769,17 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent #ifdef ZTS if (parent_ce->type != ce->type) { ZVAL_DUP(&ce->default_properties_table[i], &parent_ce->default_properties_table[i]); + if (Z_OPT_CONSTANT(ce->default_properties_table[i])) { + ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED; + } continue; } #endif ZVAL_COPY(&ce->default_properties_table[i], &parent_ce->default_properties_table[i]); + if (Z_OPT_CONSTANT(ce->default_properties_table[i])) { + ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED; + } } ce->default_properties_count += parent_ce->default_properties_count; } @@ -3791,6 +3800,9 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent ZVAL_MAKE_REF(&CE_STATIC_MEMBERS(parent_ce)[i]); ce->default_static_members_table[i] = CE_STATIC_MEMBERS(parent_ce)[i]; Z_ADDREF(ce->default_static_members_table[i]); + if (Z_CONSTANT_P(Z_REFVAL(ce->default_static_members_table[i]))) { + ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED; + } } ce->default_static_members_count += parent_ce->default_static_members_count; ce->static_members_table = ce->default_static_members_table; @@ -3809,6 +3821,9 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent ZVAL_MAKE_REF(&parent_ce->default_static_members_table[i]); ce->default_static_members_table[i] = parent_ce->default_static_members_table[i]; Z_ADDREF(ce->default_static_members_table[i]); + if (Z_CONSTANT_P(Z_REFVAL(ce->default_static_members_table[i]))) { + ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED; + } } ce->default_static_members_count += parent_ce->default_static_members_count; if (ce->type == ZEND_USER_CLASS) { @@ -5446,8 +5461,6 @@ void zend_do_declare_property(znode *var_name, znode *value, zend_uint access_ty void zend_do_declare_class_constant(znode *var_name, znode *value TSRMLS_DC) /* {{{ */ { - zval property; - if ((Z_TYPE(value->u.constant) == IS_ARRAY) || (Z_TYPE(value->u.constant) == IS_CONSTANT_AST && Z_ASTVAL(value->u.constant)->kind == ZEND_INIT_ARRAY)) { @@ -5459,13 +5472,14 @@ void zend_do_declare_class_constant(znode *var_name, znode *value TSRMLS_DC) /* return; } - ZVAL_COPY_VALUE(&property, &value->u.constant); - Z_STR(var_name->u.constant) = zend_new_interned_string(Z_STR(var_name->u.constant) TSRMLS_CC); if (IS_INTERNED(Z_STR(var_name->u.constant))) { Z_TYPE_FLAGS(var_name->u.constant) &= ~ (IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE); } - if (zend_hash_add(&CG(active_class_entry)->constants_table, Z_STR(var_name->u.constant), &property) == NULL) { + if (Z_CONSTANT(value->u.constant)) { + CG(active_class_entry)->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED; + } + if (zend_hash_add(&CG(active_class_entry)->constants_table, Z_STR(var_name->u.constant), &value->u.constant) == NULL) { zend_error_noreturn(E_COMPILE_ERROR, "Cannot redefine class constant %s::%s", CG(active_class_entry)->name->val, Z_STRVAL(var_name->u.constant)); } FREE_PNODE(var_name); @@ -6987,7 +7001,7 @@ ZEND_API void zend_initialize_class_data(zend_class_entry *ce, zend_bool nullify dtor_func_t zval_ptr_dtor_func = ((persistent_hashes) ? ZVAL_INTERNAL_PTR_DTOR : ZVAL_PTR_DTOR); ce->refcount = 1; - ce->ce_flags = 0; + ce->ce_flags = ZEND_ACC_CONSTANTS_UPDATED; ce->default_properties_table = NULL; ce->default_static_members_table = NULL; diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 690a8269b9..38377d3cce 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -1189,7 +1189,9 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMP|VAR|CV, UNUSED|CONST| } } if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) { - zval_update_constant(retval, 1 TSRMLS_CC); + if (Z_CONSTANT_P(retval)) { + zval_update_constant(retval, 1 TSRMLS_CC); + } } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { FREE_OP1(); } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index e37cba17ae..b69dcbf711 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -3684,7 +3684,9 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_CONST(int type } } if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) { - zval_update_constant(retval, 1 TSRMLS_CC); + if (Z_CONSTANT_P(retval)) { + zval_update_constant(retval, 1 TSRMLS_CC); + } } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { } @@ -5508,7 +5510,9 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_VAR(int type, } } if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) { - zval_update_constant(retval, 1 TSRMLS_CC); + if (Z_CONSTANT_P(retval)) { + zval_update_constant(retval, 1 TSRMLS_CC); + } } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { } @@ -6218,7 +6222,9 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_UNUSED(int typ } } if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) { - zval_update_constant(retval, 1 TSRMLS_CC); + if (Z_CONSTANT_P(retval)) { + zval_update_constant(retval, 1 TSRMLS_CC); + } } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { } @@ -8930,7 +8936,9 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_CONST(int type, } } if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) { - zval_update_constant(retval, 1 TSRMLS_CC); + if (Z_CONSTANT_P(retval)) { + zval_update_constant(retval, 1 TSRMLS_CC); + } } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { zval_dtor(free_op1.var); } @@ -10615,7 +10623,9 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_VAR(int type, ZE } } if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) { - zval_update_constant(retval, 1 TSRMLS_CC); + if (Z_CONSTANT_P(retval)) { + zval_update_constant(retval, 1 TSRMLS_CC); + } } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { zval_dtor(free_op1.var); } @@ -11325,7 +11335,9 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_UNUSED(int type, } } if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) { - zval_update_constant(retval, 1 TSRMLS_CC); + if (Z_CONSTANT_P(retval)) { + zval_update_constant(retval, 1 TSRMLS_CC); + } } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { zval_dtor(free_op1.var); } @@ -14826,7 +14838,9 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_CONST(int type, } } if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) { - zval_update_constant(retval, 1 TSRMLS_CC); + if (Z_CONSTANT_P(retval)) { + zval_update_constant(retval, 1 TSRMLS_CC); + } } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { zval_ptr_dtor_nogc(free_op1.var); } @@ -19181,7 +19195,9 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_VAR(int type, ZE } } if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) { - zval_update_constant(retval, 1 TSRMLS_CC); + if (Z_CONSTANT_P(retval)) { + zval_update_constant(retval, 1 TSRMLS_CC); + } } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { zval_ptr_dtor_nogc(free_op1.var); } @@ -21070,7 +21086,9 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_UNUSED(int type, } } if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) { - zval_update_constant(retval, 1 TSRMLS_CC); + if (Z_CONSTANT_P(retval)) { + zval_update_constant(retval, 1 TSRMLS_CC); + } } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { zval_ptr_dtor_nogc(free_op1.var); } @@ -31798,7 +31816,9 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_CONST(int type, Z } } if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) { - zval_update_constant(retval, 1 TSRMLS_CC); + if (Z_CONSTANT_P(retval)) { + zval_update_constant(retval, 1 TSRMLS_CC); + } } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { } @@ -35850,7 +35870,9 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_VAR(int type, ZEN } } if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) { - zval_update_constant(retval, 1 TSRMLS_CC); + if (Z_CONSTANT_P(retval)) { + zval_update_constant(retval, 1 TSRMLS_CC); + } } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { } @@ -37621,7 +37643,9 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_UNUSED(int type, } } if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) { - zval_update_constant(retval, 1 TSRMLS_CC); + if (Z_CONSTANT_P(retval)) { + zval_update_constant(retval, 1 TSRMLS_CC); + } } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { } diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 8611c9c8e2..678e328f68 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -4142,7 +4142,7 @@ ZEND_METHOD(reflection_class, getModifiers) } GET_REFLECTION_OBJECT_PTR(ce); - RETURN_LONG(ce->ce_flags); + RETURN_LONG(ce->ce_flags & ~ZEND_ACC_CONSTANTS_UPDATED); } /* }}} */ |