]> granicus.if.org Git - php/commitdiff
Specialization (only IS_VAR ad IS_CV operands may be references)
authorDmitry Stogov <dmitry@zend.com>
Mon, 22 Sep 2014 12:17:35 +0000 (16:17 +0400)
committerDmitry Stogov <dmitry@zend.com>
Mon, 22 Sep 2014 12:17:35 +0000 (16:17 +0400)
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index 873c9f478db0d114c05b1a16b6693003e8239805..b25ab4e8bedb0680c54768d159d1b66c1f035f6c 100644 (file)
@@ -2826,7 +2826,7 @@ ZEND_VM_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY)
                                        zval_copy_ctor_func(EX(return_value));
                                }
                        }
-               } else if (Z_ISREF_P(retval_ptr)) {
+               } else if ((OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) && Z_ISREF_P(retval_ptr)) {
                        ZVAL_COPY(EX(return_value), Z_REFVAL_P(retval_ptr));
                        FREE_OP1_IF_VAR();
                } else {
@@ -2879,9 +2879,8 @@ ZEND_VM_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY)
                        } else {
                                zend_error(E_NOTICE, "Only variable references should be returned by reference");
                                if (EX(return_value)) {
-                                       zval tmp;
-                                       ZVAL_DUP(&tmp, retval_ptr);
-                                       ZVAL_NEW_REF(EX(return_value), &tmp);
+                                       ZVAL_NEW_REF(EX(return_value), retval_ptr);
+                                       if (Z_REFCOUNTED_P(retval_ptr)) Z_ADDREF_P(retval_ptr);
                                }
                                break;
                        }
@@ -3040,7 +3039,7 @@ ZEND_VM_HANDLER(117, ZEND_SEND_VAR, VAR|CV, ANY)
        varptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
        arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
        EX(call)->num_args = opline->op2.num;
-       if (Z_ISREF_P(varptr)) {
+       if ((OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) && Z_ISREF_P(varptr)) {
                ZVAL_COPY(arg, Z_REFVAL_P(varptr));
                FREE_OP1();
        } else {
@@ -3145,7 +3144,7 @@ ZEND_VM_HANDLER(66, ZEND_SEND_VAR_EX, VAR|CV, ANY)
        varptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
        arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
        EX(call)->num_args = opline->op2.num;
-       if (Z_ISREF_P(varptr)) {
+       if ((OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) && Z_ISREF_P(varptr)) {
                ZVAL_COPY(arg, Z_REFVAL_P(varptr));
                FREE_OP1();
        } else {
@@ -3919,9 +3918,9 @@ ZEND_VM_HANDLER(72, ZEND_ADD_ARRAY_ELEMENT, CONST|TMP|VAR|CV, CONST|TMP|VAR|UNUS
                                ZVAL_DUP(&new_expr, expr_ptr);
                                expr_ptr = &new_expr;
                        }
-               } else if (Z_ISREF_P(expr_ptr)) {
-                       ZVAL_DUP(&new_expr, Z_REFVAL_P(expr_ptr));
-                       expr_ptr = &new_expr;
+               } else if ((OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) && Z_ISREF_P(expr_ptr)) {
+                       expr_ptr = Z_REFVAL_P(expr_ptr);
+                       if (Z_REFCOUNTED_P(expr_ptr)) Z_ADDREF_P(expr_ptr);
                        FREE_OP1_IF_VAR();
                } else if (OP1_TYPE == IS_CV && Z_REFCOUNTED_P(expr_ptr)) {
                        Z_ADDREF_P(expr_ptr);
@@ -5718,14 +5717,14 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|VAR|CV|UNUSE
                                ZVAL_DUP(&generator->value, value);
                        } else if (OP1_TYPE == IS_TMP_VAR) {
                                ZVAL_COPY_VALUE(&generator->value, value);
-            } else if (Z_ISREF_P(value)) {
+            } else if ((OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) && Z_ISREF_P(value)) {
                                ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
                                FREE_OP1_IF_VAR();
                        } else {
+                               ZVAL_COPY_VALUE(&generator->value, value);
                                if (OP1_TYPE == IS_CV) {
-                                       if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+                                       if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
                                }
-                               ZVAL_COPY_VALUE(&generator->value, value);
                        }
                }
        } else {
@@ -5743,14 +5742,14 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|VAR|CV|UNUSE
                        ZVAL_DUP(&generator->key, key);
                } else if (OP2_TYPE == IS_TMP_VAR) {
                        ZVAL_COPY_VALUE(&generator->key, key);
-               } else if (Z_ISREF_P(key)) {
+               } else if ((OP2_TYPE == IS_VAR || OP2_TYPE == IS_CV) && Z_ISREF_P(key)) {
                        ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
                        FREE_OP2_IF_VAR();
                } else {
+                       ZVAL_COPY_VALUE(&generator->key, key);
                        if (OP2_TYPE == IS_CV) {
-                               if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+                               if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
                        }
-                       ZVAL_COPY_VALUE(&generator->key, key);
                }
 
                if (Z_TYPE(generator->key) == IS_LONG
index a2b547544dc0616985a282ba77ae3b254d77297a..467dd4f168bc9bf7afeb8db01cfc44ae72fa4b7a 100644 (file)
@@ -2610,7 +2610,7 @@ static int ZEND_FASTCALL  ZEND_RETURN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG
                                        zval_copy_ctor_func(EX(return_value));
                                }
                        }
