summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Zend/zend_API.c49
-rw-r--r--Zend/zend_ast.c6
-rw-r--r--Zend/zend_builtin_functions.c12
-rw-r--r--Zend/zend_compile.c14
-rw-r--r--Zend/zend_execute_API.c2
-rw-r--r--Zend/zend_inheritance.c102
-rw-r--r--Zend/zend_opcode.c9
-rw-r--r--Zend/zend_types.h20
-rw-r--r--Zend/zend_vm_def.h23
-rw-r--r--Zend/zend_vm_execute.h49
-rw-r--r--ext/opcache/Optimizer/pass1_5.c3
-rw-r--r--ext/reflection/php_reflection.c14
-rw-r--r--ext/standard/basic_functions.c2
13 files changed, 135 insertions, 170 deletions
diff --git a/Zend/zend_API.c b/Zend/zend_API.c
index 61b1829f78..4392c4c12e 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];
-
- ZVAL_NEW_REF(q, q);
- ZVAL_COPY_VALUE(&CE_STATIC_MEMBERS(class_type)[i], q);
- Z_ADDREF_P(q);
+ 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);
+ } 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 1dcf5e31e1..26177c2c72 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 0d6cc442b6..37bf4f82e0 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 11c56cc60c..e7657bee7f 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 d159305c96..8ffeaf0b5c 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 02b1810f2e..c200573ac8 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 7eafbc05e1..2382afbfb9 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 d96891cb24..341b1fe8c9 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 5496464691..6449741d12 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 087610b10f..88adc1c255 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 9f28019013..002b6ce80a 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 9b91a5a1c3..36af4a193a 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 93d469168b..071099c7b9 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;