]> granicus.if.org Git - php/commitdiff
New sarbage collector's bug was fixed (the behavior should be the same as in PHP_5_0)
authorDmitry Stogov <dmitry@php.net>
Fri, 24 Dec 2004 09:00:29 +0000 (09:00 +0000)
committerDmitry Stogov <dmitry@php.net>
Fri, 24 Dec 2004 09:00:29 +0000 (09:00 +0000)
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index cc7e83ff0fcd3dc26746ccc28863b05d6a685ee3..5aa2d28512ab1607de1d3ae6374c0b150e4c3f95 100644 (file)
@@ -382,7 +382,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_helper, VAR|UNUSED|CV, CONST|TMP|VAR|CV,
                case ZEND_ASSIGN_DIM: {
                                zval **object_ptr = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_W);
 
-                               if(OP1_TYPE != IS_CV) {
+                               if (OP1_TYPE != IS_CV && free_op1.var == NULL) {
                                        (*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
                                }
 
@@ -1252,10 +1252,7 @@ ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV)
                zend_free_op free_op2, free_op_data1;
                zval *value;
 
-               if (object_ptr && OP1_TYPE != IS_CV) {
-                       (*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
-               }
-               zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), GET_OP1_ZVAL_PTR_PTR(BP_VAR_W), GET_OP2_ZVAL_PTR(BP_VAR_R), BP_VAR_W TSRMLS_CC);
+               zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, GET_OP2_ZVAL_PTR(BP_VAR_R), BP_VAR_W TSRMLS_CC);
                FREE_OP2();
 
                value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
@@ -1924,7 +1921,9 @@ ZEND_VM_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY)
                        if (EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr
                                || (opline->extended_value == ZEND_RETURNS_FUNCTION && !EX_T(opline->op1.u.var).var.fcall_returned_reference)) {
                                zend_error(E_STRICT, "Only variable references should be returned by reference");
-                               PZVAL_LOCK(*retval_ptr_ptr); /* undo the effect of get_zval_ptr_ptr() */
+                               if (OP1_TYPE == IS_VAR && free_op1.var == NULL) {
+                                       PZVAL_LOCK(*retval_ptr_ptr); /* undo the effect of get_zval_ptr_ptr() */
+                               }
                                ZEND_VM_C_GOTO(return_by_value);
                        }
                }
index cfbbfbe1fee5978206ad9712b6b09669dfc611a5..2103541000ab31c132cecc834647f7c9e09197b2 100644 (file)
@@ -1539,7 +1539,9 @@ static int ZEND_RETURN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                        if (EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr
                                || (opline->extended_value == ZEND_RETURNS_FUNCTION && !EX_T(opline->op1.u.var).var.fcall_returned_reference)) {
                                zend_error(E_STRICT, "Only variable references should be returned by reference");
-                               PZVAL_LOCK(*retval_ptr_ptr); /* undo the effect of get_zval_ptr_ptr() */
+                               if (IS_CONST == IS_VAR && free_op1.var == NULL) {
+                                       PZVAL_LOCK(*retval_ptr_ptr); /* undo the effect of get_zval_ptr_ptr() */
+                               }
                                goto return_by_value;
                        }
                }
@@ -3940,7 +3942,9 @@ static int ZEND_RETURN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                        if (EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr
                                || (opline->extended_value == ZEND_RETURNS_FUNCTION && !EX_T(opline->op1.u.var).var.fcall_returned_reference)) {
                                zend_error(E_STRICT, "Only variable references should be returned by reference");
-                               PZVAL_LOCK(*retval_ptr_ptr); /* undo the effect of get_zval_ptr_ptr() */
+                               if (IS_TMP_VAR == IS_VAR && free_op1.var == NULL) {
+                                       PZVAL_LOCK(*retval_ptr_ptr); /* undo the effect of get_zval_ptr_ptr() */
+                               }
                                goto return_by_value;
                        }
                }
