diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 61b1829f786..4392c4c12e1 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -1127,19 +1127,22 @@ ZEND_API int zend_update_class_constants(zend_class_entry *class_type) /* {{{ */ #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]; + if (Z_ISREF_P(p)) { + if (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); + ZVAL_NEW_REF(q, q); + ZVAL_COPY_VALUE(&CE_STATIC_MEMBERS(class_type)[i], q); + Z_ADDREF_P(q); + } else { + ZVAL_COPY_OR_DUP(&CE_STATIC_MEMBERS(class_type)[i], Z_REFVAL_P(p)); + } } else { - ZVAL_DUP(&CE_STATIC_MEMBERS(class_type)[i], p); + ZVAL_COPY_OR_DUP(&CE_STATIC_MEMBERS(class_type)[i], p); } } } else { @@ -1191,15 +1194,19 @@ ZEND_API void object_properties_init(zend_object *object, zend_class_entry *clas zval *dst = object->properties_table; zval *end = src + class_type->default_properties_count; - do { -#if ZTS - ZVAL_DUP(dst, src); -#else - ZVAL_COPY(dst, src); -#endif - src++; - dst++; - } while (src != end); + if (UNEXPECTED(class_type->type == ZEND_INTERNAL_CLASS)) { + do { + ZVAL_COPY_OR_DUP(dst, src); + src++; + dst++; + } while (src != end); + } else { + do { + ZVAL_COPY(dst, src); + src++; + dst++; + } while (src != end); + } object->properties = NULL; } } diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index 1dcf5e31e12..26177c2c726 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -301,7 +301,7 @@ ZEND_API int zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *sc ret = zend_use_undefined_constant(name, ast->attr, result); break; } - ZVAL_DUP(result, zv); + ZVAL_COPY_OR_DUP(result, zv); break; } case ZEND_AST_CONSTANT_CLASS: @@ -457,9 +457,9 @@ ZEND_API int zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *sc zend_fetch_dimension_const(&tmp, &op1, &op2, (ast->attr == ZEND_DIM_IS) ? BP_VAR_IS : BP_VAR_R); if (UNEXPECTED(Z_ISREF(tmp))) { - ZVAL_DUP(result, Z_REFVAL(tmp)); + ZVAL_COPY_OR_DUP(result, Z_REFVAL(tmp)); } else { - ZVAL_DUP(result, &tmp); + ZVAL_COPY_OR_DUP(result, &tmp); } zval_ptr_dtor(&tmp); zval_dtor(&op1); diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index 0d6cc442b67..37bf4f82e0d 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -1064,12 +1064,8 @@ static void add_class_vars(zend_class_entry *scope, zend_class_entry *ce, int st /* copy: enforce read only access */ ZVAL_DEREF(prop); - if (UNEXPECTED(Z_COPYABLE_P(prop))) { - ZVAL_DUP(&prop_copy, prop); - prop = &prop_copy; - } else { - Z_TRY_ADDREF_P(prop); - } + ZVAL_COPY_OR_DUP(&prop_copy, prop); + prop = &prop_copy; /* this is necessary to make it able to work with default array * properties, returned to user */ @@ -2032,7 +2028,7 @@ static int add_constant_info(zval *item, void *arg) /* {{{ */ return 0; } - ZVAL_DUP(&const_val, &constant->value); + ZVAL_COPY_OR_DUP(&const_val, &constant->value); zend_hash_add_new(Z_ARRVAL_P(name_array), constant->name, &const_val); return 0; } @@ -2108,7 +2104,7 @@ ZEND_FUNCTION(get_defined_constants) add_assoc_zval(return_value, module_names[module_number], &modules[module_number]); } - ZVAL_DUP(&const_val, &val->value); + ZVAL_COPY_OR_DUP(&const_val, &val->value); zend_hash_add_new(Z_ARRVAL(modules[module_number]), val->name, &const_val); } ZEND_HASH_FOREACH_END(); diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 11c56cc60c2..e7657bee7f0 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -98,12 +98,6 @@ static void zend_destroy_property_info_internal(zval *zv) /* {{{ */ } /* }}} */ -static void zend_destroy_class_constant_internal(zval *zv) /* {{{ */ -{ - free(Z_PTR_P(zv)); -} -/* }}} */ - static zend_string *zend_new_interned_string_safe(zend_string *str) /* {{{ */ { zend_string *interned_str; @@ -1402,7 +1396,7 @@ static zend_bool zend_try_ct_eval_const(zval *zv, zend_string *name, zend_bool i ((c->flags & CONST_PERSISTENT) && !(CG(compiler_options) & ZEND_COMPILE_NO_PERSISTENT_CONSTANT_SUBSTITUTION)) || (Z_TYPE(c->value) < IS_OBJECT && !(CG(compiler_options) & ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION)) )) { - ZVAL_DUP(zv, &c->value); + ZVAL_COPY_OR_DUP(zv, &c->value); return 1; } @@ -1417,7 +1411,7 @@ static zend_bool zend_try_ct_eval_const(zval *zv, zend_string *name, zend_bool i c = zend_lookup_reserved_const(lookup_name, lookup_len); if (c) { - ZVAL_DUP(zv, &c->value); + ZVAL_COPY_OR_DUP(zv, &c->value); return 1; } } @@ -1570,7 +1564,7 @@ static zend_bool zend_try_ct_eval_class_const(zval *zv, zend_string *class_name, /* Substitute case-sensitive (or lowercase) persistent class constants */ if (Z_TYPE_P(c) < IS_OBJECT) { - ZVAL_DUP(zv, c); + ZVAL_COPY_OR_DUP(zv, c); return 1; } @@ -1760,7 +1754,7 @@ ZEND_API void zend_initialize_class_data(zend_class_entry *ce, zend_bool nullify ce->default_properties_table = NULL; ce->default_static_members_table = NULL; zend_hash_init_ex(&ce->properties_info, 8, NULL, (persistent_hashes ? zend_destroy_property_info_internal : NULL), persistent_hashes, 0); - zend_hash_init_ex(&ce->constants_table, 8, NULL, (persistent_hashes ? zend_destroy_class_constant_internal : NULL), persistent_hashes, 0); + zend_hash_init_ex(&ce->constants_table, 8, NULL, NULL, persistent_hashes, 0); zend_hash_init_ex(&ce->function_table, 8, NULL, ZEND_FUNCTION_DTOR, persistent_hashes, 0); if (ce->type == ZEND_INTERNAL_CLASS) { diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index d159305c969..8ffeaf0b5c3 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -590,7 +590,7 @@ ZEND_API int zval_update_constant_ex(zval *p, zend_class_entry *scope) /* {{{ */ return zend_use_undefined_constant(name, ast->attr, p); } zval_ptr_dtor_nogc(p); - ZVAL_DUP(p, zv); + ZVAL_COPY_OR_DUP(p, zv); } else { zval tmp; diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index 02b1810f2e9..c200573ac85 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -775,16 +775,7 @@ static void do_inherit_class_constant(zend_string *name, zend_class_constant *pa if (Z_TYPE(parent_const->value) == IS_CONSTANT_AST) { ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED; } - if (ce->type & ZEND_INTERNAL_CLASS) { - if (Z_REFCOUNTED(parent_const->value)) { - Z_ADDREF(parent_const->value); - } - c = pemalloc(sizeof(zend_class_constant), 1); - memcpy(c, parent_const, sizeof(zend_class_constant)); - } else { - c = parent_const; - } - _zend_hash_append_ptr(&ce->constants_table, name, c); + _zend_hash_append_ptr(&ce->constants_table, name, parent_const); } } /* }}} */ @@ -842,24 +833,28 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent ce->default_properties_table = end; } src = parent_ce->default_properties_table + parent_ce->default_properties_count; - do { - dst--; - src--; -#ifdef ZTS - if (parent_ce->type != ce->type) { - ZVAL_DUP(dst, src); + if (UNEXPECTED(parent_ce->type != ce->type)) { + /* User class extends internal */ + do { + dst--; + src--; + ZVAL_COPY_OR_DUP(dst, src); if (Z_OPT_TYPE_P(dst) == IS_CONSTANT_AST) { ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED; } continue; - } -#endif - - ZVAL_COPY(dst, src); - if (Z_OPT_TYPE_P(dst) == IS_CONSTANT_AST) { - ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED; - } - } while (dst != end); + } while (dst != end); + } else { + do { + dst--; + src--; + ZVAL_COPY(dst, src); + if (Z_OPT_TYPE_P(dst) == IS_CONSTANT_AST) { + ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED; + } + continue; + } while (dst != end); + } ce->default_properties_count += parent_ce->default_properties_count; } @@ -884,23 +879,43 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent dst = end + parent_ce->default_static_members_count; ce->default_static_members_table = end; } - src = parent_ce->default_static_members_table + parent_ce->default_static_members_count; - do { - dst--; - src--; - if (parent_ce->type == ZEND_INTERNAL_CLASS) { + if (UNEXPECTED(parent_ce->type != ce->type)) { + /* User class extends internal */ + if (UNEXPECTED(zend_update_class_constants(parent_ce) != SUCCESS)) { + ZEND_ASSERT(0); + } + src = CE_STATIC_MEMBERS(parent_ce) + parent_ce->default_static_members_count; + do { + dst--; + src--; + ZVAL_MAKE_REF(src); + ZVAL_COPY_VALUE(dst, src); + Z_ADDREF_P(dst); + } while (dst != end); + } else if (ce->type == ZEND_USER_CLASS) { + src = parent_ce->default_static_members_table + parent_ce->default_static_members_count; + do { + dst--; + src--; + ZVAL_MAKE_REF(src); + ZVAL_COPY_VALUE(dst, src); + Z_ADDREF_P(dst); + if (Z_TYPE_P(Z_REFVAL_P(dst)) == IS_CONSTANT_AST) { + ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED; + } + } while (dst != end); + } else { + src = parent_ce->default_static_members_table + parent_ce->default_static_members_count; + do { + dst--; + src--; if (!Z_ISREF_P(src)) { ZVAL_NEW_PERSISTENT_REF(src, src); } - } else { - ZVAL_MAKE_REF(src); - } - ZVAL_COPY_VALUE(dst, src); - Z_ADDREF_P(dst); - if (Z_TYPE_P(Z_REFVAL_P(dst)) == IS_CONSTANT_AST) { - ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED; - } - } while (dst != end); + ZVAL_COPY_VALUE(dst, src); + Z_ADDREF_P(dst); + } while (dst != end); + } ce->default_static_members_count += parent_ce->default_static_members_count; if (ce->type == ZEND_USER_CLASS) { ce->static_members_table = ce->default_static_members_table; @@ -988,16 +1003,7 @@ static void do_inherit_iface_constant(zend_string *name, zend_class_constant *c, if (Z_TYPE(c->value) == IS_CONSTANT_AST) { ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED; } - if (ce->type & ZEND_INTERNAL_CLASS) { - if (Z_REFCOUNTED(c->value)) { - Z_ADDREF(c->value); - } - ct = pemalloc(sizeof(zend_class_constant), 1); - memcpy(ct, c, sizeof(zend_class_constant)); - } else { - ct = c; - } - zend_hash_update_ptr(&ce->constants_table, name, ct); + zend_hash_update_ptr(&ce->constants_table, name, c); } } /* }}} */ diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index 7eafbc05e1f..2382afbfb93 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -346,9 +346,12 @@ ZEND_API void destroy_zend_class(zval *zv) zend_class_constant *c; ZEND_HASH_FOREACH_PTR(&ce->constants_table, c) { - zval_internal_ptr_dtor(&c->value); - if (c->doc_comment && c->ce == ce) { - zend_string_release(c->doc_comment); + if (c->ce == ce) { + zval_internal_ptr_dtor(&c->value); + if (c->doc_comment) { + zend_string_release(c->doc_comment); + } + free(c); } } ZEND_HASH_FOREACH_END(); zend_hash_destroy(&ce->constants_table); diff --git a/Zend/zend_types.h b/Zend/zend_types.h index d96891cb249..341b1fe8c9e 100644 --- a/Zend/zend_types.h +++ b/Zend/zend_types.h @@ -993,6 +993,26 @@ static zend_always_inline uint32_t zval_delref_p(zval* pz) { } \ } while (0) + +/* ZVAL_COPY_OR_DUP() should be used instead of ZVAL_COPY() and ZVAL_DUP() + * in all places where the source may be a persistent zval. + */ +#define ZVAL_COPY_OR_DUP(z, v) \ + do { \ + zval *_z1 = (z); \ + const zval *_z2 = (v); \ + zend_refcounted *_gc = Z_COUNTED_P(_z2); \ + uint32_t _t = Z_TYPE_INFO_P(_z2); \ + ZVAL_COPY_VALUE_EX(_z1, _z2, _gc, _t); \ + if ((_t & (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT)) != 0) { \ + if (EXPECTED(!(GC_FLAGS(_gc) & GC_PERSISTENT))) { \ + GC_ADDREF(_gc); \ + } else { \ + _zval_copy_ctor_func(_z1 ZEND_FILE_LINE_CC); \ + } \ + } \ + } while (0) + #define ZVAL_DEREF(z) do { \ if (UNEXPECTED(Z_ISREF_P(z))) { \ (z) = Z_REFVAL_P(z); \ diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 54964646916..6449741d127 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -5055,15 +5055,7 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, UNUSED, CONST, CONST_FETCH) CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), c); } -#ifdef ZTS - if (c->flags & CONST_PERSISTENT) { - ZVAL_DUP(EX_VAR(opline->result.var), &c->value); - } else { - ZVAL_COPY(EX_VAR(opline->result.var), &c->value); - } -#else - ZVAL_COPY(EX_VAR(opline->result.var), &c->value); -#endif + ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), &c->value); ZEND_VM_NEXT_OPCODE(); } @@ -5081,9 +5073,6 @@ ZEND_VM_HANDLER(181, ZEND_FETCH_CLASS_CONSTANT, VAR|CONST|UNUSED|CLASS_FETCH, CO if (OP1_TYPE == IS_CONST) { if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))))) { value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); -#ifdef ZTS - ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); -#endif break; } else if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); @@ -5140,15 +5129,7 @@ ZEND_VM_HANDLER(181, ZEND_FETCH_CLASS_CONSTANT, VAR|CONST|UNUSED|CLASS_FETCH, CO } } while (0); -#ifdef ZTS - if (ce->type == ZEND_INTERNAL_CLASS) { - ZVAL_DUP(EX_VAR(opline->result.var), value); - } else { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } -#else - ZVAL_COPY(EX_VAR(opline->result.var), value); -#endif + ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), value); ZEND_VM_NEXT_OPCODE(); } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 087610b10f1..88adc1c2552 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -5764,9 +5764,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_CONS if (IS_CONST == IS_CONST) { if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))))) { value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); -#ifdef ZTS - ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); -#endif break; } else if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); @@ -5823,15 +5820,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_CONS } } while (0); -#ifdef ZTS - if (ce->type == ZEND_INTERNAL_CLASS) { - ZVAL_DUP(EX_VAR(opline->result.var), value); - } else { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } -#else - ZVAL_COPY(EX_VAR(opline->result.var), value); -#endif + ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), value); ZEND_VM_NEXT_OPCODE(); } @@ -19813,9 +19802,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_ if (IS_VAR == IS_CONST) { if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))))) { value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); -#ifdef ZTS - ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); -#endif break; } else if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); @@ -19872,15 +19858,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_ } } while (0); -#ifdef ZTS - if (ce->type == ZEND_INTERNAL_CLASS) { - ZVAL_DUP(EX_VAR(opline->result.var), value); - } else { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } -#else - ZVAL_COPY(EX_VAR(opline->result.var), value); -#endif + ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), value); ZEND_VM_NEXT_OPCODE(); } @@ -28698,15 +28676,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CON CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), c); } -#ifdef ZTS - if (c->flags & CONST_PERSISTENT) { - ZVAL_DUP(EX_VAR(opline->result.var), &c->value); - } else { - ZVAL_COPY(EX_VAR(opline->result.var), &c->value); - } -#else - ZVAL_COPY(EX_VAR(opline->result.var), &c->value); -#endif + ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), &c->value); ZEND_VM_NEXT_OPCODE(); } @@ -28724,9 +28694,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUS if (IS_UNUSED == IS_CONST) { if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))))) { value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); -#ifdef ZTS - ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); -#endif break; } else if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); @@ -28783,15 +28750,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUS } } while (0); -#ifdef ZTS - if (ce->type == ZEND_INTERNAL_CLASS) { - ZVAL_DUP(EX_VAR(opline->result.var), value); - } else { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } -#else - ZVAL_COPY(EX_VAR(opline->result.var), value); -#endif + ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), value); ZEND_VM_NEXT_OPCODE(); } diff --git a/ext/opcache/Optimizer/pass1_5.c b/ext/opcache/Optimizer/pass1_5.c index 9f280190135..002b6ce80a9 100644 --- a/ext/opcache/Optimizer/pass1_5.c +++ b/ext/opcache/Optimizer/pass1_5.c @@ -310,8 +310,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx) break; } } else { - ZVAL_COPY_VALUE(&t, c); - zval_copy_ctor(&t); + ZVAL_COPY_OR_DUP(&t, c); } if (opline->op1_type == IS_CONST) { diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 9b91a5a1c31..36af4a193a8 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -3715,7 +3715,7 @@ ZEND_METHOD(reflection_class_constant, getValue) } GET_REFLECTION_OBJECT_PTR(ref); - ZVAL_DUP(return_value, &ref->value); + ZVAL_COPY_OR_DUP(return_value, &ref->value); if (Z_TYPE_P(return_value) == IS_CONSTANT_AST) { zval_update_constant_ex(return_value, ref->ce); } @@ -3848,7 +3848,7 @@ static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value /* copy: enforce read only access */ ZVAL_DEREF(prop); - ZVAL_DUP(&prop_copy, prop); + ZVAL_COPY_OR_DUP(&prop_copy, prop); /* this is necessary to make it able to work with default array * properties, returned to user */ @@ -4504,7 +4504,7 @@ ZEND_METHOD(reflection_class, getConstants) zend_class_entry *ce; zend_string *key; zend_class_constant *c; - zval *val; + zval val; if (zend_parse_parameters_none() == FAILURE) { return; @@ -4516,8 +4516,8 @@ ZEND_METHOD(reflection_class, getConstants) zend_array_destroy(Z_ARRVAL_P(return_value)); return; } - val = zend_hash_add_new(Z_ARRVAL_P(return_value), key, &c->value); - Z_TRY_ADDREF_P(val); + ZVAL_COPY_OR_DUP(&val, &c->value); + zend_hash_add_new(Z_ARRVAL_P(return_value), key, &val); } ZEND_HASH_FOREACH_END(); } /* }}} */ @@ -4567,7 +4567,7 @@ ZEND_METHOD(reflection_class, getConstant) if ((c = zend_hash_find_ptr(&ce->constants_table, name)) == NULL) { RETURN_FALSE; } - ZVAL_DUP(return_value, &c->value); + ZVAL_COPY_OR_DUP(return_value, &c->value); } /* }}} */ @@ -5848,7 +5848,7 @@ static int _addconstant(zval *el, int num_args, va_list args, zend_hash_key *has int number = va_arg(args, int); if (number == constant->module_number) { - ZVAL_DUP(&const_val, &constant->value); + ZVAL_COPY_OR_DUP(&const_val, &constant->value); zend_hash_update(Z_ARRVAL_P(retval), constant->name, &const_val); } return 0; diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 93d469168b7..071099c7b90 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -3879,7 +3879,7 @@ PHP_FUNCTION(constant) scope = zend_get_executed_scope(); c = zend_get_constant_ex(const_name, scope, ZEND_FETCH_CLASS_SILENT); if (c) { - ZVAL_DUP(return_value, c); + ZVAL_COPY_OR_DUP(return_value, c); if (Z_TYPE_P(return_value) == IS_CONSTANT_AST) { if (UNEXPECTED(zval_update_constant_ex(return_value, scope) != SUCCESS)) { return;