-               } else if (Z_ISREF_P(retval_ptr)) {
+               } else if ((IS_CONST == IS_CV || IS_CONST == IS_VAR) && Z_ISREF_P(retval_ptr)) {
                        ZVAL_COPY(EX(return_value), Z_REFVAL_P(retval_ptr));
 
                } else {
@@ -2663,9 +2663,8 @@ static int ZEND_FASTCALL  ZEND_RETURN_BY_REF_SPEC_CONST_HANDLER(ZEND_OPCODE_HAND
                        } else {
                                zend_error(E_NOTICE, "Only variable references should be returned by reference");
                                if (EX(return_value)) {
-                                       zval tmp;
-                                       ZVAL_DUP(&tmp, retval_ptr);
-                                       ZVAL_NEW_REF(EX(return_value), &tmp);
+                                       ZVAL_NEW_REF(EX(return_value), retval_ptr);
+                                       if (Z_REFCOUNTED_P(retval_ptr)) Z_ADDREF_P(retval_ptr);
                                }
                                break;
                        }
@@ -4341,9 +4340,9 @@ static int ZEND_FASTCALL  ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_HANDLER(ZEND_O
                                ZVAL_DUP(&new_expr, expr_ptr);
                                expr_ptr = &new_expr;
                        }
-               } else if (Z_ISREF_P(expr_ptr)) {
-                       ZVAL_DUP(&new_expr, Z_REFVAL_P(expr_ptr));
-                       expr_ptr = &new_expr;
+               } else if ((IS_CONST == IS_CV || IS_CONST == IS_VAR) && Z_ISREF_P(expr_ptr)) {
+                       expr_ptr = Z_REFVAL_P(expr_ptr);
+                       if (Z_REFCOUNTED_P(expr_ptr)) Z_ADDREF_P(expr_ptr);
 
                } else if (IS_CONST == IS_CV && Z_REFCOUNTED_P(expr_ptr)) {
                        Z_ADDREF_P(expr_ptr);
@@ -4832,14 +4831,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLE
                                ZVAL_DUP(&generator->value, value);
                        } else if (IS_CONST == IS_TMP_VAR) {
                                ZVAL_COPY_VALUE(&generator->value, value);
-            } else if (Z_ISREF_P(value)) {
+            } else if ((IS_CONST == IS_CV || IS_CONST == IS_VAR) && Z_ISREF_P(value)) {
                                ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
 
                        } else {
+                               ZVAL_COPY_VALUE(&generator->value, value);
                                if (IS_CONST == IS_CV) {
-                                       if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+                                       if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
                                }
-                               ZVAL_COPY_VALUE(&generator->value, value);
                        }
                }
        } else {
@@ -4857,14 +4856,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLE
                        ZVAL_DUP(&generator->key, key);
                } else if (IS_CONST == IS_TMP_VAR) {
                        ZVAL_COPY_VALUE(&generator->key, key);
-               } else if (Z_ISREF_P(key)) {
+               } else if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && Z_ISREF_P(key)) {
                        ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
 
                } else {
+                       ZVAL_COPY_VALUE(&generator->key, key);
                        if (IS_CONST == IS_CV) {
-                               if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+                               if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
                        }
-                       ZVAL_COPY_VALUE(&generator->key, key);
                }
 
                if (Z_TYPE(generator->key) == IS_LONG
@@ -5558,9 +5557,9 @@ static int ZEND_FASTCALL  ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMP_HANDLER(ZEND_OPC
                                ZVAL_DUP(&new_expr, expr_ptr);
                                expr_ptr = &new_expr;
                        }
-               } else if (Z_ISREF_P(expr_ptr)) {
-                       ZVAL_DUP(&new_expr, Z_REFVAL_P(expr_ptr));
-                       expr_ptr = &new_expr;
+               } else if ((IS_CONST == IS_CV || IS_CONST == IS_VAR) && Z_ISREF_P(expr_ptr)) {
+                       expr_ptr = Z_REFVAL_P(expr_ptr);
+                       if (Z_REFCOUNTED_P(expr_ptr)) Z_ADDREF_P(expr_ptr);
 
                } else if (IS_CONST == IS_CV && Z_REFCOUNTED_P(expr_ptr)) {
                        Z_ADDREF_P(expr_ptr);
@@ -5862,14 +5861,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_
                                ZVAL_DUP(&generator->value, value);
                        } else if (IS_CONST == IS_TMP_VAR) {
                                ZVAL_COPY_VALUE(&generator->value, value);
-            } else if (Z_ISREF_P(value)) {
+            } else if ((IS_CONST == IS_CV || IS_CONST == IS_VAR) && Z_ISREF_P(value)) {
                                ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
 
                        } else {
+                               ZVAL_COPY_VALUE(&generator->value, value);
                                if (IS_CONST == IS_CV) {
-                                       if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+                                       if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
                                }
-                               ZVAL_COPY_VALUE(&generator->value, value);
                        }
                }
        } else {
@@ -5887,14 +5886,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_
                        ZVAL_DUP(&generator->key, key);
                } else if (IS_TMP_VAR == IS_TMP_VAR) {
                        ZVAL_COPY_VALUE(&generator->key, key);
-               } else if (Z_ISREF_P(key)) {
+               } else if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && Z_ISREF_P(key)) {
                        ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
 
                } else {
+                       ZVAL_COPY_VALUE(&generator->key, key);
                        if (IS_TMP_VAR == IS_CV) {
-                               if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+                               if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
                        }
-                       ZVAL_COPY_VALUE(&generator->key, key);
                }
 
                if (Z_TYPE(generator->key) == IS_LONG
@@ -6739,9 +6738,9 @@ static int ZEND_FASTCALL  ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_VAR_HANDLER(ZEND_OPC
                                ZVAL_DUP(&new_expr, expr_ptr);
                                expr_ptr = &new_expr;
                        }
-               } else if (Z_ISREF_P(expr_ptr)) {
-                       ZVAL_DUP(&new_expr, Z_REFVAL_P(expr_ptr));
-                       expr_ptr = &new_expr;
+               } else if ((IS_CONST == IS_CV || IS_CONST == IS_VAR) && Z_ISREF_P(expr_ptr)) {
+                       expr_ptr = Z_REFVAL_P(expr_ptr);
+                       if (Z_REFCOUNTED_P(expr_ptr)) Z_ADDREF_P(expr_ptr);
 
                } else if (IS_CONST == IS_CV && Z_REFCOUNTED_P(expr_ptr)) {
                        Z_ADDREF_P(expr_ptr);
@@ -7199,14 +7198,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_
                                ZVAL_DUP(&generator->value, value);
                        } else if (IS_CONST == IS_TMP_VAR) {
                                ZVAL_COPY_VALUE(&generator->value, value);
-            } else if (Z_ISREF_P(value)) {
+            } else if ((IS_CONST == IS_CV || IS_CONST == IS_VAR) && Z_ISREF_P(value)) {
                                ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
 
                        } else {
+                               ZVAL_COPY_VALUE(&generator->value, value);
                                if (IS_CONST == IS_CV) {
-                                       if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+                                       if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
                                }
-                               ZVAL_COPY_VALUE(&generator->value, value);
                        }
                }
        } else {
@@ -7224,14 +7223,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_
                        ZVAL_DUP(&generator->key, key);
                } else if (IS_VAR == IS_TMP_VAR) {
                        ZVAL_COPY_VALUE(&generator->key, key);
-               } else if (Z_ISREF_P(key)) {
+               } else if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && Z_ISREF_P(key)) {
                        ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
                        zval_ptr_dtor_nogc(free_op2.var);
                } else {
+                       ZVAL_COPY_VALUE(&generator->key, key);
                        if (IS_VAR == IS_CV) {
-                               if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+                               if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
                        }
-                       ZVAL_COPY_VALUE(&generator->key, key);
                }
 
                if (Z_TYPE(generator->key) == IS_LONG
@@ -7608,9 +7607,9 @@ static int ZEND_FASTCALL  ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_HANDLER(ZEND_
                                ZVAL_DUP(&new_expr, expr_ptr);
                                expr_ptr = &new_expr;
                        }
-               } else if (Z_ISREF_P(expr_ptr)) {
-                       ZVAL_DUP(&new_expr, Z_REFVAL_P(expr_ptr));
-                       expr_ptr = &new_expr;
+               } else if ((IS_CONST == IS_CV || IS_CONST == IS_VAR) && Z_ISREF_P(expr_ptr)) {
+                       expr_ptr = Z_REFVAL_P(expr_ptr);
+                       if (Z_REFCOUNTED_P(expr_ptr)) Z_ADDREF_P(expr_ptr);
 
                } else if (IS_CONST == IS_CV && Z_REFCOUNTED_P(expr_ptr)) {
                        Z_ADDREF_P(expr_ptr);
@@ -7946,14 +7945,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDL
                                ZVAL_DUP(&generator->value, value);
                        } else if (IS_CONST == IS_TMP_VAR) {
                                ZVAL_COPY_VALUE(&generator->value, value);
-            } else if (Z_ISREF_P(value)) {
+            } else if ((IS_CONST == IS_CV || IS_CONST == IS_VAR) && Z_ISREF_P(value)) {
                                ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
 
                        } else {
+                               ZVAL_COPY_VALUE(&generator->value, value);
                                if (IS_CONST == IS_CV) {
-                                       if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+                                       if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
                                }
-                               ZVAL_COPY_VALUE(&generator->value, value);
                        }
                }
        } else {
@@ -7971,14 +7970,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDL
                        ZVAL_DUP(&generator->key, key);
                } else if (IS_UNUSED == IS_TMP_VAR) {
                        ZVAL_COPY_VALUE(&generator->key, key);
-               } else if (Z_ISREF_P(key)) {
+               } else if ((IS_UNUSED == IS_VAR || IS_UNUSED == IS_CV) && Z_ISREF_P(key)) {
                        ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
 
                } else {
+                       ZVAL_COPY_VALUE(&generator->key, key);
                        if (IS_UNUSED == IS_CV) {
-                               if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+                               if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
                        }
-                       ZVAL_COPY_VALUE(&generator->key, key);
                }
 
                if (Z_TYPE(generator->key) == IS_LONG
@@ -8706,9 +8705,9 @@ static int ZEND_FASTCALL  ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_HANDLER(ZEND_OPCO
                                ZVAL_DUP(&new_expr, expr_ptr);
                                expr_ptr = &new_expr;
                        }
-               } else if (Z_ISREF_P(expr_ptr)) {
-                       ZVAL_DUP(&new_expr, Z_REFVAL_P(expr_ptr));
-                       expr_ptr = &new_expr;
+               } else if ((IS_CONST == IS_CV || IS_CONST == IS_VAR) && Z_ISREF_P(expr_ptr)) {
+                       expr_ptr = Z_REFVAL_P(expr_ptr);
+                       if (Z_REFCOUNTED_P(expr_ptr)) Z_ADDREF_P(expr_ptr);
 
                } else if (IS_CONST == IS_CV && Z_REFCOUNTED_P(expr_ptr)) {
                        Z_ADDREF_P(expr_ptr);
@@ -9008,14 +9007,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_A
                                ZVAL_DUP(&generator->value, value);
                        } else if (IS_CONST == IS_TMP_VAR) {
                                ZVAL_COPY_VALUE(&generator->value, value);
-            } else if (Z_ISREF_P(value)) {
+            } else if ((IS_CONST == IS_CV || IS_CONST == IS_VAR) && Z_ISREF_P(value)) {
                                ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
 
                        } else {
+                               ZVAL_COPY_VALUE(&generator->value, value);
                                if (IS_CONST == IS_CV) {
-                                       if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+                                       if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
                                }
-                               ZVAL_COPY_VALUE(&generator->value, value);
                        }
                }
        } else {
@@ -9033,14 +9032,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_A
                        ZVAL_DUP(&generator->key, key);
                } else if (IS_CV == IS_TMP_VAR) {
                        ZVAL_COPY_VALUE(&generator->key, key);
-               } else if (Z_ISREF_P(key)) {
+               } else if ((IS_CV == IS_VAR || IS_CV == IS_CV) && Z_ISREF_P(key)) {
                        ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
 
                } else {
+                       ZVAL_COPY_VALUE(&generator->key, key);
                        if (IS_CV == IS_CV) {
-                               if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+                               if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
                        }
-                       ZVAL_COPY_VALUE(&generator->key, key);
                }
 
                if (Z_TYPE(generator->key) == IS_LONG
@@ -9334,7 +9333,7 @@ static int ZEND_FASTCALL  ZEND_RETURN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                                        zval_copy_ctor_func(EX(return_value));
                                }
                        }
