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.
This commit is contained in:
Nikita Popov 2016-04-10 13:01:54 +02:00
parent fd2cd35429
commit 64f91774f2
9 changed files with 160 additions and 176 deletions

View file

@ -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);

View file

@ -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:

View file

@ -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

View file

@ -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 */

View file

@ -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 */

View file

@ -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);

View file

@ -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),

View file

@ -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);
}
}
/* }}} */

View file

@ -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);