summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikic@php.net>2016-04-10 13:01:54 +0200
committerNikita Popov <nikic@php.net>2016-04-15 15:32:20 +0200
commit64f91774f225e78a79c3623b185ae8b64ef9e30b (patch)
treea0947c110c53409cbdc585b20a9800adf11e5fac
parentfd2cd354291d77f8949f905b50218e74463f3e7a (diff)
downloadphp-git-64f91774f225e78a79c3623b185ae8b64ef9e30b.tar.gz
Remove IS_VAR_RET_REF flag
Instead decide whether a function returned by reference or by value by checking whether the return value has REFERENCE type. This means that functions returning by reference must always return a reference and functions returning by value must not return a reference.
-rw-r--r--Zend/zend_execute.c1
-rw-r--r--Zend/zend_operators.c11
-rw-r--r--Zend/zend_operators.h12
-rw-r--r--Zend/zend_types.h7
-rw-r--r--Zend/zend_vm_def.h67
-rw-r--r--Zend/zend_vm_execute.h224
-rw-r--r--ext/opcache/Optimizer/zend_func_info.c2
-rw-r--r--ext/reflection/php_reflection.c7
-rw-r--r--ext/standard/var.c5
9 files changed, 160 insertions, 176 deletions
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index a23b843bc6..f14434bff9 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -2978,7 +2978,6 @@ static zend_never_inline int zend_do_fcall_overloaded(zend_function *fbc, zend_e
EG(scope) = fbc->common.scope;
ZVAL_NULL(ret);
- Z_VAR_FLAGS_P(ret) = 0;
EG(current_execute_data) = call;
object->handlers->call_method(fbc->common.function_name, object, call, ret);
diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c
index 06a0f75386..c1a7986650 100644
--- a/Zend/zend_operators.c
+++ b/Zend/zend_operators.c
@@ -136,17 +136,6 @@ ZEND_API zend_long ZEND_FASTCALL zend_atol(const char *str, int str_len) /* {{{
}
/* }}} */
-static zend_always_inline void zend_unwrap_reference(zval *op) /* {{{ */
-{
- if (Z_REFCOUNT_P(op) == 1) {
- ZVAL_UNREF(op);
- } else {
- Z_DELREF_P(op);
- ZVAL_COPY(op, Z_REFVAL_P(op));
- }
-}
-/* }}} */
-
void ZEND_FASTCALL _convert_scalar_to_number(zval *op, zend_bool silent) /* {{{ */
{
try_again:
diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h
index db6162a4e5..405ca0926f 100644
--- a/Zend/zend_operators.h
+++ b/Zend/zend_operators.h
@@ -821,6 +821,18 @@ static zend_always_inline char *zend_print_long_to_buf(char *buf, zend_long num)
ZEND_API zend_string* ZEND_FASTCALL zend_long_to_str(zend_long num);
+static zend_always_inline void zend_unwrap_reference(zval *op) /* {{{ */
+{
+ if (Z_REFCOUNT_P(op) == 1) {
+ ZVAL_UNREF(op);
+ } else {
+ Z_DELREF_P(op);
+ ZVAL_COPY(op, Z_REFVAL_P(op));
+ }
+}
+/* }}} */
+
+
END_EXTERN_C()
#endif
diff --git a/Zend/zend_types.h b/Zend/zend_types.h
index d3fa56080b..9545b53e33 100644
--- a/Zend/zend_types.h
+++ b/Zend/zend_types.h
@@ -131,7 +131,6 @@ struct _zval_struct {
uint32_t type_info;
} u1;
union {
- uint32_t var_flags;
uint32_t next; /* hash collision chain */
uint32_t cache_slot; /* literal cache slot */
uint32_t lineno; /* line number (for ast nodes) */
@@ -345,9 +344,6 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
#define Z_CONST_FLAGS(zval) (zval).u1.v.const_flags
#define Z_CONST_FLAGS_P(zval_p) Z_CONST_FLAGS(*(zval_p))
-#define Z_VAR_FLAGS(zval) (zval).u2.var_flags
-#define Z_VAR_FLAGS_P(zval_p) Z_VAR_FLAGS(*(zval_p))
-
#define Z_TYPE_INFO(zval) (zval).u1.type_info
#define Z_TYPE_INFO_P(zval_p) Z_TYPE_INFO(*(zval_p))
@@ -416,9 +412,6 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
#define IS_CONSTANT_CLASS 0x080 /* __CLASS__ in trait */
#define IS_CONSTANT_IN_NAMESPACE 0x100 /* used only in opline->extended_value */
-/* zval.u2.var_flags */
-#define IS_VAR_RET_REF (1<<0) /* return by by reference */
-
/* string flags (zval.value->gc.u.flags) */
#define IS_STR_PERSISTENT (1<<0) /* allocated using malloc */
#define IS_STR_INTERNED (1<<1) /* interned string */
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index c1f3fad2ed..6c9adea30b 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -2449,8 +2449,7 @@ ZEND_VM_HANDLER(39, ZEND_ASSIGN_REF, VAR|CV, VAR|CV, SRC)
} else if (OP2_TYPE == IS_VAR &&
opline->extended_value == ZEND_RETURNS_FUNCTION &&
- UNEXPECTED(!(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
-
+ UNEXPECTED(!Z_ISREF_P(value_ptr))) {
zend_error(E_NOTICE, "Only variables should be assigned by reference");
if (UNEXPECTED(EG(exception) != NULL)) {
FREE_OP2_VAR_PTR();
@@ -3551,7 +3550,6 @@ ZEND_VM_HANDLER(129, ZEND_DO_ICALL, ANY, ANY, SPEC(RETVAL))
ret = RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : &retval;
ZVAL_NULL(ret);
- Z_VAR_FLAGS_P(ret) = 0;
fbc->internal_function.handler(call, ret);
@@ -3560,6 +3558,7 @@ ZEND_VM_HANDLER(129, ZEND_DO_ICALL, ANY, ANY, SPEC(RETVAL))
EG(exception) || !call->func ||
!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
zend_verify_internal_return_type(call->func, ret));
+ ZEND_ASSERT(!Z_ISREF_P(ret));
#endif
EG(current_execute_data) = call->prev_execute_data;
@@ -3598,7 +3597,6 @@ ZEND_VM_HANDLER(130, ZEND_DO_UCALL, ANY, ANY, SPEC(RETVAL))
if (RETURN_VALUE_USED(opline)) {
ret = EX_VAR(opline->result.var);
ZVAL_NULL(ret);
- Z_VAR_FLAGS_P(ret) = 0;
}
call->prev_execute_data = execute_data;
@@ -3623,7 +3621,6 @@ ZEND_VM_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY, SPEC(RETVAL))
if (EXPECTED(RETURN_VALUE_USED(opline))) {
ret = EX_VAR(opline->result.var);
zend_generator_create_zval(call, &fbc->op_array, ret);
- Z_VAR_FLAGS_P(ret) = 0;
} else {
zend_vm_stack_free_args(call);
}
@@ -3635,7 +3632,6 @@ ZEND_VM_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY, SPEC(RETVAL))
if (RETURN_VALUE_USED(opline)) {
ret = EX_VAR(opline->result.var);
ZVAL_NULL(ret);
- Z_VAR_FLAGS_P(ret) = 0;
}
call->prev_execute_data = execute_data;
@@ -3670,15 +3666,16 @@ ZEND_VM_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY, SPEC(RETVAL))
ret = RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : &retval;
ZVAL_NULL(ret);
- Z_VAR_FLAGS_P(ret) = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0 ? IS_VAR_RET_REF : 0;
fbc->internal_function.handler(call, ret);
#if ZEND_DEBUG
- ZEND_ASSERT(
- EG(exception) || !call->func ||
- !(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
- zend_verify_internal_return_type(call->func, ret));
+ if (!EG(exception) && call->func) {
+ ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
+ zend_verify_internal_return_type(call->func, ret));
+ ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
+ ? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
+ }
#endif
EG(current_execute_data) = call->prev_execute_data;
@@ -3735,7 +3732,6 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL))
if (EXPECTED(RETURN_VALUE_USED(opline))) {
ret = EX_VAR(opline->result.var);
zend_generator_create_zval(call, &fbc->op_array, ret);
- Z_VAR_FLAGS_P(ret) = 0;
} else {
if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_CLOSURE)) {
OBJ_RELEASE((zend_object*)fbc->op_array.prototype);
@@ -3748,7 +3744,6 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL))
if (RETURN_VALUE_USED(opline)) {
ret = EX_VAR(opline->result.var);
ZVAL_NULL(ret);
- Z_VAR_FLAGS_P(ret) = 0;
}
call->prev_execute_data = execute_data;
@@ -3787,7 +3782,6 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL))
ret = RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : &retval;
ZVAL_NULL(ret);
- Z_VAR_FLAGS_P(ret) = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0 ? IS_VAR_RET_REF : 0;
if (!zend_execute_internal) {
/* saves one function call if zend_execute_internal is not used */
@@ -3797,10 +3791,12 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL))
}
#if ZEND_DEBUG
- ZEND_ASSERT(
- EG(exception) || !call->func ||
- !(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
- zend_verify_internal_return_type(call->func, ret));
+ if (!EG(exception) && call->func) {
+ ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
+ zend_verify_internal_return_type(call->func, ret));
+ ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
+ ? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
+ }
#endif
EG(current_execute_data) = call->prev_execute_data;
@@ -3998,14 +3994,16 @@ ZEND_VM_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY, SRC)
retval_ptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
if (!EX(return_value)) {
- if (OP1_TYPE == IS_TMP_VAR) {
- FREE_OP1();
- }
+ FREE_OP1();
} else {
- ZVAL_COPY_VALUE(EX(return_value), retval_ptr);
- Z_VAR_FLAGS_P(EX(return_value)) = IS_VAR_RET_REF;
- if (OP1_TYPE != IS_TMP_VAR) {
- zval_opt_copy_ctor_no_imm(EX(return_value));
+ if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_ISREF_P(retval_ptr))) {
+ ZVAL_COPY_VALUE(EX(return_value), retval_ptr);
+ break;
+ }
+
+ ZVAL_NEW_REF(EX(return_value), retval_ptr);
+ if (OP1_TYPE == IS_CONST) {
+ if (Z_REFCOUNTED_P(retval_ptr)) Z_ADDREF_P(retval_ptr);
}
}
break;
@@ -4015,13 +4013,12 @@ ZEND_VM_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY, SRC)
if (OP1_TYPE == IS_VAR) {
if (retval_ptr == &EG(uninitialized_zval) ||
- (opline->extended_value == ZEND_RETURNS_FUNCTION &&
- !(Z_VAR_FLAGS_P(retval_ptr) & IS_VAR_RET_REF))) {
+ (opline->extended_value == ZEND_RETURNS_FUNCTION && !Z_ISREF_P(retval_ptr))) {
zend_error(E_NOTICE, "Only variable references should be returned by reference");
if (EX(return_value)) {
ZVAL_NEW_REF(EX(return_value), retval_ptr);
- Z_VAR_FLAGS_P(EX(return_value)) = IS_VAR_RET_REF;
- if (Z_REFCOUNTED_P(retval_ptr)) Z_ADDREF_P(retval_ptr);
+ } else {
+ FREE_OP1_VAR_PTR();
}
break;
}
@@ -4031,11 +4028,11 @@ ZEND_VM_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY, SRC)
ZVAL_MAKE_REF(retval_ptr);
Z_ADDREF_P(retval_ptr);
ZVAL_REF(EX(return_value), Z_REF_P(retval_ptr));
- Z_VAR_FLAGS_P(EX(return_value)) = IS_VAR_RET_REF;
}
+
+ FREE_OP1_VAR_PTR();
} while (0);
- FREE_OP1_VAR_PTR();
ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
}
@@ -4276,7 +4273,7 @@ ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR, NUM, SEND)
varptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
if ((!(opline->extended_value & ZEND_ARG_SEND_FUNCTION) ||
- (Z_VAR_FLAGS_P(varptr) & IS_VAR_RET_REF)) &&
+ Z_ISREF_P(varptr)) &&
(Z_ISREF_P(varptr) || Z_TYPE_P(varptr) == IS_OBJECT)) {
ZVAL_MAKE_REF(varptr);
@@ -7300,9 +7297,6 @@ ZEND_VM_HANDLER(156, ZEND_SEPARATE, VAR, UNUSED)
if (UNEXPECTED(Z_ISREF_P(var_ptr))) {
if (UNEXPECTED(Z_REFCOUNT_P(var_ptr) == 1)) {
ZVAL_UNREF(var_ptr);
- } else if (!(Z_VAR_FLAGS_P(var_ptr) & IS_VAR_RET_REF)) {
- Z_DELREF_P(var_ptr);
- ZVAL_COPY(var_ptr, Z_REFVAL_P(var_ptr));
}
}
@@ -7356,7 +7350,7 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|VAR|CV|UNUSE
if (OP1_TYPE == IS_VAR &&
(value_ptr == &EG(uninitialized_zval) ||
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
- !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
+ !Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -7935,7 +7929,6 @@ ZEND_VM_HANDLER(158, ZEND_CALL_TRAMPOLINE, ANY, ANY)
ZVAL_NULL(&retval);
ret = &retval;
}
- Z_VAR_FLAGS_P(ret) = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0 ? IS_VAR_RET_REF : 0;
if (!zend_execute_internal) {
/* saves one function call if zend_execute_internal is not used */
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 6128e6c4fc..0fc6899535 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -611,7 +611,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HA
ret = 0 ? EX_VAR(opline->result.var) : &retval;
ZVAL_NULL(ret);
- Z_VAR_FLAGS_P(ret) = 0;
fbc->internal_function.handler(call, ret);
@@ -620,6 +619,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HA
EG(exception) || !call->func ||
!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
zend_verify_internal_return_type(call->func, ret));
+ ZEND_ASSERT(!Z_ISREF_P(ret));
#endif
EG(current_execute_data) = call->prev_execute_data;
@@ -658,7 +658,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETVAL_USED_HAND
ret = 1 ? EX_VAR(opline->result.var) : &retval;
ZVAL_NULL(ret);
- Z_VAR_FLAGS_P(ret) = 0;
fbc->internal_function.handler(call, ret);
@@ -667,6 +666,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETVAL_USED_HAND
EG(exception) || !call->func ||
!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
zend_verify_internal_return_type(call->func, ret));
+ ZEND_ASSERT(!Z_ISREF_P(ret));
#endif
EG(current_execute_data) = call->prev_execute_data;
@@ -705,7 +705,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_UCALL_SPEC_RETVAL_UNUSED_HA
if (0) {
ret = EX_VAR(opline->result.var);
ZVAL_NULL(ret);
- Z_VAR_FLAGS_P(ret) = 0;
}
call->prev_execute_data = execute_data;
@@ -730,7 +729,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_UCALL_SPEC_RETVAL_USED_HAND
if (1) {
ret = EX_VAR(opline->result.var);
ZVAL_NULL(ret);
- Z_VAR_FLAGS_P(ret) = 0;
}
call->prev_execute_data = execute_data;
@@ -755,7 +753,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_U
if (EXPECTED(0)) {
ret = EX_VAR(opline->result.var);
zend_generator_create_zval(call, &fbc->op_array, ret);
- Z_VAR_FLAGS_P(ret) = 0;
} else {
zend_vm_stack_free_args(call);
}
@@ -767,7 +764,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_U
if (0) {
ret = EX_VAR(opline->result.var);
ZVAL_NULL(ret);
- Z_VAR_FLAGS_P(ret) = 0;
}
call->prev_execute_data = execute_data;
@@ -802,15 +798,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_U
ret = 0 ? EX_VAR(opline->result.var) : &retval;
ZVAL_NULL(ret);
- Z_VAR_FLAGS_P(ret) = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0 ? IS_VAR_RET_REF : 0;
fbc->internal_function.handler(call, ret);
#if ZEND_DEBUG
- ZEND_ASSERT(
- EG(exception) || !call->func ||
- !(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
- zend_verify_internal_return_type(call->func, ret));
+ if (!EG(exception) && call->func) {
+ ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
+ zend_verify_internal_return_type(call->func, ret));
+ ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
+ ? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
+ }
#endif
EG(current_execute_data) = call->prev_execute_data;
@@ -849,7 +846,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_U
if (EXPECTED(1)) {
ret = EX_VAR(opline->result.var);
zend_generator_create_zval(call, &fbc->op_array, ret);
- Z_VAR_FLAGS_P(ret) = 0;
} else {
zend_vm_stack_free_args(call);
}
@@ -861,7 +857,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_U
if (1) {
ret = EX_VAR(opline->result.var);
ZVAL_NULL(ret);
- Z_VAR_FLAGS_P(ret) = 0;
}
call->prev_execute_data = execute_data;
@@ -896,15 +891,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_U
ret = 1 ? EX_VAR(opline->result.var) : &retval;
ZVAL_NULL(ret);
- Z_VAR_FLAGS_P(ret) = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0 ? IS_VAR_RET_REF : 0;
fbc->internal_function.handler(call, ret);
#if ZEND_DEBUG
- ZEND_ASSERT(
- EG(exception) || !call->func ||
- !(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
- zend_verify_internal_return_type(call->func, ret));
+ if (!EG(exception) && call->func) {
+ ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
+ zend_verify_internal_return_type(call->func, ret));
+ ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
+ ? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
+ }
#endif
EG(current_execute_data) = call->prev_execute_data;
@@ -961,7 +957,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HA
if (EXPECTED(0)) {
ret = EX_VAR(opline->result.var);
zend_generator_create_zval(call, &fbc->op_array, ret);
- Z_VAR_FLAGS_P(ret) = 0;
} else {
if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_CLOSURE)) {
OBJ_RELEASE((zend_object*)fbc->op_array.prototype);
@@ -974,7 +969,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HA
if (0) {
ret = EX_VAR(opline->result.var);
ZVAL_NULL(ret);
- Z_VAR_FLAGS_P(ret) = 0;
}
call->prev_execute_data = execute_data;
@@ -1013,7 +1007,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HA
ret = 0 ? EX_VAR(opline->result.var) : &retval;
ZVAL_NULL(ret);
- Z_VAR_FLAGS_P(ret) = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0 ? IS_VAR_RET_REF : 0;
if (!zend_execute_internal) {
/* saves one function call if zend_execute_internal is not used */
@@ -1023,10 +1016,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HA
}
#if ZEND_DEBUG
- ZEND_ASSERT(
- EG(exception) || !call->func ||
- !(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
- zend_verify_internal_return_type(call->func, ret));
+ if (!EG(exception) && call->func) {
+ ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
+ zend_verify_internal_return_type(call->func, ret));
+ ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
+ ? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
+ }
#endif
EG(current_execute_data) = call->prev_execute_data;
@@ -1122,7 +1117,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETVAL_USED_HAND
if (EXPECTED(1)) {
ret = EX_VAR(opline->result.var);
zend_generator_create_zval(call, &fbc->op_array, ret);
- Z_VAR_FLAGS_P(ret) = 0;
} else {
if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_CLOSURE)) {
OBJ_RELEASE((zend_object*)fbc->op_array.prototype);
@@ -1135,7 +1129,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETVAL_USED_HAND
if (1) {
ret = EX_VAR(opline->result.var);
ZVAL_NULL(ret);
- Z_VAR_FLAGS_P(ret) = 0;
}
call->prev_execute_data = execute_data;
@@ -1174,7 +1167,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETVAL_USED_HAND
ret = 1 ? EX_VAR(opline->result.var) : &retval;
ZVAL_NULL(ret);
- Z_VAR_FLAGS_P(ret) = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0 ? IS_VAR_RET_REF : 0;
if (!zend_execute_internal) {
/* saves one function call if zend_execute_internal is not used */
@@ -1184,10 +1176,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETVAL_USED_HAND
}
#if ZEND_DEBUG
- ZEND_ASSERT(
- EG(exception) || !call->func ||
- !(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
- zend_verify_internal_return_type(call->func, ret));
+ if (!EG(exception) && call->func) {
+ ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
+ zend_verify_internal_return_type(call->func, ret));
+ ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
+ ? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
+ }
#endif
EG(current_execute_data) = call->prev_execute_data;
@@ -2073,7 +2067,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CALL_TRAMPOLINE_SPEC_HANDLER(Z
ZVAL_NULL(&retval);
ret = &retval;
}
- Z_VAR_FLAGS_P(ret) = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0 ? IS_VAR_RET_REF : 0;
if (!zend_execute_internal) {
/* saves one function call if zend_execute_internal is not used */
@@ -2960,14 +2953,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CONST_HANDL
retval_ptr = EX_CONSTANT(opline->op1);
if (!EX(return_value)) {
- if (IS_CONST == IS_TMP_VAR) {
- }
} else {
- ZVAL_COPY_VALUE(EX(return_value), retval_ptr);
- Z_VAR_FLAGS_P(EX(return_value)) = IS_VAR_RET_REF;
- if (IS_CONST != IS_TMP_VAR) {
- zval_opt_copy_ctor_no_imm(EX(return_value));
+ if (IS_CONST == IS_VAR && UNEXPECTED(Z_ISREF_P(retval_ptr))) {
+ ZVAL_COPY_VALUE(EX(return_value), retval_ptr);
+ break;
+ }
+
+ ZVAL_NEW_REF(EX(return_value), retval_ptr);
+ if (IS_CONST == IS_CONST) {
+ if (Z_REFCOUNTED_P(retval_ptr)) Z_ADDREF_P(retval_ptr);
}
}
break;
@@ -2977,13 +2972,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CONST_HANDL
if (IS_CONST == IS_VAR) {
if (retval_ptr == &EG(uninitialized_zval) ||
- (opline->extended_value == ZEND_RETURNS_FUNCTION &&
- !(Z_VAR_FLAGS_P(retval_ptr) & IS_VAR_RET_REF))) {
+ (opline->extended_value == ZEND_RETURNS_FUNCTION && !Z_ISREF_P(retval_ptr))) {
zend_error(E_NOTICE, "Only variable references should be returned by reference");
if (EX(return_value)) {
ZVAL_NEW_REF(EX(return_value), retval_ptr);
- Z_VAR_FLAGS_P(EX(return_value)) = IS_VAR_RET_REF;
- if (Z_REFCOUNTED_P(retval_ptr)) Z_ADDREF_P(retval_ptr);
+ } else {
+
}
break;
}
@@ -2993,8 +2987,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CONST_HANDL
ZVAL_MAKE_REF(retval_ptr);
Z_ADDREF_P(retval_ptr);
ZVAL_REF(EX(return_value), Z_REF_P(retval_ptr));
- Z_VAR_FLAGS_P(EX(return_value)) = IS_VAR_RET_REF;
}
+
} while (0);
ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
@@ -6236,7 +6230,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CONST_HANDLER
if (IS_CONST == IS_VAR &&
(value_ptr == &EG(uninitialized_zval) ||
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
- !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
+ !Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -6407,7 +6401,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_TMP_HANDLER(Z
if (IS_CONST == IS_VAR &&
(value_ptr == &EG(uninitialized_zval) ||
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
- !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
+ !Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -6858,7 +6852,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_VAR_HANDLER(Z
if (IS_CONST == IS_VAR &&
(value_ptr == &EG(uninitialized_zval) ||
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
- !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
+ !Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -7913,7 +7907,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_UNUSED_HANDLE
if (IS_CONST == IS_VAR &&
(value_ptr == &EG(uninitialized_zval) ||
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
- !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
+ !Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -9786,7 +9780,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZE
if (IS_CONST == IS_VAR &&
(value_ptr == &EG(uninitialized_zval) ||
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
- !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
+ !Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -12058,14 +12052,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER
retval_ptr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1);
if (!EX(return_value)) {
- if (IS_TMP_VAR == IS_TMP_VAR) {
- zval_ptr_dtor_nogc(free_op1);
- }
+ zval_ptr_dtor_nogc(free_op1);
} else {
- ZVAL_COPY_VALUE(EX(return_value), retval_ptr);
- Z_VAR_FLAGS_P(EX(return_value)) = IS_VAR_RET_REF;
- if (IS_TMP_VAR != IS_TMP_VAR) {
- zval_opt_copy_ctor_no_imm(EX(return_value));
+ if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_ISREF_P(retval_ptr))) {
+ ZVAL_COPY_VALUE(EX(return_value), retval_ptr);
+ break;
+ }
+
+ ZVAL_NEW_REF(EX(return_value), retval_ptr);
+ if (IS_TMP_VAR == IS_CONST) {
+ if (Z_REFCOUNTED_P(retval_ptr)) Z_ADDREF_P(retval_ptr);
}
}
break;
@@ -12075,13 +12071,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER
if (IS_TMP_VAR == IS_VAR) {
if (retval_ptr == &EG(uninitialized_zval) ||
- (opline->extended_value == ZEND_RETURNS_FUNCTION &&
- !(Z_VAR_FLAGS_P(retval_ptr) & IS_VAR_RET_REF))) {
+ (opline->extended_value == ZEND_RETURNS_FUNCTION && !Z_ISREF_P(retval_ptr))) {
zend_error(E_NOTICE, "Only variable references should be returned by reference");
if (EX(return_value)) {
ZVAL_NEW_REF(EX(return_value), retval_ptr);
- Z_VAR_FLAGS_P(EX(return_value)) = IS_VAR_RET_REF;
- if (Z_REFCOUNTED_P(retval_ptr)) Z_ADDREF_P(retval_ptr);
+ } else {
+
}
break;
}
@@ -12091,8 +12086,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER
ZVAL_MAKE_REF(retval_ptr);
Z_ADDREF_P(retval_ptr);
ZVAL_REF(EX(return_value), Z_REF_P(retval_ptr));
- Z_VAR_FLAGS_P(EX(return_value)) = IS_VAR_RET_REF;
}
+
} while (0);
ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
@@ -13319,7 +13314,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CONST_HANDLER(Z
if (IS_TMP_VAR == IS_VAR &&
(value_ptr == &EG(uninitialized_zval) ||
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
- !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
+ !Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -13490,7 +13485,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_TMP_HANDLER(ZEN
if (IS_TMP_VAR == IS_VAR &&
(value_ptr == &EG(uninitialized_zval) ||
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
- !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
+ !Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -13661,7 +13656,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEN
if (IS_TMP_VAR == IS_VAR &&
(value_ptr == &EG(uninitialized_zval) ||
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
- !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
+ !Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -14013,7 +14008,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(
if (IS_TMP_VAR == IS_VAR &&
(value_ptr == &EG(uninitialized_zval) ||
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
- !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
+ !Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -14541,7 +14536,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND
if (IS_TMP_VAR == IS_VAR &&
(value_ptr == &EG(uninitialized_zval) ||
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
- !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
+ !Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -15325,14 +15320,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER
retval_ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
if (!EX(return_value)) {
- if (IS_VAR == IS_TMP_VAR) {
- zval_ptr_dtor_nogc(free_op1);
- }
+ zval_ptr_dtor_nogc(free_op1);
} else {
- ZVAL_COPY_VALUE(EX(return_value), retval_ptr);
- Z_VAR_FLAGS_P(EX(return_value)) = IS_VAR_RET_REF;
- if (IS_VAR != IS_TMP_VAR) {
- zval_opt_copy_ctor_no_imm(EX(return_value));
+ if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISREF_P(retval_ptr))) {
+ ZVAL_COPY_VALUE(EX(return_value), retval_ptr);
+ break;
+ }
+
+ ZVAL_NEW_REF(EX(return_value), retval_ptr);
+ if (IS_VAR == IS_CONST) {
+ if (Z_REFCOUNTED_P(retval_ptr)) Z_ADDREF_P(retval_ptr);
}
}
break;
@@ -15342,13 +15339,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER
if (IS_VAR == IS_VAR) {
if (retval_ptr == &EG(uninitialized_zval) ||
- (opline->extended_value == ZEND_RETURNS_FUNCTION &&
- !(Z_VAR_FLAGS_P(retval_ptr) & IS_VAR_RET_REF))) {
+ (opline->extended_value == ZEND_RETURNS_FUNCTION && !Z_ISREF_P(retval_ptr))) {
zend_error(E_NOTICE, "Only variable references should be returned by reference");
if (EX(return_value)) {
ZVAL_NEW_REF(EX(return_value), retval_ptr);
- Z_VAR_FLAGS_P(EX(return_value)) = IS_VAR_RET_REF;
- if (Z_REFCOUNTED_P(retval_ptr)) Z_ADDREF_P(retval_ptr);
+ } else {
+ if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);};
}
break;
}
@@ -15358,11 +15354,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER
ZVAL_MAKE_REF(retval_ptr);
Z_ADDREF_P(retval_ptr);
ZVAL_REF(EX(return_value), Z_REF_P(retval_ptr));
- Z_VAR_FLAGS_P(EX(return_value)) = IS_VAR_RET_REF;
}
+
+ if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);};
} while (0);
- if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);};
ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
}
@@ -15505,7 +15501,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDL
varptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
if ((!(opline->extended_value & ZEND_ARG_SEND_FUNCTION) ||
- (Z_VAR_FLAGS_P(varptr) & IS_VAR_RET_REF)) &&
+ Z_ISREF_P(varptr)) &&
(Z_ISREF_P(varptr) || Z_TYPE_P(varptr) == IS_OBJECT)) {
ZVAL_MAKE_REF(varptr);
@@ -19366,7 +19362,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(Z
if (IS_VAR == IS_VAR &&
(value_ptr == &EG(uninitialized_zval) ||
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
- !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
+ !Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -19594,7 +19590,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_TMP_HANDLER(ZEN
if (IS_VAR == IS_VAR &&
(value_ptr == &EG(uninitialized_zval) ||
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
- !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
+ !Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -19797,8 +19793,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLE
} else if (IS_VAR == IS_VAR &&
opline->extended_value == ZEND_RETURNS_FUNCTION &&
- UNEXPECTED(!(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
-
+ UNEXPECTED(!Z_ISREF_P(value_ptr))) {
zend_error(E_NOTICE, "Only variables should be assigned by reference");
if (UNEXPECTED(EG(exception) != NULL)) {
if (UNEXPECTED(free_op2)) {zval_ptr_dtor_nogc(free_op2);};
@@ -19878,7 +19873,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEN
if (IS_VAR == IS_VAR &&
(value_ptr == &EG(uninitialized_zval) ||
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
- !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
+ !Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -21154,9 +21149,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEPARATE_SPEC_VAR_UNUSED_HANDL
if (UNEXPECTED(Z_ISREF_P(var_ptr))) {
if (UNEXPECTED(Z_REFCOUNT_P(var_ptr) == 1)) {
ZVAL_UNREF(var_ptr);
- } else if (!(Z_VAR_FLAGS_P(var_ptr) & IS_VAR_RET_REF)) {
- Z_DELREF_P(var_ptr);
- ZVAL_COPY(var_ptr, Z_REFVAL_P(var_ptr));
}
}
@@ -21210,7 +21202,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER(
if (IS_VAR == IS_VAR &&
(value_ptr == &EG(uninitialized_zval) ||
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
- !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
+ !Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -23385,8 +23377,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER
} else if (IS_CV == IS_VAR &&
opline->extended_value == ZEND_RETURNS_FUNCTION &&
- UNEXPECTED(!(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
-
+ UNEXPECTED(!Z_ISREF_P(value_ptr))) {
zend_error(E_NOTICE, "Only variables should be assigned by reference");
if (UNEXPECTED(EG(exception) != NULL)) {
@@ -23882,7 +23873,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND
if (IS_VAR == IS_VAR &&
(value_ptr == &EG(uninitialized_zval) ||
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
- !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
+ !Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -28871,7 +28862,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CONST_HANDLE
if (IS_UNUSED == IS_VAR &&
(value_ptr == &EG(uninitialized_zval) ||
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
- !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
+ !Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -29006,7 +28997,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER(
if (IS_UNUSED == IS_VAR &&
(value_ptr == &EG(uninitialized_zval) ||
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
- !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
+ !Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -29141,7 +29132,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_VAR_HANDLER(
if (IS_UNUSED == IS_VAR &&
(value_ptr == &EG(uninitialized_zval) ||
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
- !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
+ !Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -29863,7 +29854,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDL
if (IS_UNUSED == IS_VAR &&
(value_ptr == &EG(uninitialized_zval) ||
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
- !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
+ !Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -32161,7 +32152,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(Z
if (IS_UNUSED == IS_VAR &&
(value_ptr == &EG(uninitialized_zval) ||
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
- !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
+ !Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -34977,14 +34968,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CV_HANDLER(
retval_ptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
if (!EX(return_value)) {
- if (IS_CV == IS_TMP_VAR) {
- }
} else {
- ZVAL_COPY_VALUE(EX(return_value), retval_ptr);
- Z_VAR_FLAGS_P(EX(return_value)) = IS_VAR_RET_REF;
- if (IS_CV != IS_TMP_VAR) {
- zval_opt_copy_ctor_no_imm(EX(return_value));
+ if (IS_CV == IS_VAR && UNEXPECTED(Z_ISREF_P(retval_ptr))) {
+ ZVAL_COPY_VALUE(EX(return_value), retval_ptr);
+ break;
+ }
+
+ ZVAL_NEW_REF(EX(return_value), retval_ptr);
+ if (IS_CV == IS_CONST) {
+ if (Z_REFCOUNTED_P(retval_ptr)) Z_ADDREF_P(retval_ptr);
}
}
break;
@@ -34994,13 +34987,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CV_HANDLER(
if (IS_CV == IS_VAR) {
if (retval_ptr == &EG(uninitialized_zval) ||
- (opline->extended_value == ZEND_RETURNS_FUNCTION &&
- !(Z_VAR_FLAGS_P(retval_ptr) & IS_VAR_RET_REF))) {
+ (opline->extended_value == ZEND_RETURNS_FUNCTION && !Z_ISREF_P(retval_ptr))) {
zend_error(E_NOTICE, "Only variable references should be returned by reference");
if (EX(return_value)) {
ZVAL_NEW_REF(EX(return_value), retval_ptr);
- Z_VAR_FLAGS_P(EX(return_value)) = IS_VAR_RET_REF;
- if (Z_REFCOUNTED_P(retval_ptr)) Z_ADDREF_P(retval_ptr);
+ } else {
+
}
break;
}
@@ -35010,8 +35002,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CV_HANDLER(
ZVAL_MAKE_REF(retval_ptr);
Z_ADDREF_P(retval_ptr);
ZVAL_REF(EX(return_value), Z_REF_P(retval_ptr));
- Z_VAR_FLAGS_P(EX(return_value)) = IS_VAR_RET_REF;
}
+
} while (0);
ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
@@ -40018,7 +40010,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZE
if (IS_CV == IS_VAR &&
(value_ptr == &EG(uninitialized_zval) ||
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
- !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
+ !Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -40387,7 +40379,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_TMP_HANDLER(ZEND
if (IS_CV == IS_VAR &&
(value_ptr == &EG(uninitialized_zval) ||
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
- !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
+ !Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -40728,8 +40720,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER
} else if (IS_VAR == IS_VAR &&
opline->extended_value == ZEND_RETURNS_FUNCTION &&
- UNEXPECTED(!(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
-
+ UNEXPECTED(!Z_ISREF_P(value_ptr))) {
zend_error(E_NOTICE, "Only variables should be assigned by reference");
if (UNEXPECTED(EG(exception) != NULL)) {
if (UNEXPECTED(free_op2)) {zval_ptr_dtor_nogc(free_op2);};
@@ -41000,7 +40991,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_VAR_HANDLER(ZEND
if (IS_CV == IS_VAR &&
(value_ptr == &EG(uninitialized_zval) ||
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
- !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
+ !Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -42721,7 +42712,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(Z
if (IS_CV == IS_VAR &&
(value_ptr == &EG(uninitialized_zval) ||
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
- !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
+ !Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -45609,8 +45600,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_CV_HANDLER(
} else if (IS_CV == IS_VAR &&
opline->extended_value == ZEND_RETURNS_FUNCTION &&
- UNEXPECTED(!(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
-
+ UNEXPECTED(!Z_ISREF_P(value_ptr))) {
zend_error(E_NOTICE, "Only variables should be assigned by reference");
if (UNEXPECTED(EG(exception) != NULL)) {
@@ -46396,7 +46386,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_
if (IS_CV == IS_VAR &&
(value_ptr == &EG(uninitialized_zval) ||
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
- !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
+ !Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
diff --git a/ext/opcache/Optimizer/zend_func_info.c b/ext/opcache/Optimizer/zend_func_info.c
index 2aa3ecb928..a684a16e73 100644
--- a/ext/opcache/Optimizer/zend_func_info.c
+++ b/ext/opcache/Optimizer/zend_func_info.c
@@ -529,7 +529,7 @@ static const func_info_t func_infos[] = {
F1("forward_static_call", UNKNOWN_INFO),
F1("forward_static_call_array", UNKNOWN_INFO),
F1("serialize", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_STRING),
- FX("unserialize", UNKNOWN_INFO),
+ FN("unserialize", UNKNOWN_INFO),
F1("var_dump", MAY_BE_NULL),
F1("var_export", MAY_BE_NULL | MAY_BE_STRING),
F1("debug_zval_dump", MAY_BE_NULL),
diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c
index dd3bd6e94d..186df87fd7 100644
--- a/ext/reflection/php_reflection.c
+++ b/ext/reflection/php_reflection.c
@@ -5647,7 +5647,9 @@ ZEND_METHOD(reflection_property, getValue)
php_error_docref(NULL, E_ERROR, "Internal error: Could not find the property %s::%s", ZSTR_VAL(intern->ce->name), ZSTR_VAL(ref->prop.name));
/* Bails out */
}
- ZVAL_DUP(return_value, &CE_STATIC_MEMBERS(intern->ce)[ref->prop.offset]);
+ member_p = &CE_STATIC_MEMBERS(intern->ce)[ref->prop.offset];
+ ZVAL_DEREF(member_p);
+ ZVAL_COPY(return_value, member_p);
} else {
const char *class_name, *prop_name;
size_t prop_name_len;
@@ -5659,7 +5661,8 @@ ZEND_METHOD(reflection_property, getValue)
zend_unmangle_property_name_ex(ref->prop.name, &class_name, &prop_name, &prop_name_len);
member_p = zend_read_property(ref->ce, object, prop_name, prop_name_len, 1, &rv);
- ZVAL_DUP(return_value, member_p);
+ ZVAL_DEREF(member_p);
+ ZVAL_COPY(return_value, member_p);
}
}
/* }}} */
diff --git a/ext/standard/var.c b/ext/standard/var.c
index acb1d40c01..76d92a5fd3 100644
--- a/ext/standard/var.c
+++ b/ext/standard/var.c
@@ -1080,6 +1080,11 @@ PHP_FUNCTION(unserialize)
in case nesting calls to unserialize */
var_push_dtor(&var_hash, return_value);
+ /* Ensure return value is a value */
+ if (Z_ISREF_P(return_value)) {
+ zend_unwrap_reference(return_value);
+ }
+
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
if (class_hash) {
zend_hash_destroy(class_hash);