-               } else if (Z_ISREF_P(retval_ptr)) {
+               } else if ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) && Z_ISREF_P(retval_ptr)) {
                        ZVAL_COPY(EX(return_value), Z_REFVAL_P(retval_ptr));
 
                } else {
@@ -9387,9 +9386,8 @@ static int ZEND_FASTCALL  ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLE
                        } else {
                                zend_error(E_NOTICE, "Only variable references should be returned by reference");
                                if (EX(return_value)) {
-                                       zval tmp;
-                                       ZVAL_DUP(&tmp, retval_ptr);
-                                       ZVAL_NEW_REF(EX(return_value), &tmp);
+                                       ZVAL_NEW_REF(EX(return_value), retval_ptr);
+                                       if (Z_REFCOUNTED_P(retval_ptr)) Z_ADDREF_P(retval_ptr);
                                }
                                break;
                        }
@@ -10941,9 +10939,9 @@ static int ZEND_FASTCALL  ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_HANDLER(ZEND_OPC
                                ZVAL_DUP(&new_expr, expr_ptr);
                                expr_ptr = &new_expr;
                        }
-               } else if (Z_ISREF_P(expr_ptr)) {
-                       ZVAL_DUP(&new_expr, Z_REFVAL_P(expr_ptr));
-                       expr_ptr = &new_expr;
+               } else if ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) && Z_ISREF_P(expr_ptr)) {
+                       expr_ptr = Z_REFVAL_P(expr_ptr);
+                       if (Z_REFCOUNTED_P(expr_ptr)) Z_ADDREF_P(expr_ptr);
 
                } else if (IS_TMP_VAR == IS_CV && Z_REFCOUNTED_P(expr_ptr)) {
                        Z_ADDREF_P(expr_ptr);
@@ -11399,14 +11397,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_
                                ZVAL_DUP(&generator->value, value);
                        } else if (IS_TMP_VAR == IS_TMP_VAR) {
                                ZVAL_COPY_VALUE(&generator->value, value);
-            } else if (Z_ISREF_P(value)) {
+            } else if ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) && Z_ISREF_P(value)) {
                                ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
 
                        } else {
+                               ZVAL_COPY_VALUE(&generator->value, value);
                                if (IS_TMP_VAR == IS_CV) {
-                                       if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+                                       if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
                                }
-                               ZVAL_COPY_VALUE(&generator->value, value);
                        }
                }
        } else {
@@ -11424,14 +11422,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_
                        ZVAL_DUP(&generator->key, key);
                } else if (IS_CONST == IS_TMP_VAR) {
                        ZVAL_COPY_VALUE(&generator->key, key);
-               } else if (Z_ISREF_P(key)) {
+               } else if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && Z_ISREF_P(key)) {
                        ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
 
                } else {
+                       ZVAL_COPY_VALUE(&generator->key, key);
                        if (IS_CONST == IS_CV) {
-                               if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+                               if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
                        }
-                       ZVAL_COPY_VALUE(&generator->key, key);
                }
 
                if (Z_TYPE(generator->key) == IS_LONG
@@ -12082,9 +12080,9 @@ static int ZEND_FASTCALL  ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP_HANDLER(ZEND_OPCOD
                                ZVAL_DUP(&new_expr, expr_ptr);
                                expr_ptr = &new_expr;
                        }
-               } else if (Z_ISREF_P(expr_ptr)) {
-                       ZVAL_DUP(&new_expr, Z_REFVAL_P(expr_ptr));
-                       expr_ptr = &new_expr;
+               } else if ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) && Z_ISREF_P(expr_ptr)) {
+                       expr_ptr = Z_REFVAL_P(expr_ptr);
+                       if (Z_REFCOUNTED_P(expr_ptr)) Z_ADDREF_P(expr_ptr);
 
                } else if (IS_TMP_VAR == IS_CV && Z_REFCOUNTED_P(expr_ptr)) {
                        Z_ADDREF_P(expr_ptr);
@@ -12386,14 +12384,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
                                ZVAL_DUP(&generator->value, value);
                        } else if (IS_TMP_VAR == IS_TMP_VAR) {
                                ZVAL_COPY_VALUE(&generator->value, value);
-            } else if (Z_ISREF_P(value)) {
+            } else if ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) && Z_ISREF_P(value)) {
                                ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
 
                        } else {
+                               ZVAL_COPY_VALUE(&generator->value, value);
                                if (IS_TMP_VAR == IS_CV) {
-                                       if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+                                       if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
                                }
-                               ZVAL_COPY_VALUE(&generator->value, value);
                        }
                }
        } else {
@@ -12411,14 +12409,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
                        ZVAL_DUP(&generator->key, key);
                } else if (IS_TMP_VAR == IS_TMP_VAR) {
                        ZVAL_COPY_VALUE(&generator->key, key);
-               } else if (Z_ISREF_P(key)) {
+               } else if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && Z_ISREF_P(key)) {
                        ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
 
                } else {
+                       ZVAL_COPY_VALUE(&generator->key, key);
                        if (IS_TMP_VAR == IS_CV) {
-                               if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+                               if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
                        }
-                       ZVAL_COPY_VALUE(&generator->key, key);
                }
 
                if (Z_TYPE(generator->key) == IS_LONG
@@ -13220,9 +13218,9 @@ static int ZEND_FASTCALL  ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_VAR_HANDLER(ZEND_OPCOD
                                ZVAL_DUP(&new_expr, expr_ptr);
                                expr_ptr = &new_expr;
                        }
-               } else if (Z_ISREF_P(expr_ptr)) {
-                       ZVAL_DUP(&new_expr, Z_REFVAL_P(expr_ptr));
-                       expr_ptr = &new_expr;
+               } else if ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) && Z_ISREF_P(expr_ptr)) {
+                       expr_ptr = Z_REFVAL_P(expr_ptr);
+                       if (Z_REFCOUNTED_P(expr_ptr)) Z_ADDREF_P(expr_ptr);
 
                } else if (IS_TMP_VAR == IS_CV && Z_REFCOUNTED_P(expr_ptr)) {
                        Z_ADDREF_P(expr_ptr);
@@ -13680,14 +13678,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
                                ZVAL_DUP(&generator->value, value);
                        } else if (IS_TMP_VAR == IS_TMP_VAR) {
                                ZVAL_COPY_VALUE(&generator->value, value);
-            } else if (Z_ISREF_P(value)) {
+            } else if ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) && Z_ISREF_P(value)) {
                                ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
 
                        } else {
+                               ZVAL_COPY_VALUE(&generator->value, value);
                                if (IS_TMP_VAR == IS_CV) {
-                                       if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+                                       if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
                                }
-                               ZVAL_COPY_VALUE(&generator->value, value);
                        }
                }
        } else {
@@ -13705,14 +13703,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
                        ZVAL_DUP(&generator->key, key);
                } else if (IS_VAR == IS_TMP_VAR) {
                        ZVAL_COPY_VALUE(&generator->key, key);
-               } else if (Z_ISREF_P(key)) {
+               } else if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && Z_ISREF_P(key)) {
                        ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
                        zval_ptr_dtor_nogc(free_op2.var);
                } else {
+                       ZVAL_COPY_VALUE(&generator->key, key);
                        if (IS_VAR == IS_CV) {
-                               if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+                               if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
                        }
-                       ZVAL_COPY_VALUE(&generator->key, key);
                }
 
                if (Z_TYPE(generator->key) == IS_LONG
@@ -13973,9 +13971,9 @@ static int ZEND_FASTCALL  ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_HANDLER(ZEND_OP
                                ZVAL_DUP(&new_expr, expr_ptr);
                                expr_ptr = &new_expr;
                        }
-               } else if (Z_ISREF_P(expr_ptr)) {
-                       ZVAL_DUP(&new_expr, Z_REFVAL_P(expr_ptr));
-                       expr_ptr = &new_expr;
+               } else if ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) && Z_ISREF_P(expr_ptr)) {
+                       expr_ptr = Z_REFVAL_P(expr_ptr);
+                       if (Z_REFCOUNTED_P(expr_ptr)) Z_ADDREF_P(expr_ptr);
 
                } else if (IS_TMP_VAR == IS_CV && Z_REFCOUNTED_P(expr_ptr)) {
                        Z_ADDREF_P(expr_ptr);
@@ -14286,14 +14284,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER
                                ZVAL_DUP(&generator->value, value);
                        } else if (IS_TMP_VAR == IS_TMP_VAR) {
                                ZVAL_COPY_VALUE(&generator->value, value);
-            } else if (Z_ISREF_P(value)) {
+            } else if ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) && Z_ISREF_P(value)) {
                                ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
 
                        } else {
+                               ZVAL_COPY_VALUE(&generator->value, value);
                                if (IS_TMP_VAR == IS_CV) {
-                                       if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+                                       if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
                                }
-                               ZVAL_COPY_VALUE(&generator->value, value);
                        }
                }
        } else {
@@ -14311,14 +14309,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER
                        ZVAL_DUP(&generator->key, key);
                } else if (IS_UNUSED == IS_TMP_VAR) {
                        ZVAL_COPY_VALUE(&generator->key, key);
-               } else if (Z_ISREF_P(key)) {
+               } else if ((IS_UNUSED == IS_VAR || IS_UNUSED == IS_CV) && Z_ISREF_P(key)) {
                        ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
 
                } else {
+                       ZVAL_COPY_VALUE(&generator->key, key);
                        if (IS_UNUSED == IS_CV) {
-                               if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+                               if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
                        }
-                       ZVAL_COPY_VALUE(&generator->key, key);
                }
 
                if (Z_TYPE(generator->key) == IS_LONG
@@ -14949,9 +14947,9 @@ static int ZEND_FASTCALL  ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE
                                ZVAL_DUP(&new_expr, expr_ptr);
                                expr_ptr = &new_expr;
                        }
