]> granicus.if.org Git - php/commitdiff
Fixed variations of bug #35163
authorDmitry Stogov <dmitry@php.net>
Tue, 23 Oct 2007 12:52:51 +0000 (12:52 +0000)
committerDmitry Stogov <dmitry@php.net>
Tue, 23 Oct 2007 12:52:51 +0000 (12:52 +0000)
Zend/tests/bug35163_2.phpt [new file with mode: 0755]
Zend/tests/bug35163_3.phpt [new file with mode: 0755]
Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

diff --git a/Zend/tests/bug35163_2.phpt b/Zend/tests/bug35163_2.phpt
new file mode 100755 (executable)
index 0000000..4adf770
--- /dev/null
@@ -0,0 +1,65 @@
+--TEST--
+Bug #35163.2 (Array elements can lose references)
+--FILE--
+<?php
+$a = array(1);
+$b = 'a';
+${$b}[] =& $$b;
+${$b}[] =& $$b;
+${$b}[0] = 2;
+var_dump($a);
+$a[0] = null;
+$a = null;
+?>
+--EXPECT--
+array(3) {
+  [0]=>
+  int(2)
+  [1]=>
+  &array(3) {
+    [0]=>
+    int(2)
+    [1]=>
+    &array(3) {
+      [0]=>
+      int(2)
+      [1]=>
+      *RECURSION*
+      [2]=>
+      *RECURSION*
+    }
+    [2]=>
+    &array(3) {
+      [0]=>
+      int(2)
+      [1]=>
+      *RECURSION*
+      [2]=>
+      *RECURSION*
+    }
+  }
+  [2]=>
+  &array(3) {
+    [0]=>
+    int(2)
+    [1]=>
+    &array(3) {
+      [0]=>
+      int(2)
+      [1]=>
+      *RECURSION*
+      [2]=>
+      *RECURSION*
+    }
+    [2]=>
+    &array(3) {
+      [0]=>
+      int(2)
+      [1]=>
+      *RECURSION*
+      [2]=>
+      *RECURSION*
+    }
+  }
+}
+
diff --git a/Zend/tests/bug35163_3.phpt b/Zend/tests/bug35163_3.phpt
new file mode 100755 (executable)
index 0000000..d34b94e
--- /dev/null
@@ -0,0 +1,65 @@
+--TEST--
+Bug #35163.3 (Array elements can lose references)
+--FILE--
+<?php
+$a = new stdClass;
+$a->b = array(1);
+$a->b[] =& $a->b;
+$a->b[] =& $a->b;
+$a->b[0] = 2;
+var_dump($a);
+$a->b = null;
+$a = null;
+?>
+--EXPECT--
+object(stdClass)#1 (1) {
+  ["b"]=>
+  &array(3) {
+    [0]=>
+    int(2)
+    [1]=>
+    &array(3) {
+      [0]=>
+      int(2)
+      [1]=>
+      *RECURSION*
+      [2]=>
+      *RECURSION*
+    }
+    [2]=>
+    &array(3) {
+      [0]=>
+      int(2)
+      [1]=>
+      *RECURSION*
+      [2]=>
+      *RECURSION*
+    }
+  }
+}
+--UEXPECT--
+object(stdClass)#1 (1) {
+  [u"b"]=>
+  &array(3) {
+    [0]=>
+    int(2)
+    [1]=>
+    &array(3) {
+      [0]=>
+      int(2)
+      [1]=>
+      *RECURSION*
+      [2]=>
+      *RECURSION*
+    }
+    [2]=>
+    &array(3) {
+      [0]=>
+      int(2)
+      [1]=>
+      *RECURSION*
+      [2]=>
+      *RECURSION*
+    }
+  }
+}
index 25ca7f95819160ddbb37b665d266537ee5e944b2..963f7c2d1e3980b5360a03089c65f0bad2d8783c 100644 (file)
@@ -988,8 +988,8 @@ void zend_do_end_variable_parse(int type, int arg_offset TSRMLS_DC) /* {{{ */
                        if (le == NULL) break;
                        opline_ptr = (zend_op *)le->data;
                }
