mirror of
https://github.com/php/php-src.git
synced 2024-11-27 03:44:07 +08:00
Prevent reference-counting on persistent zvals (internal constants, default properties and constants of internal classes).
New macro ZVAL_COPY_OR_DUP() is used perform duplication, if necessary. This should eliminate related race-coditions in ZTS build and prevent reference-counting bugs after unclean shutdown.
This commit is contained in:
parent
dc4427d0ca
commit
fcc08ce19f
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
@ -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);
|
||||
|
@ -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); \
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user