-               } else if (Z_ISREF_P(expr_ptr)) {
-                       ZVAL_DUP(&new_expr, Z_REFVAL_P(expr_ptr));
-                       expr_ptr = &new_expr;
+               } else if ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) && Z_ISREF_P(expr_ptr)) {
+                       expr_ptr = Z_REFVAL_P(expr_ptr);
+                       if (Z_REFCOUNTED_P(expr_ptr)) Z_ADDREF_P(expr_ptr);
 
                } else if (IS_TMP_VAR == IS_CV && Z_REFCOUNTED_P(expr_ptr)) {
                        Z_ADDREF_P(expr_ptr);
@@ -15251,14 +15249,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
                                ZVAL_DUP(&generator->value, value);
                        } else if (IS_TMP_VAR == IS_TMP_VAR) {
                                ZVAL_COPY_VALUE(&generator->value, value);
-            } else if (Z_ISREF_P(value)) {
+            } else if ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) && Z_ISREF_P(value)) {
                                ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
 
                        } else {
+                               ZVAL_COPY_VALUE(&generator->value, value);
                                if (IS_TMP_VAR == IS_CV) {
-                                       if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+                                       if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
                                }
-                               ZVAL_COPY_VALUE(&generator->value, value);
                        }
                }
        } else {
@@ -15276,14 +15274,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
                        ZVAL_DUP(&generator->key, key);
                } else if (IS_CV == IS_TMP_VAR) {
                        ZVAL_COPY_VALUE(&generator->key, key);
-               } else if (Z_ISREF_P(key)) {
+               } else if ((IS_CV == IS_VAR || IS_CV == IS_CV) && Z_ISREF_P(key)) {
                        ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
 
                } else {
+                       ZVAL_COPY_VALUE(&generator->key, key);
                        if (IS_CV == IS_CV) {
-                               if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+                               if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
                        }
-                       ZVAL_COPY_VALUE(&generator->key, key);
                }
 
                if (Z_TYPE(generator->key) == IS_LONG
@@ -15799,7 +15797,7 @@ static int ZEND_FASTCALL  ZEND_RETURN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                                        zval_copy_ctor_func(EX(return_value));
                                }
                        }
-               } else if (Z_ISREF_P(retval_ptr)) {
+               } else if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && Z_ISREF_P(retval_ptr)) {
                        ZVAL_COPY(EX(return_value), Z_REFVAL_P(retval_ptr));
                        zval_ptr_dtor_nogc(free_op1.var);
                } else {
@@ -15852,9 +15850,8 @@ static int ZEND_FASTCALL  ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLE
                        } else {
                                zend_error(E_NOTICE, "Only variable references should be returned by reference");
                                if (EX(return_value)) {
-                                       zval tmp;
-                                       ZVAL_DUP(&tmp, retval_ptr);
-                                       ZVAL_NEW_REF(EX(return_value), &tmp);
+                                       ZVAL_NEW_REF(EX(return_value), retval_ptr);
+                                       if (Z_REFCOUNTED_P(retval_ptr)) Z_ADDREF_P(retval_ptr);
                                }
                                break;
                        }
@@ -15907,7 +15904,7 @@ static int ZEND_FASTCALL  ZEND_SEND_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
        varptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
        arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
        EX(call)->num_args = opline->op2.num;