-               if (opline->opcode == ZEND_FETCH_DIM_W) {
-                       opline->extended_value = arg_offset;
+               if (type == BP_VAR_W && arg_offset) {
+                       opline->extended_value = ZEND_FETCH_MAKE_REF;
                }
        }
        zend_llist_destroy(fetch_list_ptr);
index 8b86cd3e50dbb0c3204c57157f40bc142b6c6f2a..ec26c360a0c5f11d59ba5958c57dec8e15264965 100644 (file)
@@ -692,7 +692,8 @@ int zendlex(znode *zendlval TSRMLS_DC);
 #define ZEND_HANDLE_STREAM                     5
 
 #define ZEND_FETCH_STANDARD            0
-#define ZEND_FETCH_ADD_LOCK            1
+#define ZEND_FETCH_ADD_LOCK            (1<<0)
+#define ZEND_FETCH_MAKE_REF            (1<<1)
 
 #define ZEND_FE_FETCH_BYREF    1
 #define ZEND_FE_FETCH_WITH_KEY 2
index 3a94dbed791357065b92ed903aa0bf3809bc6588..5956bf90efdc6ece71e7625b204f29f7bc54efa0 100644 (file)
@@ -1014,6 +1014,9 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMP|VAR|CV, ANY, int type
                zval_dtor(varname);
        }
        if (!RETURN_VALUE_UNUSED(&opline->result)) {
+               if (opline->extended_value & ZEND_FETCH_MAKE_REF) {
+                       SEPARATE_ZVAL_TO_MAKE_IS_REF(retval);
+               }
                EX_T(opline->result.u.var).var.ptr_ptr = retval;
                PZVAL_LOCK(*retval);
                switch (type) {
@@ -1104,7 +1107,7 @@ ZEND_VM_HANDLER(84, ZEND_FETCH_DIM_W, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
        FREE_OP1_VAR_PTR();
        
        /* We are going to assign the result by reference */
-       if (opline->extended_value) {           
+       if (opline->extended_value) {
                Z_DELREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
                SEPARATE_ZVAL_TO_MAKE_IS_REF(EX_T(opline->result.u.var).var.ptr_ptr);
                Z_ADDREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
@@ -1275,7 +1278,7 @@ ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
        zend_free_op free_op1, free_op2;
        zval *property = GET_OP2_ZVAL_PTR(BP_VAR_R);
 
-       if (opline->extended_value == ZEND_FETCH_ADD_LOCK && OP1_TYPE != IS_CV) {
+       if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && OP1_TYPE != IS_CV) {
                PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
                EX_T(opline->op1.u.var).var.ptr = *EX_T(opline->op1.u.var).var.ptr_ptr;
        }
@@ -1295,6 +1298,14 @@ ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
                AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
        FREE_OP1_VAR_PTR();
+
+       /* We are going to assign the result by reference */
+       if (opline->extended_value & ZEND_FETCH_MAKE_REF) {
+               Z_DELREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+               SEPARATE_ZVAL_TO_MAKE_IS_REF(EX_T(opline->result.u.var).var.ptr_ptr);
+               Z_ADDREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+       }
+       
        ZEND_VM_NEXT_OPCODE();
 }
 
index 807253dc184f82b84eba86377b03e7bb34302096..5d1d7af5b7c05c36dd6d6e87d990b2a61a79dbc8 100644 (file)
@@ -1353,6 +1353,9 @@ static int zend_fetch_var_address_helper_SPEC_CONST(int type, ZEND_OPCODE_HANDLE
                zval_dtor(varname);
        }
        if (!RETURN_VALUE_UNUSED(&opline->result)) {
+               if (opline->extended_value & ZEND_FETCH_MAKE_REF) {
+                       SEPARATE_ZVAL_TO_MAKE_IS_REF(retval);
+               }
                EX_T(opline->result.u.var).var.ptr_ptr = retval;
                PZVAL_LOCK(*retval);
                switch (type) {
@@ -4557,6 +4560,9 @@ static int zend_fetch_var_address_helper_SPEC_TMP(int type, ZEND_OPCODE_HANDLER_
                zval_dtor(varname);
        }
        if (!RETURN_VALUE_UNUSED(&opline->result)) {
+               if (opline->extended_value & ZEND_FETCH_MAKE_REF) {
+                       SEPARATE_ZVAL_TO_MAKE_IS_REF(retval);
+               }
                EX_T(opline->result.u.var).var.ptr_ptr = retval;
                PZVAL_LOCK(*retval);
                switch (type) {
@@ -7751,6 +7757,9 @@ static int zend_fetch_var_address_helper_SPEC_VAR(int type, ZEND_OPCODE_HANDLER_
                zval_dtor(varname);
        }
        if (!RETURN_VALUE_UNUSED(&opline->result)) {
+               if (opline->extended_value & ZEND_FETCH_MAKE_REF) {
+                       SEPARATE_ZVAL_TO_MAKE_IS_REF(retval);
+               }
                EX_T(opline->result.u.var).var.ptr_ptr = retval;
                PZVAL_LOCK(*retval);
                switch (type) {
@@ -9825,7 +9834,7 @@ static int ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zend_free_op free_op1;
        zval *property = &opline->op2.u.constant;
 
-       if (opline->extended_value == ZEND_FETCH_ADD_LOCK && IS_VAR != IS_CV) {
+       if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && IS_VAR != IS_CV) {
                PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
                EX_T(opline->op1.u.var).var.ptr = *EX_T(opline->op1.u.var).var.ptr_ptr;
        }
@@ -9845,6 +9854,14 @@ static int ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+
+       /* We are going to assign the result by reference */
+       if (opline->extended_value & ZEND_FETCH_MAKE_REF) {
+               Z_DELREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+               SEPARATE_ZVAL_TO_MAKE_IS_REF(EX_T(opline->result.u.var).var.ptr_ptr);
+               Z_ADDREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+       }
+
        ZEND_VM_NEXT_OPCODE();
 }
 
@@ -11561,7 +11578,7 @@ static int ZEND_FETCH_OBJ_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zend_free_op free_op1, free_op2;
        zval *property = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
 
-       if (opline->extended_value == ZEND_FETCH_ADD_LOCK && IS_VAR != IS_CV) {
+       if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && IS_VAR != IS_CV) {
                PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
                EX_T(opline->op1.u.var).var.ptr = *EX_T(opline->op1.u.var).var.ptr_ptr;
        }
@@ -11581,6 +11598,14 @@ static int ZEND_FETCH_OBJ_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+
+       /* We are going to assign the result by reference */
+       if (opline->extended_value & ZEND_FETCH_MAKE_REF) {
+               Z_DELREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+               SEPARATE_ZVAL_TO_MAKE_IS_REF(EX_T(opline->result.u.var).var.ptr_ptr);
+               Z_ADDREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+       }
+
        ZEND_VM_NEXT_OPCODE();
 }
 
@@ -13206,7 +13231,7 @@ static int ZEND_FETCH_OBJ_W_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zend_free_op free_op1, free_op2;
        zval *property = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
 
-       if (opline->extended_value == ZEND_FETCH_ADD_LOCK && IS_VAR != IS_CV) {
+       if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && IS_VAR != IS_CV) {
                PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
                EX_T(opline->op1.u.var).var.ptr = *EX_T(opline->op1.u.var).var.ptr_ptr;
        }
@@ -13226,6 +13251,14 @@ static int ZEND_FETCH_OBJ_W_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+
+       /* We are going to assign the result by reference */
+       if (opline->extended_value & ZEND_FETCH_MAKE_REF) {
+               Z_DELREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+               SEPARATE_ZVAL_TO_MAKE_IS_REF(EX_T(opline->result.u.var).var.ptr_ptr);
+               Z_ADDREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+       }
+
        ZEND_VM_NEXT_OPCODE();
 }
 
@@ -15422,7 +15455,7 @@ static int ZEND_FETCH_OBJ_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zend_free_op free_op1;
        zval *property = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
 
-       if (opline->extended_value == ZEND_FETCH_ADD_LOCK && IS_VAR != IS_CV) {
+       if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && IS_VAR != IS_CV) {
                PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
                EX_T(opline->op1.u.var).var.ptr = *EX_T(opline->op1.u.var).var.ptr_ptr;
        }
@@ -15442,6 +15475,14 @@ static int ZEND_FETCH_OBJ_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+
+       /* We are going to assign the result by reference */
+       if (opline->extended_value & ZEND_FETCH_MAKE_REF) {
+               Z_DELREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+               SEPARATE_ZVAL_TO_MAKE_IS_REF(EX_T(opline->result.u.var).var.ptr_ptr);
+               Z_ADDREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+       }
+
        ZEND_VM_NEXT_OPCODE();
 }
 
@@ -16808,7 +16849,7 @@ static int ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zend_free_op free_op1;
        zval *property = &opline->op2.u.constant;
 
-       if (opline->extended_value == ZEND_FETCH_ADD_LOCK && IS_UNUSED != IS_CV) {
+       if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && IS_UNUSED != IS_CV) {
                PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
                EX_T(opline->op1.u.var).var.ptr = *EX_T(opline->op1.u.var).var.ptr_ptr;
        }
@@ -16828,6 +16869,13 @@ static int ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
 
+       /* We are going to assign the result by reference */
+       if (opline->extended_value & ZEND_FETCH_MAKE_REF) {
+               Z_DELREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+               SEPARATE_ZVAL_TO_MAKE_IS_REF(EX_T(opline->result.u.var).var.ptr_ptr);
+               Z_ADDREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+       }
+
        ZEND_VM_NEXT_OPCODE();
 }
 
@@ -17893,7 +17941,7 @@ static int ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zend_free_op free_op1, free_op2;
        zval *property = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
 
-       if (opline->extended_value == ZEND_FETCH_ADD_LOCK && IS_UNUSED != IS_CV) {
+       if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && IS_UNUSED != IS_CV) {
                PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
                EX_T(opline->op1.u.var).var.ptr = *EX_T(opline->op1.u.var).var.ptr_ptr;
        }
@@ -17913,6 +17961,13 @@ static int ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
 
+       /* We are going to assign the result by reference */
+       if (opline->extended_value & ZEND_FETCH_MAKE_REF) {
+               Z_DELREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+               SEPARATE_ZVAL_TO_MAKE_IS_REF(EX_T(opline->result.u.var).var.ptr_ptr);
+               Z_ADDREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+       }
+
        ZEND_VM_NEXT_OPCODE();
 }
 
@@ -18912,7 +18967,7 @@ static int ZEND_FETCH_OBJ_W_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zend_free_op free_op1, free_op2;
        zval *property = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
 
-       if (opline->extended_value == ZEND_FETCH_ADD_LOCK && IS_UNUSED != IS_CV) {
+       if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && IS_UNUSED != IS_CV) {
                PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
                EX_T(opline->op1.u.var).var.ptr = *EX_T(opline->op1.u.var).var.ptr_ptr;
        }
@@ -18932,6 +18987,13 @@ static int ZEND_FETCH_OBJ_W_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
 
+       /* We are going to assign the result by reference */
+       if (opline->extended_value & ZEND_FETCH_MAKE_REF) {
+               Z_DELREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+               SEPARATE_ZVAL_TO_MAKE_IS_REF(EX_T(opline->result.u.var).var.ptr_ptr);
+               Z_ADDREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+       }
+
        ZEND_VM_NEXT_OPCODE();
 }
 
@@ -20196,7 +20258,7 @@ static int ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zend_free_op free_op1;
        zval *property = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
 
-       if (opline->extended_value == ZEND_FETCH_ADD_LOCK && IS_UNUSED != IS_CV) {
+       if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && IS_UNUSED != IS_CV) {
                PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
                EX_T(opline->op1.u.var).var.ptr = *EX_T(opline->op1.u.var).var.ptr_ptr;
        }
@@ -20216,6 +20278,13 @@ static int ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
 
+       /* We are going to assign the result by reference */
+       if (opline->extended_value & ZEND_FETCH_MAKE_REF) {
+               Z_DELREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+               SEPARATE_ZVAL_TO_MAKE_IS_REF(EX_T(opline->result.u.var).var.ptr_ptr);
+               Z_ADDREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+       }
+
        ZEND_VM_NEXT_OPCODE();
 }
 
@@ -21021,6 +21090,9 @@ static int zend_fetch_var_address_helper_SPEC_CV(int type, ZEND_OPCODE_HANDLER_A
                zval_dtor(varname);
        }
        if (!RETURN_VALUE_UNUSED(&opline->result)) {
+               if (opline->extended_value & ZEND_FETCH_MAKE_REF) {
+                       SEPARATE_ZVAL_TO_MAKE_IS_REF(retval);
+               }
                EX_T(opline->result.u.var).var.ptr_ptr = retval;
                PZVAL_LOCK(*retval);
                switch (type) {
@@ -22920,7 +22992,7 @@ static int ZEND_FETCH_OBJ_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zend_free_op free_op1;
        zval *property = &opline->op2.u.constant;
 
-       if (opline->extended_value == ZEND_FETCH_ADD_LOCK && IS_CV != IS_CV) {
+       if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && IS_CV != IS_CV) {
                PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
                EX_T(opline->op1.u.var).var.ptr = *EX_T(opline->op1.u.var).var.ptr_ptr;
        }
@@ -22940,6 +23012,13 @@ static int ZEND_FETCH_OBJ_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
 
+       /* We are going to assign the result by reference */
+       if (opline->extended_value & ZEND_FETCH_MAKE_REF) {
+               Z_DELREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+               SEPARATE_ZVAL_TO_MAKE_IS_REF(EX_T(opline->result.u.var).var.ptr_ptr);
+               Z_ADDREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+       }
+
        ZEND_VM_NEXT_OPCODE();
 }
 
@@ -24490,7 +24569,7 @@ static int ZEND_FETCH_OBJ_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zend_free_op free_op1, free_op2;
        zval *property = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
 
-       if (opline->extended_value == ZEND_FETCH_ADD_LOCK && IS_CV != IS_CV) {
+       if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && IS_CV != IS_CV) {
                PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
                EX_T(opline->op1.u.var).var.ptr = *EX_T(opline->op1.u.var).var.ptr_ptr;
        }
@@ -24510,6 +24589,13 @@ static int ZEND_FETCH_OBJ_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
 
+       /* We are going to assign the result by reference */
+       if (opline->extended_value & ZEND_FETCH_MAKE_REF) {
+               Z_DELREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+               SEPARATE_ZVAL_TO_MAKE_IS_REF(EX_T(opline->result.u.var).var.ptr_ptr);
+               Z_ADDREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+       }
+
        ZEND_VM_NEXT_OPCODE();
 }
 
@@ -26036,7 +26122,7 @@ static int ZEND_FETCH_OBJ_W_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zend_free_op free_op1, free_op2;
        zval *property = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
 
-       if (opline->extended_value == ZEND_FETCH_ADD_LOCK && IS_CV != IS_CV) {
+       if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && IS_CV != IS_CV) {
                PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
                EX_T(opline->op1.u.var).var.ptr = *EX_T(opline->op1.u.var).var.ptr_ptr;
        }
@@ -26056,6 +26142,13 @@ static int ZEND_FETCH_OBJ_W_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
 
+       /* We are going to assign the result by reference */
+       if (opline->extended_value & ZEND_FETCH_MAKE_REF) {
+               Z_DELREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+               SEPARATE_ZVAL_TO_MAKE_IS_REF(EX_T(opline->result.u.var).var.ptr_ptr);
+               Z_ADDREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+       }
+
        ZEND_VM_NEXT_OPCODE();
 }
 
@@ -28060,7 +28153,7 @@ static int ZEND_FETCH_OBJ_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zend_free_op free_op1;
        zval *property = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
 
-       if (opline->extended_value == ZEND_FETCH_ADD_LOCK && IS_CV != IS_CV) {
+       if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && IS_CV != IS_CV) {
                PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
                EX_T(opline->op1.u.var).var.ptr = *EX_T(opline->op1.u.var).var.ptr_ptr;
        }
@@ -28080,6 +28173,13 @@ static int ZEND_FETCH_OBJ_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
 
+       /* We are going to assign the result by reference */
+       if (opline->extended_value & ZEND_FETCH_MAKE_REF) {
+               Z_DELREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+               SEPARATE_ZVAL_TO_MAKE_IS_REF(EX_T(opline->result.u.var).var.ptr_ptr);
+               Z_ADDREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+       }
+
        ZEND_VM_NEXT_OPCODE();
 }