@@ -6899,7 +6903,9 @@ static int ZEND_RETURN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                        if (EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr
                                || (opline->extended_value == ZEND_RETURNS_FUNCTION && !EX_T(opline->op1.u.var).var.fcall_returned_reference)) {
                                zend_error(E_STRICT, "Only variable references should be returned by reference");
-                               PZVAL_LOCK(*retval_ptr_ptr); /* undo the effect of get_zval_ptr_ptr() */
+                               if (IS_VAR == IS_VAR && free_op1.var == NULL) {
+                                       PZVAL_LOCK(*retval_ptr_ptr); /* undo the effect of get_zval_ptr_ptr() */
+                               }
                                goto return_by_value;
                        }
                }
@@ -8084,7 +8090,7 @@ static int zend_binary_assign_op_helper_SPEC_VAR_CONST(int (*binary_op)(zval *re
                case ZEND_ASSIGN_DIM: {
                                zval **object_ptr = _get_obj_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
 
-                               if(IS_VAR != IS_CV) {
+                               if (IS_VAR != IS_CV && free_op1.var == NULL) {
                                        (*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
                                }
 
@@ -8616,10 +8622,7 @@ static int ZEND_ASSIGN_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                zend_free_op free_op2, free_op_data1;
                zval *value;
 
-               if (object_ptr && IS_VAR != IS_CV) {
-                       (*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
-               }
-               zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), _get_zval_ptr_const(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC), BP_VAR_W TSRMLS_CC);
+               zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, _get_zval_ptr_const(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC), BP_VAR_W TSRMLS_CC);
                ;
 
                value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
@@ -9400,7 +9403,7 @@ static int zend_binary_assign_op_helper_SPEC_VAR_TMP(int (*binary_op)(zval *resu
                case ZEND_ASSIGN_DIM: {
                                zval **object_ptr = _get_obj_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
 
-                               if(IS_VAR != IS_CV) {
+                               if (IS_VAR != IS_CV && free_op1.var == NULL) {
                                        (*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
                                }
 
@@ -9932,10 +9935,7 @@ static int ZEND_ASSIGN_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                zend_free_op free_op2, free_op_data1;
                zval *value;
 
-               if (object_ptr && IS_VAR != IS_CV) {
-                       (*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
-               }
-               zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC), BP_VAR_W TSRMLS_CC);
+               zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC), BP_VAR_W TSRMLS_CC);
                zval_dtor(free_op2.var);
 
                value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
@@ -10716,7 +10716,7 @@ static int zend_binary_assign_op_helper_SPEC_VAR_VAR(int (*binary_op)(zval *resu
                case ZEND_ASSIGN_DIM: {
                                zval **object_ptr = _get_obj_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
 
-                               if(IS_VAR != IS_CV) {
+                               if (IS_VAR != IS_CV && free_op1.var == NULL) {
                                        (*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
                                }
 
@@ -11248,10 +11248,7 @@ static int ZEND_ASSIGN_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                zend_free_op free_op2, free_op_data1;
                zval *value;
 
-               if (object_ptr && IS_VAR != IS_CV) {
-                       (*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
-               }
-               zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC), BP_VAR_W TSRMLS_CC);
+               zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC), BP_VAR_W TSRMLS_CC);
                if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
 
                value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
@@ -11722,10 +11719,7 @@ static int ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                zend_free_op free_op2, free_op_data1;
                zval *value;
 
-               if (object_ptr && IS_VAR != IS_CV) {
-                       (*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
-               }
-               zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), _get_zval_ptr_unused(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC), BP_VAR_W TSRMLS_CC);
+               zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, _get_zval_ptr_unused(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC), BP_VAR_W TSRMLS_CC);
                ;
 
                value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
@@ -12186,7 +12180,7 @@ static int zend_binary_assign_op_helper_SPEC_VAR_CV(int (*binary_op)(zval *resul
                case ZEND_ASSIGN_DIM: {
                                zval **object_ptr = _get_obj_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
 
-                               if(IS_VAR != IS_CV) {
+                               if (IS_VAR != IS_CV && free_op1.var == NULL) {
                                        (*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
                                }
 
@@ -12718,10 +12712,7 @@ static int ZEND_ASSIGN_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                zend_free_op free_op2, free_op_data1;
                zval *value;
 
-               if (object_ptr && IS_VAR != IS_CV) {
-                       (*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
-               }
-               zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), _get_zval_ptr_cv(&opline->op2, EX(Ts), &free_op2, BP_VAR_R TSRMLS_CC), BP_VAR_W TSRMLS_CC);
+               zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, _get_zval_ptr_cv(&opline->op2, EX(Ts), &free_op2, BP_VAR_R TSRMLS_CC), BP_VAR_W TSRMLS_CC);
                ;
 
                value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
@@ -13365,7 +13356,7 @@ static int zend_binary_assign_op_helper_SPEC_UNUSED_CONST(int (*binary_op)(zval
                case ZEND_ASSIGN_DIM: {
                                zval **object_ptr = _get_obj_zval_ptr_ptr_unused(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
 
-                               if(IS_UNUSED != IS_CV) {
+                               if (IS_UNUSED != IS_CV && free_op1.var == NULL) {
                                        (*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
                                }
 
@@ -13810,10 +13801,7 @@ static int ZEND_ASSIGN_DIM_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                zend_free_op free_op2, free_op_data1;
                zval *value;
 
-               if (object_ptr && IS_UNUSED != IS_CV) {
-                       (*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
-               }
-               zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), _get_zval_ptr_ptr_unused(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), _get_zval_ptr_const(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC), BP_VAR_W TSRMLS_CC);
+               zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, _get_zval_ptr_const(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC), BP_VAR_W TSRMLS_CC);
                ;
 
                value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
@@ -14356,7 +14344,7 @@ static int zend_binary_assign_op_helper_SPEC_UNUSED_TMP(int (*binary_op)(zval *r
                case ZEND_ASSIGN_DIM: {
                                zval **object_ptr = _get_obj_zval_ptr_ptr_unused(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
 
-                               if(IS_UNUSED != IS_CV) {
+                               if (IS_UNUSED != IS_CV && free_op1.var == NULL) {
                                        (*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
                                }
 
@@ -14801,10 +14789,7 @@ static int ZEND_ASSIGN_DIM_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                zend_free_op free_op2, free_op_data1;
                zval *value;
 
-               if (object_ptr && IS_UNUSED != IS_CV) {
-                       (*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
-               }
-               zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), _get_zval_ptr_ptr_unused(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC), BP_VAR_W TSRMLS_CC);
+               zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC), BP_VAR_W TSRMLS_CC);
                zval_dtor(free_op2.var);
 
                value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
@@ -15306,7 +15291,7 @@ static int zend_binary_assign_op_helper_SPEC_UNUSED_VAR(int (*binary_op)(zval *r
                case ZEND_ASSIGN_DIM: {
                                zval **object_ptr = _get_obj_zval_ptr_ptr_unused(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
 
-                               if(IS_UNUSED != IS_CV) {
+                               if (IS_UNUSED != IS_CV && free_op1.var == NULL) {
                                        (*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
                                }
 
@@ -15751,10 +15736,7 @@ static int ZEND_ASSIGN_DIM_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                zend_free_op free_op2, free_op_data1;
                zval *value;
 
-               if (object_ptr && IS_UNUSED != IS_CV) {
-                       (*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
-               }
-               zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), _get_zval_ptr_ptr_unused(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC), BP_VAR_W TSRMLS_CC);
+               zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC), BP_VAR_W TSRMLS_CC);
                if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
 
                value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
@@ -16148,10 +16130,7 @@ static int ZEND_ASSIGN_DIM_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                zend_free_op free_op2, free_op_data1;
                zval *value;
 
-               if (object_ptr && IS_UNUSED != IS_CV) {
-                       (*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
-               }
-               zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), _get_zval_ptr_ptr_unused(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), _get_zval_ptr_unused(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC), BP_VAR_W TSRMLS_CC);
+               zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, _get_zval_ptr_unused(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC), BP_VAR_W TSRMLS_CC);
                ;
 
                value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
@@ -16378,7 +16357,7 @@ static int zend_binary_assign_op_helper_SPEC_UNUSED_CV(int (*binary_op)(zval *re
                case ZEND_ASSIGN_DIM: {
                                zval **object_ptr = _get_obj_zval_ptr_ptr_unused(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
 
-                               if(IS_UNUSED != IS_CV) {
+                               if (IS_UNUSED != IS_CV && free_op1.var == NULL) {
                                        (*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
                                }
 
@@ -16823,10 +16802,7 @@ static int ZEND_ASSIGN_DIM_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                zend_free_op free_op2, free_op_data1;
                zval *value;
 
-               if (object_ptr && IS_UNUSED != IS_CV) {
-                       (*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
-               }
-               zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), _get_zval_ptr_ptr_unused(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), _get_zval_ptr_cv(&opline->op2, EX(Ts), &free_op2, BP_VAR_R TSRMLS_CC), BP_VAR_W TSRMLS_CC);
+               zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, _get_zval_ptr_cv(&opline->op2, EX(Ts), &free_op2, BP_VAR_R TSRMLS_CC), BP_VAR_W TSRMLS_CC);
                ;
 
                value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
@@ -17686,7 +17662,9 @@ static int ZEND_RETURN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                        if (EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr
                                || (opline->extended_value == ZEND_RETURNS_FUNCTION && !EX_T(opline->op1.u.var).var.fcall_returned_reference)) {
                                zend_error(E_STRICT, "Only variable references should be returned by reference");
-                               PZVAL_LOCK(*retval_ptr_ptr); /* undo the effect of get_zval_ptr_ptr() */
+                               if (IS_CV == IS_VAR && free_op1.var == NULL) {
+                                       PZVAL_LOCK(*retval_ptr_ptr); /* undo the effect of get_zval_ptr_ptr() */
+                               }
                                goto return_by_value;
                        }
                }
@@ -18730,7 +18708,7 @@ static int zend_binary_assign_op_helper_SPEC_CV_CONST(int (*binary_op)(zval *res
                case ZEND_ASSIGN_DIM: {
                                zval **object_ptr = _get_obj_zval_ptr_ptr_cv(&opline->op1, EX(Ts), &free_op1, BP_VAR_W TSRMLS_CC);
 
-                               if(IS_CV != IS_CV) {
+                               if (IS_CV != IS_CV && free_op1.var == NULL) {
                                        (*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
                                }
 
@@ -19262,10 +19240,7 @@ static int ZEND_ASSIGN_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                zend_free_op free_op2, free_op_data1;
                zval *value;
 
-               if (object_ptr && IS_CV != IS_CV) {
-                       (*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
-               }
-               zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), &free_op1, BP_VAR_W TSRMLS_CC), _get_zval_ptr_const(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC), BP_VAR_W TSRMLS_CC);
+               zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, _get_zval_ptr_const(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC), BP_VAR_W TSRMLS_CC);
                ;
 
                value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
@@ -20046,7 +20021,7 @@ static int zend_binary_assign_op_helper_SPEC_CV_TMP(int (*binary_op)(zval *resul
                case ZEND_ASSIGN_DIM: {
                                zval **object_ptr = _get_obj_zval_ptr_ptr_cv(&opline->op1, EX(Ts), &free_op1, BP_VAR_W TSRMLS_CC);
 
-                               if(IS_CV != IS_CV) {
+                               if (IS_CV != IS_CV && free_op1.var == NULL) {
                                        (*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
                                }
 
@@ -20578,10 +20553,7 @@ static int ZEND_ASSIGN_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                zend_free_op free_op2, free_op_data1;
                zval *value;
 
-               if (object_ptr && IS_CV != IS_CV) {
-                       (*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
-               }
-               zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), &free_op1, BP_VAR_W TSRMLS_CC), _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC), BP_VAR_W TSRMLS_CC);
+               zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC), BP_VAR_W TSRMLS_CC);
                zval_dtor(free_op2.var);
 
                value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
@@ -21362,7 +21334,7 @@ static int zend_binary_assign_op_helper_SPEC_CV_VAR(int (*binary_op)(zval *resul
                case ZEND_ASSIGN_DIM: {
                                zval **object_ptr = _get_obj_zval_ptr_ptr_cv(&opline->op1, EX(Ts), &free_op1, BP_VAR_W TSRMLS_CC);
 
-                               if(IS_CV != IS_CV) {
+                               if (IS_CV != IS_CV && free_op1.var == NULL) {
                                        (*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
                                }
 
@@ -21894,10 +21866,7 @@ static int ZEND_ASSIGN_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                zend_free_op free_op2, free_op_data1;
                zval *value;
 
-               if (object_ptr && IS_CV != IS_CV) {
-                       (*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
-               }
-               zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), &free_op1, BP_VAR_W TSRMLS_CC), _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC), BP_VAR_W TSRMLS_CC);
+               zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC), BP_VAR_W TSRMLS_CC);
                if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
 
                value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
@@ -22368,10 +22337,7 @@ static int ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                zend_free_op free_op2, free_op_data1;
                zval *value;
 
-               if (object_ptr && IS_CV != IS_CV) {
-                       (*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
-               }
-               zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), &free_op1, BP_VAR_W TSRMLS_CC), _get_zval_ptr_unused(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC), BP_VAR_W TSRMLS_CC);
+               zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, _get_zval_ptr_unused(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC), BP_VAR_W TSRMLS_CC);
                ;
 
                value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
@@ -22832,7 +22798,7 @@ static int zend_binary_assign_op_helper_SPEC_CV_CV(int (*binary_op)(zval *result
                case ZEND_ASSIGN_DIM: {
                                zval **object_ptr = _get_obj_zval_ptr_ptr_cv(&opline->op1, EX(Ts), &free_op1, BP_VAR_W TSRMLS_CC);
 
-                               if(IS_CV != IS_CV) {
+                               if (IS_CV != IS_CV && free_op1.var == NULL) {
                                        (*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
                                }
 
@@ -23364,10 +23330,7 @@ static int ZEND_ASSIGN_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                zend_free_op free_op2, free_op_data1;
                zval *value;
 
-               if (object_ptr && IS_CV != IS_CV) {
-                       (*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
-               }
-               zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), &free_op1, BP_VAR_W TSRMLS_CC), _get_zval_ptr_cv(&opline->op2, EX(Ts), &free_op2, BP_VAR_R TSRMLS_CC), BP_VAR_W TSRMLS_CC);
+               zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, _get_zval_ptr_cv(&opline->op2, EX(Ts), &free_op2, BP_VAR_R TSRMLS_CC), BP_VAR_W TSRMLS_CC);
                ;
 
                value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
@@ -28033,7 +27996,7 @@ static int zend_binary_assign_op_helper(int (*binary_op)(zval *result, zval *op1
                case ZEND_ASSIGN_DIM: {
                                zval **object_ptr = get_obj_zval_ptr_ptr(&opline->op1, EX(Ts), &free_op1, BP_VAR_W);
 
-                               if(opline->op1.op_type != IS_CV) {
+                               if (opline->op1.op_type != IS_CV && free_op1.var == NULL) {
                                        (*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
                                }
 
@@ -28902,10 +28865,7 @@ static int ZEND_ASSIGN_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                zend_free_op free_op2, free_op_data1;
                zval *value;
 
-               if (object_ptr && opline->op1.op_type != IS_CV) {
-                       (*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
-               }
-               zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), get_zval_ptr_ptr(&opline->op1, EX(Ts), &free_op1, BP_VAR_W), get_zval_ptr(&opline->op2, EX(Ts), &free_op2, BP_VAR_R), BP_VAR_W TSRMLS_CC);
+               zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, get_zval_ptr(&opline->op2, EX(Ts), &free_op2, BP_VAR_R), BP_VAR_W TSRMLS_CC);
                FREE_OP(free_op2);
 
                value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
@@ -29574,7 +29534,9 @@ static int ZEND_RETURN_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                        if (EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr
                                || (opline->extended_value == ZEND_RETURNS_FUNCTION && !EX_T(opline->op1.u.var).var.fcall_returned_reference)) {
                                zend_error(E_STRICT, "Only variable references should be returned by reference");
-                               PZVAL_LOCK(*retval_ptr_ptr); /* undo the effect of get_zval_ptr_ptr() */
+                               if (opline->op1.op_type == IS_VAR && free_op1.var == NULL) {
+                                       PZVAL_LOCK(*retval_ptr_ptr); /* undo the effect of get_zval_ptr_ptr() */
+                               }
                                goto return_by_value;
                        }
                }