-       if (Z_ISREF_P(varptr)) {
+       if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && Z_ISREF_P(varptr)) {
                ZVAL_COPY(arg, Z_REFVAL_P(varptr));
                zval_ptr_dtor_nogc(free_op1.var);
        } else {
@@ -16012,7 +16009,7 @@ static int ZEND_FASTCALL  ZEND_SEND_VAR_EX_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_
        varptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
        arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
        EX(call)->num_args = opline->op2.num;
-       if (Z_ISREF_P(varptr)) {
+       if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && Z_ISREF_P(varptr)) {
                ZVAL_COPY(arg, Z_REFVAL_P(varptr));
                zval_ptr_dtor_nogc(free_op1.var);
        } else {
@@ -18747,9 +18744,9 @@ static int ZEND_FASTCALL  ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(ZEND_OPC
                                ZVAL_DUP(&new_expr, expr_ptr);
                                expr_ptr = &new_expr;
                        }
-               } else if (Z_ISREF_P(expr_ptr)) {
-                       ZVAL_DUP(&new_expr, Z_REFVAL_P(expr_ptr));
-                       expr_ptr = &new_expr;
+               } else if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && Z_ISREF_P(expr_ptr)) {
+                       expr_ptr = Z_REFVAL_P(expr_ptr);
+                       if (Z_REFCOUNTED_P(expr_ptr)) Z_ADDREF_P(expr_ptr);
                        zval_ptr_dtor_nogc(free_op1.var);
                } else if (IS_VAR == IS_CV && Z_REFCOUNTED_P(expr_ptr)) {
                        Z_ADDREF_P(expr_ptr);
@@ -19324,14 +19321,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_
                                ZVAL_DUP(&generator->value, value);
                        } else if (IS_VAR == IS_TMP_VAR) {
                                ZVAL_COPY_VALUE(&generator->value, value);
-            } else if (Z_ISREF_P(value)) {
+            } else if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && Z_ISREF_P(value)) {
                                ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
                                zval_ptr_dtor_nogc(free_op1.var);
                        } else {
+                               ZVAL_COPY_VALUE(&generator->value, value);
                                if (IS_VAR == IS_CV) {
-                                       if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+                                       if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
                                }
-                               ZVAL_COPY_VALUE(&generator->value, value);
                        }
                }
        } else {
@@ -19349,14 +19346,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_
                        ZVAL_DUP(&generator->key, key);
                } else if (IS_CONST == IS_TMP_VAR) {
                        ZVAL_COPY_VALUE(&generator->key, key);
-               } else if (Z_ISREF_P(key)) {
+               } else if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && Z_ISREF_P(key)) {
                        ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
 
                } else {
+                       ZVAL_COPY_VALUE(&generator->key, key);
                        if (IS_CONST == IS_CV) {
-                               if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+                               if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
                        }
-                       ZVAL_COPY_VALUE(&generator->key, key);
                }
 
                if (Z_TYPE(generator->key) == IS_LONG
@@ -20873,9 +20870,9 @@ static int ZEND_FASTCALL  ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP_HANDLER(ZEND_OPCOD
                                ZVAL_DUP(&new_expr, expr_ptr);
                                expr_ptr = &new_expr;
                        }
-               } else if (Z_ISREF_P(expr_ptr)) {
-                       ZVAL_DUP(&new_expr, Z_REFVAL_P(expr_ptr));
-                       expr_ptr = &new_expr;
+               } else if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && Z_ISREF_P(expr_ptr)) {
+                       expr_ptr = Z_REFVAL_P(expr_ptr);
+                       if (Z_REFCOUNTED_P(expr_ptr)) Z_ADDREF_P(expr_ptr);
                        zval_ptr_dtor_nogc(free_op1.var);
                } else if (IS_VAR == IS_CV && Z_REFCOUNTED_P(expr_ptr)) {
                        Z_ADDREF_P(expr_ptr);
@@ -21296,14 +21293,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
                                ZVAL_DUP(&generator->value, value);
                        } else if (IS_VAR == IS_TMP_VAR) {
                                ZVAL_COPY_VALUE(&generator->value, value);
-            } else if (Z_ISREF_P(value)) {
+            } else if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && Z_ISREF_P(value)) {
                                ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
                                zval_ptr_dtor_nogc(free_op1.var);
                        } else {
+                               ZVAL_COPY_VALUE(&generator->value, value);
                                if (IS_VAR == IS_CV) {
-                                       if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+                                       if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
                                }
-                               ZVAL_COPY_VALUE(&generator->value, value);
                        }
                }
        } else {
@@ -21321,14 +21318,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
                        ZVAL_DUP(&generator->key, key);
                } else if (IS_TMP_VAR == IS_TMP_VAR) {
                        ZVAL_COPY_VALUE(&generator->key, key);
-               } else if (Z_ISREF_P(key)) {
+               } else if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && Z_ISREF_P(key)) {
                        ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
 
                } else {
+                       ZVAL_COPY_VALUE(&generator->key, key);
                        if (IS_TMP_VAR == IS_CV) {
-                               if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+                               if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
                        }
-                       ZVAL_COPY_VALUE(&generator->key, key);
                }
 
                if (Z_TYPE(generator->key) == IS_LONG
@@ -23060,9 +23057,9 @@ static int ZEND_FASTCALL  ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_VAR_HANDLER(ZEND_OPCOD
                                ZVAL_DUP(&new_expr, expr_ptr);
                                expr_ptr = &new_expr;
                        }
-               } else if (Z_ISREF_P(expr_ptr)) {
-                       ZVAL_DUP(&new_expr, Z_REFVAL_P(expr_ptr));
-                       expr_ptr = &new_expr;
+               } else if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && Z_ISREF_P(expr_ptr)) {
+                       expr_ptr = Z_REFVAL_P(expr_ptr);
+                       if (Z_REFCOUNTED_P(expr_ptr)) Z_ADDREF_P(expr_ptr);
                        zval_ptr_dtor_nogc(free_op1.var);
                } else if (IS_VAR == IS_CV && Z_REFCOUNTED_P(expr_ptr)) {
                        Z_ADDREF_P(expr_ptr);
@@ -23639,14 +23636,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
                                ZVAL_DUP(&generator->value, value);
                        } else if (IS_VAR == IS_TMP_VAR) {
                                ZVAL_COPY_VALUE(&generator->value, value);
-            } else if (Z_ISREF_P(value)) {
+            } else if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && Z_ISREF_P(value)) {
                                ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
                                zval_ptr_dtor_nogc(free_op1.var);
                        } else {
+                               ZVAL_COPY_VALUE(&generator->value, value);
                                if (IS_VAR == IS_CV) {
-                                       if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+                                       if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
                                }
-                               ZVAL_COPY_VALUE(&generator->value, value);
                        }
                }
        } else {
@@ -23664,14 +23661,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
                        ZVAL_DUP(&generator->key, key);
                } else if (IS_VAR == IS_TMP_VAR) {
                        ZVAL_COPY_VALUE(&generator->key, key);
-               } else if (Z_ISREF_P(key)) {
+               } else if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && Z_ISREF_P(key)) {
                        ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
                        zval_ptr_dtor_nogc(free_op2.var);
                } else {
+                       ZVAL_COPY_VALUE(&generator->key, key);
                        if (IS_VAR == IS_CV) {
-                               if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+                               if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
                        }
-                       ZVAL_COPY_VALUE(&generator->key, key);
                }
 
                if (Z_TYPE(generator->key) == IS_LONG
@@ -24511,9 +24508,9 @@ static int ZEND_FASTCALL  ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OP
                                ZVAL_DUP(&new_expr, expr_ptr);
                                expr_ptr = &new_expr;
                        }
