]> granicus.if.org Git - php/commitdiff
Remove IS_VAR_RET_REF flag
authorNikita Popov <nikic@php.net>
Sun, 10 Apr 2016 11:01:54 +0000 (13:01 +0200)
committerNikita Popov <nikic@php.net>
Fri, 15 Apr 2016 13:32:20 +0000 (15:32 +0200)
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.

Zend/zend_execute.c
Zend/zend_operators.c
Zend/zend_operators.h
Zend/zend_types.h
Zend/zend_vm_def.h
Zend/zend_vm_execute.h
ext/opcache/Optimizer/zend_func_info.c
ext/reflection/php_reflection.c
ext/standard/var.c

index a23b843bc60e1a65f50892424e9db6c712486a72..f14434bff92b01e09ff434605ada553614a04b8c 100644 (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);
index 06a0f75386dd7dccbaa6458eda300c0754f7eeba..c1a798665043019ac33361952583607031a53162 100644 (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:
index db6162a4e52b3c8a4a3cef03b925078322aa7068..405ca0926f5cd29034db9ec08124a5cd7531b91a 100644 (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
index d3fa56080b4b7407af052e8097bac67360c72b10..9545b53e33ea8fc6cf35ac61d4a1f453124a54d6 100644 (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          */
index c1f3fad2edd7f921d949564f87529af88414b514..6c9adea30bc5b2b812a32a3c406f9002e49f0a0f 100644 (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 */
index 6128e6c4fc045d81e6acc0f9684242eacf5ff475..0fc68995357f582b85d6107daf1611bb40feb10c 100644 (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);
index 2aa3ecb928c80718447d66a17db6c745107562ab..a684a16e73e9a0614213fb7def7e25c377559cb1 100644 (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),
index dd3bd6e94d9e56fc038f7acacc957f7ae08ff550..186df87fd7363205479e7f1e345d169b770b136f 100644 (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);
        }
 }
 /* }}} */
index acb1d40c0171c2699035913aa63d153b64ca5270..76d92a5fd3c68c0d7f904be99093f44db872847d 100644 (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);