-               } else if (Z_ISREF_P(expr_ptr)) {
-                       ZVAL_DUP(&new_expr, Z_REFVAL_P(expr_ptr));
-                       expr_ptr = &new_expr;
+               } else if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && Z_ISREF_P(expr_ptr)) {
+                       expr_ptr = Z_REFVAL_P(expr_ptr);
+                       if (Z_REFCOUNTED_P(expr_ptr)) Z_ADDREF_P(expr_ptr);
                        zval_ptr_dtor_nogc(free_op1.var);
                } else if (IS_VAR == IS_CV && Z_REFCOUNTED_P(expr_ptr)) {
                        Z_ADDREF_P(expr_ptr);
@@ -24843,14 +24840,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER
                                ZVAL_DUP(&generator->value, value);
                        } else if (IS_VAR == IS_TMP_VAR) {
                                ZVAL_COPY_VALUE(&generator->value, value);
-            } else if (Z_ISREF_P(value)) {
+            } else if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && Z_ISREF_P(value)) {
                                ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
                                zval_ptr_dtor_nogc(free_op1.var);
                        } else {
+                               ZVAL_COPY_VALUE(&generator->value, value);
                                if (IS_VAR == IS_CV) {
-                                       if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+                                       if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
                                }
-                               ZVAL_COPY_VALUE(&generator->value, value);
                        }
                }
        } else {
@@ -24868,14 +24865,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER
                        ZVAL_DUP(&generator->key, key);
                } else if (IS_UNUSED == IS_TMP_VAR) {
                        ZVAL_COPY_VALUE(&generator->key, key);
-               } else if (Z_ISREF_P(key)) {
+               } else if ((IS_UNUSED == IS_VAR || IS_UNUSED == IS_CV) && Z_ISREF_P(key)) {
                        ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
 
                } else {
+                       ZVAL_COPY_VALUE(&generator->key, key);
                        if (IS_UNUSED == IS_CV) {
-                               if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+                               if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
                        }
-                       ZVAL_COPY_VALUE(&generator->key, key);
                }
 
                if (Z_TYPE(generator->key) == IS_LONG
@@ -26432,9 +26429,9 @@ static int ZEND_FASTCALL  ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE
                                ZVAL_DUP(&new_expr, expr_ptr);
                                expr_ptr = &new_expr;
                        }
-               } else if (Z_ISREF_P(expr_ptr)) {
-                       ZVAL_DUP(&new_expr, Z_REFVAL_P(expr_ptr));
-                       expr_ptr = &new_expr;
+               } else if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && Z_ISREF_P(expr_ptr)) {
+                       expr_ptr = Z_REFVAL_P(expr_ptr);
+                       if (Z_REFCOUNTED_P(expr_ptr)) Z_ADDREF_P(expr_ptr);
                        zval_ptr_dtor_nogc(free_op1.var);
                } else if (IS_VAR == IS_CV && Z_REFCOUNTED_P(expr_ptr)) {
                        Z_ADDREF_P(expr_ptr);
@@ -26853,14 +26850,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
                                ZVAL_DUP(&generator->value, value);
                        } else if (IS_VAR == IS_TMP_VAR) {
                                ZVAL_COPY_VALUE(&generator->value, value);
-            } else if (Z_ISREF_P(value)) {
+            } else if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && Z_ISREF_P(value)) {
                                ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
                                zval_ptr_dtor_nogc(free_op1.var);
                        } else {
+                               ZVAL_COPY_VALUE(&generator->value, value);
                                if (IS_VAR == IS_CV) {
-                                       if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+                                       if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
                                }
-                               ZVAL_COPY_VALUE(&generator->value, value);
                        }
                }
        } else {
@@ -26878,14 +26875,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
                        ZVAL_DUP(&generator->key, key);
                } else if (IS_CV == IS_TMP_VAR) {
                        ZVAL_COPY_VALUE(&generator->key, key);
-               } else if (Z_ISREF_P(key)) {
+               } else if ((IS_CV == IS_VAR || IS_CV == IS_CV) && Z_ISREF_P(key)) {
                        ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
 
                } else {
+                       ZVAL_COPY_VALUE(&generator->key, key);
                        if (IS_CV == IS_CV) {
-                               if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+                               if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
                        }
-                       ZVAL_COPY_VALUE(&generator->key, key);
                }
 
                if (Z_TYPE(generator->key) == IS_LONG
@@ -28305,14 +28302,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDL
                                ZVAL_DUP(&generator->value, value);
                        } else if (IS_UNUSED == IS_TMP_VAR) {
                                ZVAL_COPY_VALUE(&generator->value, value);
-            } else if (Z_ISREF_P(value)) {
+            } else if ((IS_UNUSED == IS_CV || IS_UNUSED == IS_VAR) && Z_ISREF_P(value)) {
                                ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
 
                        } else {
+                               ZVAL_COPY_VALUE(&generator->value, value);
                                if (IS_UNUSED == IS_CV) {
-                                       if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+                                       if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
                                }
-                               ZVAL_COPY_VALUE(&generator->value, value);
                        }
                }
        } else {
@@ -28330,14 +28327,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDL
                        ZVAL_DUP(&generator->key, key);
                } else if (IS_CONST == IS_TMP_VAR) {
                        ZVAL_COPY_VALUE(&generator->key, key);
-               } else if (Z_ISREF_P(key)) {
+               } else if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && Z_ISREF_P(key)) {
                        ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
 
                } else {
+                       ZVAL_COPY_VALUE(&generator->key, key);
                        if (IS_CONST == IS_CV) {
-                               if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+                               if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
                        }
-                       ZVAL_COPY_VALUE(&generator->key, key);
                }
 
                if (Z_TYPE(generator->key) == IS_LONG
@@ -29580,14 +29577,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER
                                ZVAL_DUP(&generator->value, value);
                        } else if (IS_UNUSED == IS_TMP_VAR) {
                                ZVAL_COPY_VALUE(&generator->value, value);
-            } else if (Z_ISREF_P(value)) {
+            } else if ((IS_UNUSED == IS_CV || IS_UNUSED == IS_VAR) && Z_ISREF_P(value)) {
                                ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
 
                        } else {
+                               ZVAL_COPY_VALUE(&generator->value, value);
                                if (IS_UNUSED == IS_CV) {
-                                       if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+                                       if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
                                }
-                               ZVAL_COPY_VALUE(&generator->value, value);
                        }
                }
        } else {
@@ -29605,14 +29602,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER
                        ZVAL_DUP(&generator->key, key);
                } else if (IS_TMP_VAR == IS_TMP_VAR) {
                        ZVAL_COPY_VALUE(&generator->key, key);
-               } else if (Z_ISREF_P(key)) {
+               } else if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && Z_ISREF_P(key)) {
                        ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
 
                } else {
+                       ZVAL_COPY_VALUE(&generator->key, key);
                        if (IS_TMP_VAR == IS_CV) {
-                               if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+                               if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
                        }
-                       ZVAL_COPY_VALUE(&generator->key, key);
                }
 
                if (Z_TYPE(generator->key) == IS_LONG
@@ -30855,14 +30852,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER
                                ZVAL_DUP(&generator->value, value);
                        } else if (IS_UNUSED == IS_TMP_VAR) {
                                ZVAL_COPY_VALUE(&generator->value, value);
-            } else if (Z_ISREF_P(value)) {
+            } else if ((IS_UNUSED == IS_CV || IS_UNUSED == IS_VAR) && Z_ISREF_P(value)) {
                                ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
 
                        } else {
+                               ZVAL_COPY_VALUE(&generator->value, value);
                                if (IS_UNUSED == IS_CV) {
-                                       if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+                                       if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
                                }
-                               ZVAL_COPY_VALUE(&generator->value, value);
                        }
                }
        } else {
@@ -30880,14 +30877,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER
                        ZVAL_DUP(&generator->key, key);
                } else if (IS_VAR == IS_TMP_VAR) {
                        ZVAL_COPY_VALUE(&generator->key, key);
-               } else if (Z_ISREF_P(key)) {
+               } else if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && Z_ISREF_P(key)) {
                        ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
                        zval_ptr_dtor_nogc(free_op2.var);
                } else {
+                       ZVAL_COPY_VALUE(&generator->key, key);
                        if (IS_VAR == IS_CV) {
-                               if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+                               if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
                        }
-                       ZVAL_COPY_VALUE(&generator->key, key);
                }
 
                if (Z_TYPE(generator->key) == IS_LONG
@@ -31371,14 +31368,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HAND
                                ZVAL_DUP(&generator->value, value);
                        } else if (IS_UNUSED == IS_TMP_VAR) {
                                ZVAL_COPY_VALUE(&generator->value, value);
-            } else if (Z_ISREF_P(value)) {
+            } else if ((IS_UNUSED == IS_CV || IS_UNUSED == IS_VAR) && Z_ISREF_P(value)) {
                                ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
 
                        } else {
+                               ZVAL_COPY_VALUE(&generator->value, value);
                                if (IS_UNUSED == IS_CV) {
-                                       if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+                                       if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
                                }
-                               ZVAL_COPY_VALUE(&generator->value, value);
                        }
                }
        } else {
@@ -31396,14 +31393,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HAND
                        ZVAL_DUP(&generator->key, key);
                } else if (IS_UNUSED == IS_TMP_VAR) {
                        ZVAL_COPY_VALUE(&generator->key, key);
-               } else if (Z_ISREF_P(key)) {
+               } else if ((IS_UNUSED == IS_VAR || IS_UNUSED == IS_CV) && Z_ISREF_P(key)) {
                        ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
 
                } else {
+                       ZVAL_COPY_VALUE(&generator->key, key);
                        if (IS_UNUSED == IS_CV) {
-                               if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+                               if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
                        }
-                       ZVAL_COPY_VALUE(&generator->key, key);
                }
 
                if (Z_TYPE(generator->key) == IS_LONG
@@ -32637,14 +32634,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_
                                ZVAL_DUP(&generator->value, value);
                        } else if (IS_UNUSED == IS_TMP_VAR) {
                                ZVAL_COPY_VALUE(&generator->value, value);
-            } else if (Z_ISREF_P(value)) {
+            } else if ((IS_UNUSED == IS_CV || IS_UNUSED == IS_VAR) && Z_ISREF_P(value)) {
                                ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
 
                        } else {
+                               ZVAL_COPY_VALUE(&generator->value, value);
                                if (IS_UNUSED == IS_CV) {
-                                       if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+                                       if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
                                }
-                               ZVAL_COPY_VALUE(&generator->value, value);
                        }
                }
        } else {
@@ -32662,14 +32659,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_
                        ZVAL_DUP(&generator->key, key);
                } else if (IS_CV == IS_TMP_VAR) {
                        ZVAL_COPY_VALUE(&generator->key, key);
-               } else if (Z_ISREF_P(key)) {
+               } else if ((IS_CV == IS_VAR || IS_CV == IS_CV) && Z_ISREF_P(key)) {
                        ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
 
                } else {
+                       ZVAL_COPY_VALUE(&generator->key, key);
                        if (IS_CV == IS_CV) {
-                               if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+                               if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
                        }
-                       ZVAL_COPY_VALUE(&generator->key, key);
                }
 
                if (Z_TYPE(generator->key) == IS_LONG
@@ -33156,7 +33153,7 @@ static int ZEND_FASTCALL  ZEND_RETURN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                                        zval_copy_ctor_func(EX(return_value));
                                }
                        }
-               } else if (Z_ISREF_P(retval_ptr)) {
+               } else if ((IS_CV == IS_CV || IS_CV == IS_VAR) && Z_ISREF_P(retval_ptr)) {
                        ZVAL_COPY(EX(return_value), Z_REFVAL_P(retval_ptr));
 
                } else {
@@ -33209,9 +33206,8 @@ static int ZEND_FASTCALL  ZEND_RETURN_BY_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER
                        } else {
                                zend_error(E_NOTICE, "Only variable references should be returned by reference");
                                if (EX(return_value)) {
-                                       zval tmp;
-                                       ZVAL_DUP(&tmp, retval_ptr);
-                                       ZVAL_NEW_REF(EX(return_value), &tmp);
+                                       ZVAL_NEW_REF(EX(return_value), retval_ptr);
+                                       if (Z_REFCOUNTED_P(retval_ptr)) Z_ADDREF_P(retval_ptr);
                                }
                                break;
                        }
@@ -33263,7 +33259,7 @@ static int ZEND_FASTCALL  ZEND_SEND_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
        varptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
        arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
        EX(call)->num_args = opline->op2.num;
-       if (Z_ISREF_P(varptr)) {
+       if ((IS_CV == IS_CV || IS_CV == IS_VAR) && Z_ISREF_P(varptr)) {
                ZVAL_COPY(arg, Z_REFVAL_P(varptr));
 
        } else {
@@ -33367,7 +33363,7 @@ static int ZEND_FASTCALL  ZEND_SEND_VAR_EX_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_A
        varptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
        arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
        EX(call)->num_args = opline->op2.num;
-       if (Z_ISREF_P(varptr)) {
+       if ((IS_CV == IS_CV || IS_CV == IS_VAR) && Z_ISREF_P(varptr)) {
                ZVAL_COPY(arg, Z_REFVAL_P(varptr));
 
        } else {
@@ -35630,9 +35626,9 @@ static int ZEND_FASTCALL  ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER(ZEND_OPCO
                                ZVAL_DUP(&new_expr, expr_ptr);
                                expr_ptr = &new_expr;
                        }
-               } else if (Z_ISREF_P(expr_ptr)) {
-                       ZVAL_DUP(&new_expr, Z_REFVAL_P(expr_ptr));
-                       expr_ptr = &new_expr;
+               } else if ((IS_CV == IS_CV || IS_CV == IS_VAR) && Z_ISREF_P(expr_ptr)) {
+                       expr_ptr = Z_REFVAL_P(expr_ptr);
+                       if (Z_REFCOUNTED_P(expr_ptr)) Z_ADDREF_P(expr_ptr);
 
                } else if (IS_CV == IS_CV && Z_REFCOUNTED_P(expr_ptr)) {
                        Z_ADDREF_P(expr_ptr);
@@ -36206,14 +36202,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_A
                                ZVAL_DUP(&generator->value, value);
                        } else if (IS_CV == IS_TMP_VAR) {
                                ZVAL_COPY_VALUE(&generator->value, value);
-            } else if (Z_ISREF_P(value)) {
+            } else if ((IS_CV == IS_CV || IS_CV == IS_VAR) && Z_ISREF_P(value)) {
                                ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
 
                        } else {
+                               ZVAL_COPY_VALUE(&generator->value, value);
                                if (IS_CV == IS_CV) {
-                                       if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+                                       if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
                                }
-                               ZVAL_COPY_VALUE(&generator->value, value);
                        }
                }
        } else {
@@ -36231,14 +36227,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_A
                        ZVAL_DUP(&generator->key, key);
                } else if (IS_CONST == IS_TMP_VAR) {
                        ZVAL_COPY_VALUE(&generator->key, key);
-               } else if (Z_ISREF_P(key)) {
+               } else if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && Z_ISREF_P(key)) {
                        ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
 
                } else {
+                       ZVAL_COPY_VALUE(&generator->key, key);
                        if (IS_CONST == IS_CV) {
-                               if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+                               if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
                        }
-                       ZVAL_COPY_VALUE(&generator->key, key);
                }
 
                if (Z_TYPE(generator->key) == IS_LONG
@@ -37694,9 +37690,9 @@ static int ZEND_FASTCALL  ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP_HANDLER(ZEND_OPCODE
                                ZVAL_DUP(&new_expr, expr_ptr);
                                expr_ptr = &new_expr;
                        }
-               } else if (Z_ISREF_P(expr_ptr)) {
-                       ZVAL_DUP(&new_expr, Z_REFVAL_P(expr_ptr));
-                       expr_ptr = &new_expr;
+               } else if ((IS_CV == IS_CV || IS_CV == IS_VAR) && Z_ISREF_P(expr_ptr)) {
+                       expr_ptr = Z_REFVAL_P(expr_ptr);
+                       if (Z_REFCOUNTED_P(expr_ptr)) Z_ADDREF_P(expr_ptr);
 
                } else if (IS_CV == IS_CV && Z_REFCOUNTED_P(expr_ptr)) {
                        Z_ADDREF_P(expr_ptr);
@@ -38116,14 +38112,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
                                ZVAL_DUP(&generator->value, value);
                        } else if (IS_CV == IS_TMP_VAR) {
                                ZVAL_COPY_VALUE(&generator->value, value);
-            } else if (Z_ISREF_P(value)) {
+            } else if ((IS_CV == IS_CV || IS_CV == IS_VAR) && Z_ISREF_P(value)) {
                                ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
 
                        } else {
+                               ZVAL_COPY_VALUE(&generator->value, value);
                                if (IS_CV == IS_CV) {
-                                       if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+                                       if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
                                }
-                               ZVAL_COPY_VALUE(&generator->value, value);
                        }
                }
        } else {
@@ -38141,14 +38137,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
                        ZVAL_DUP(&generator->key, key);
                } else if (IS_TMP_VAR == IS_TMP_VAR) {
                        ZVAL_COPY_VALUE(&generator->key, key);
-               } else if (Z_ISREF_P(key)) {
+               } else if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && Z_ISREF_P(key)) {
                        ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
 
                } else {
+                       ZVAL_COPY_VALUE(&generator->key, key);
                        if (IS_TMP_VAR == IS_CV) {
-                               if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+                               if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
                        }
-                       ZVAL_COPY_VALUE(&generator->key, key);
                }
 
                if (Z_TYPE(generator->key) == IS_LONG
@@ -39761,9 +39757,9 @@ static int ZEND_FASTCALL  ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_VAR_HANDLER(ZEND_OPCODE
                                ZVAL_DUP(&new_expr, expr_ptr);
                                expr_ptr = &new_expr;
                        }
-               } else if (Z_ISREF_P(expr_ptr)) {
-                       ZVAL_DUP(&new_expr, Z_REFVAL_P(expr_ptr));
-                       expr_ptr = &new_expr;
+               } else if ((IS_CV == IS_CV || IS_CV == IS_VAR) && Z_ISREF_P(expr_ptr)) {
+                       expr_ptr = Z_REFVAL_P(expr_ptr);
+                       if (Z_REFCOUNTED_P(expr_ptr)) Z_ADDREF_P(expr_ptr);
 
                } else if (IS_CV == IS_CV && Z_REFCOUNTED_P(expr_ptr)) {
                        Z_ADDREF_P(expr_ptr);
@@ -40339,14 +40335,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
                                ZVAL_DUP(&generator->value, value);
                        } else if (IS_CV == IS_TMP_VAR) {
                                ZVAL_COPY_VALUE(&generator->value, value);
-            } else if (Z_ISREF_P(value)) {
+            } else if ((IS_CV == IS_CV || IS_CV == IS_VAR) && Z_ISREF_P(value)) {
                                ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
 
                        } else {
+                               ZVAL_COPY_VALUE(&generator->value, value);
                                if (IS_CV == IS_CV) {
-                                       if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+                                       if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
                                }
-                               ZVAL_COPY_VALUE(&generator->value, value);
                        }
                }
        } else {
@@ -40364,14 +40360,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
                        ZVAL_DUP(&generator->key, key);
                } else if (IS_VAR == IS_TMP_VAR) {
                        ZVAL_COPY_VALUE(&generator->key, key);
-               } else if (Z_ISREF_P(key)) {
+               } else if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && Z_ISREF_P(key)) {
                        ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
                        zval_ptr_dtor_nogc(free_op2.var);
                } else {
+                       ZVAL_COPY_VALUE(&generator->key, key);
                        if (IS_VAR == IS_CV) {
-                               if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+                               if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
                        }
-                       ZVAL_COPY_VALUE(&generator->key, key);
                }
 
                if (Z_TYPE(generator->key) == IS_LONG
@@ -41094,9 +41090,9 @@ static int ZEND_FASTCALL  ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER(ZEND_OPC
                                ZVAL_DUP(&new_expr, expr_ptr);
                                expr_ptr = &new_expr;
                        }
-               } else if (Z_ISREF_P(expr_ptr)) {
-                       ZVAL_DUP(&new_expr, Z_REFVAL_P(expr_ptr));
-                       expr_ptr = &new_expr;
+               } else if ((IS_CV == IS_CV || IS_CV == IS_VAR) && Z_ISREF_P(expr_ptr)) {
+                       expr_ptr = Z_REFVAL_P(expr_ptr);
+                       if (Z_REFCOUNTED_P(expr_ptr)) Z_ADDREF_P(expr_ptr);
 
                } else if (IS_CV == IS_CV && Z_REFCOUNTED_P(expr_ptr)) {
                        Z_ADDREF_P(expr_ptr);
@@ -41407,14 +41403,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_
                                ZVAL_DUP(&generator->value, value);
                        } else if (IS_CV == IS_TMP_VAR) {
                                ZVAL_COPY_VALUE(&generator->value, value);
-            } else if (Z_ISREF_P(value)) {
+            } else if ((IS_CV == IS_CV || IS_CV == IS_VAR) && Z_ISREF_P(value)) {
                                ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
 
                        } else {
+                               ZVAL_COPY_VALUE(&generator->value, value);
                                if (IS_CV == IS_CV) {
-                                       if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+                                       if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
                                }
-                               ZVAL_COPY_VALUE(&generator->value, value);
                        }
                }
        } else {
@@ -41432,14 +41428,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_
                        ZVAL_DUP(&generator->key, key);
                } else if (IS_UNUSED == IS_TMP_VAR) {
                        ZVAL_COPY_VALUE(&generator->key, key);
-               } else if (Z_ISREF_P(key)) {
+               } else if ((IS_UNUSED == IS_VAR || IS_UNUSED == IS_CV) && Z_ISREF_P(key)) {
                        ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
 
                } else {
+                       ZVAL_COPY_VALUE(&generator->key, key);
                        if (IS_UNUSED == IS_CV) {
-                               if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+                               if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
                        }
-                       ZVAL_COPY_VALUE(&generator->key, key);
                }
 
                if (Z_TYPE(generator->key) == IS_LONG
@@ -42877,9 +42873,9 @@ static int ZEND_FASTCALL  ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_
                                ZVAL_DUP(&new_expr, expr_ptr);
                                expr_ptr = &new_expr;
                        }
-               } else if (Z_ISREF_P(expr_ptr)) {
-                       ZVAL_DUP(&new_expr, Z_REFVAL_P(expr_ptr));
-                       expr_ptr = &new_expr;
+               } else if ((IS_CV == IS_CV || IS_CV == IS_VAR) && Z_ISREF_P(expr_ptr)) {
+                       expr_ptr = Z_REFVAL_P(expr_ptr);
+                       if (Z_REFCOUNTED_P(expr_ptr)) Z_ADDREF_P(expr_ptr);
 
                } else if (IS_CV == IS_CV && Z_REFCOUNTED_P(expr_ptr)) {
                        Z_ADDREF_P(expr_ptr);
@@ -43297,14 +43293,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
                                ZVAL_DUP(&generator->value, value);
                        } else if (IS_CV == IS_TMP_VAR) {
                                ZVAL_COPY_VALUE(&generator->value, value);
-            } else if (Z_ISREF_P(value)) {
+            } else if ((IS_CV == IS_CV || IS_CV == IS_VAR) && Z_ISREF_P(value)) {
                                ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
 
                        } else {
+                               ZVAL_COPY_VALUE(&generator->value, value);
                                if (IS_CV == IS_CV) {
-                                       if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+                                       if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
                                }
-                               ZVAL_COPY_VALUE(&generator->value, value);
                        }
                }
        } else {
@@ -43322,14 +43318,14 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
                        ZVAL_DUP(&generator->key, key);
                } else if (IS_CV == IS_TMP_VAR) {
                        ZVAL_COPY_VALUE(&generator->key, key);
-               } else if (Z_ISREF_P(key)) {
+               } else if ((IS_CV == IS_VAR || IS_CV == IS_CV) && Z_ISREF_P(key)) {
                        ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
 
                } else {
+                       ZVAL_COPY_VALUE(&generator->key, key);
                        if (IS_CV == IS_CV) {
-                               if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+                               if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
                        }
-                       ZVAL_COPY_VALUE(&generator->key, key);
                }
 
                if (Z_TYPE(generator->key) == IS_LONG