From: Dmitry Stogov Date: Wed, 6 Jul 2016 17:46:43 +0000 (+0300) Subject: Fixed bug #72543 (Different references behavior comparing to PHP 5) X-Git-Tag: php-7.1.0beta1~163 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=023b81259325c00012c0f703976c082be72dc5b9;p=php Fixed bug #72543 (Different references behavior comparing to PHP 5) --- diff --git a/NEWS b/NEWS index 470052bd2b..e3af5613f8 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,10 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? 2016, PHP 7.1.0beta1 +- Core: + . Fixed bug #72543 (Different references behavior comparing to PHP 5) + (Laruence, Dmitry, Nikita) + - pcntl . Implemented asynchronous signal handling without TICKS. (Dmitry) diff --git a/Zend/tests/bug72543.phpt b/Zend/tests/bug72543.phpt new file mode 100644 index 0000000000..4244b8ce41 --- /dev/null +++ b/Zend/tests/bug72543.phpt @@ -0,0 +1,39 @@ +--TEST-- +Bug #72543 (different references behavior comparing to PHP 5) +--FILE-- + $value) { + create_references($array[$key]); + } +} + +function change_copy($copy) { + $copy['b']['z']['z'] = $copy['b']; +} + +$data = [ + 'a' => [ + 'b' => [], + ], +]; + +create_references($data); + +$copy = $data['a']; +var_dump($copy); + +change_copy($copy); +var_dump($copy); //RECURSION +?> +--EXPECT-- +array(1) { + ["b"]=> + array(0) { + } +} +array(1) { + ["b"]=> + array(0) { + } +} diff --git a/Zend/tests/bug72543_1.phpt b/Zend/tests/bug72543_1.phpt new file mode 100644 index 0000000000..f63ee7f14b --- /dev/null +++ b/Zend/tests/bug72543_1.phpt @@ -0,0 +1,19 @@ +--TEST-- +Bug #72543.1 (different references behavior comparing to PHP 5) +--FILE-- + +--EXPECT-- +array(1) { + [0]=> + array(1) { + [0]=> + NULL + } +} diff --git a/Zend/tests/bug72543_2.phpt b/Zend/tests/bug72543_2.phpt new file mode 100644 index 0000000000..2070d65bdd --- /dev/null +++ b/Zend/tests/bug72543_2.phpt @@ -0,0 +1,19 @@ +--TEST-- +Bug #72543.2 (different references behavior comparing to PHP 5) +--FILE-- + +--EXPECT-- +array(1) { + [0]=> + array(1) { + [""]=> + NULL + } +} diff --git a/Zend/tests/bug72543_3.phpt b/Zend/tests/bug72543_3.phpt new file mode 100644 index 0000000000..3835fafaa3 --- /dev/null +++ b/Zend/tests/bug72543_3.phpt @@ -0,0 +1,12 @@ +--TEST-- +Bug #72543.3 (different references behavior comparing to PHP 5) +--FILE-- +a = 1; +$ref =& $x->a; +unset($ref); +var_dump($x->a + ($x->a = 2)); +?> +--EXPECT-- +int(3) diff --git a/Zend/tests/bug72543_4.phpt b/Zend/tests/bug72543_4.phpt new file mode 100644 index 0000000000..3480c1c42c --- /dev/null +++ b/Zend/tests/bug72543_4.phpt @@ -0,0 +1,11 @@ +--TEST-- +Bug #72543.4 (different references behavior comparing to PHP 5) +--FILE-- + +--EXPECT-- +int(3) diff --git a/Zend/tests/bug72543_5.phpt b/Zend/tests/bug72543_5.phpt new file mode 100644 index 0000000000..66b3b75f2a --- /dev/null +++ b/Zend/tests/bug72543_5.phpt @@ -0,0 +1,10 @@ +--TEST-- +Bug #72543.5 (different references behavior comparing to PHP 5) +--FILE-- + +--EXPECT-- +int(4) diff --git a/Zend/zend_types.h b/Zend/zend_types.h index 95c4ef6e54..29dec8e97f 100644 --- a/Zend/zend_types.h +++ b/Zend/zend_types.h @@ -917,6 +917,23 @@ static zend_always_inline uint32_t zval_delref_p(zval* pz) { efree_size(ref, sizeof(zend_reference)); \ } while (0) +#define ZVAL_COPY_UNREF(z, v) do { \ + zval *_z3 = (v); \ + if (Z_REFCOUNTED_P(_z3)) { \ + if (UNEXPECTED(Z_ISREF_P(_z3)) \ + && UNEXPECTED(Z_REFCOUNT_P(_z3) == 1)) { \ + ZVAL_UNREF(_z3); \ + if (Z_REFCOUNTED_P(_z3)) { \ + Z_ADDREF_P(_z3); \ + } \ + } else { \ + Z_ADDREF_P(_z3); \ + } \ + } \ + ZVAL_COPY_VALUE(z, _z3); \ + } while (0) + + #define SEPARATE_STRING(zv) do { \ zval *_zv = (zv); \ if (Z_REFCOUNTED_P(_zv) && \ diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index f8082f91cf..f39ce0ec6a 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -1557,10 +1557,7 @@ ZEND_VM_C_LABEL(fetch_this): ZEND_ASSERT(retval != NULL); if (type == BP_VAR_R || type == BP_VAR_IS) { - if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) { - ZVAL_UNREF(retval); - } - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); } else { ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); } @@ -1698,10 +1695,7 @@ ZEND_VM_HELPER(zend_fetch_static_prop_helper, CONST|TMPVAR|CV, UNUSED|CONST|VAR, ZEND_VM_C_LABEL(fetch_static_prop_return): ZEND_ASSERT(retval != NULL); if (type == BP_VAR_R || type == BP_VAR_IS) { - if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) { - ZVAL_UNREF(retval); - } - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); } else { ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); } @@ -1758,7 +1752,7 @@ ZEND_VM_HANDLER(81, ZEND_FETCH_DIM_R, CONST|TMPVAR|CV, CONST|TMPVAR|CV) ZEND_VM_C_LABEL(fetch_dim_r_array): value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, OP2_TYPE, BP_VAR_R); result = EX_VAR(opline->result.var); - ZVAL_COPY(result, value); + ZVAL_COPY_UNREF(result, value); } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { container = Z_REFVAL_P(container); if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { @@ -1928,13 +1922,13 @@ ZEND_VM_HANDLER(82, ZEND_FETCH_OBJ_R, CONST|TMP|VAR|UNUSED|THIS|CV, CONST|TMPVAR if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); break; } } else if (EXPECTED(zobj->properties != NULL)) { retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); if (EXPECTED(retval)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); break; } } @@ -1948,7 +1942,7 @@ ZEND_VM_C_LABEL(fetch_obj_r_no_object): retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); } } } while (0); @@ -4886,14 +4880,6 @@ ZEND_VM_HANDLER(48, ZEND_CASE, CONST|TMPVAR|CV, CONST|TMPVAR|CV) SAVE_OPLINE(); if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } else if ((OP1_TYPE & IS_VAR) && UNEXPECTED(Z_ISREF_P(op1))) { - /* Don't keep lock on reference, lock the value instead */ - if (UNEXPECTED(Z_REFCOUNT_P(op1) == 1)) { - ZVAL_UNREF(op1); - } else { - Z_DELREF_P(op1); - ZVAL_COPY(op1, Z_REFVAL_P(op1)); - } } if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); @@ -8537,7 +8523,7 @@ ZEND_VM_C_LABEL(fetch_dim_r_index_array): offset = zval_get_long(dim); } ZEND_HASH_INDEX_FIND(Z_ARRVAL_P(container), offset, value, ZEND_VM_C_LABEL(fetch_dim_r_index_undef)); - ZVAL_COPY(EX_VAR(opline->result.var), value); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), value); if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) { SAVE_OPLINE(); FREE_OP1(); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index a495b59000..803414ac9d 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -4816,10 +4816,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_ fetch_static_prop_return: ZEND_ASSERT(retval != NULL); if (type == BP_VAR_R || type == BP_VAR_IS) { - if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) { - ZVAL_UNREF(retval); - } - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); } else { ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); } @@ -4876,7 +4873,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_CONST_H fetch_dim_r_array: value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CONST, BP_VAR_R); result = EX_VAR(opline->result.var); - ZVAL_COPY(result, value); + ZVAL_COPY_UNREF(result, value); } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { container = Z_REFVAL_P(container); if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { @@ -4992,13 +4989,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_CONST_H if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); break; } } else if (EXPECTED(zobj->properties != NULL)) { retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); if (EXPECTED(retval)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); break; } } @@ -5012,7 +5009,7 @@ fetch_obj_r_no_object: retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); } } } while (0); @@ -5605,14 +5602,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CONST_CONST_HANDLER( SAVE_OPLINE(); if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } else if ((IS_CONST & IS_VAR) && UNEXPECTED(Z_ISREF_P(op1))) { - /* Don't keep lock on reference, lock the value instead */ - if (UNEXPECTED(Z_REFCOUNT_P(op1) == 1)) { - ZVAL_UNREF(op1); - } else { - Z_DELREF_P(op1); - ZVAL_COPY(op1, Z_REFVAL_P(op1)); - } } if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); @@ -6330,7 +6319,7 @@ fetch_dim_r_index_array: offset = zval_get_long(dim); } ZEND_HASH_INDEX_FIND(Z_ARRVAL_P(container), offset, value, fetch_dim_r_index_undef); - ZVAL_COPY(EX_VAR(opline->result.var), value); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), value); if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { SAVE_OPLINE(); @@ -6661,10 +6650,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_ fetch_static_prop_return: ZEND_ASSERT(retval != NULL); if (type == BP_VAR_R || type == BP_VAR_IS) { - if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) { - ZVAL_UNREF(retval); - } - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); } else { ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); } @@ -7100,10 +7086,7 @@ fetch_this: ZEND_ASSERT(retval != NULL); if (type == BP_VAR_R || type == BP_VAR_IS) { - if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) { - ZVAL_UNREF(retval); - } - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); } else { ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); } @@ -7239,10 +7222,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_ fetch_static_prop_return: ZEND_ASSERT(retval != NULL); if (type == BP_VAR_R || type == BP_VAR_IS) { - if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) { - ZVAL_UNREF(retval); - } - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); } else { ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); } @@ -8728,7 +8708,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_CV_HAND fetch_dim_r_array: value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CV, BP_VAR_R); result = EX_VAR(opline->result.var); - ZVAL_COPY(result, value); + ZVAL_COPY_UNREF(result, value); } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { container = Z_REFVAL_P(container); if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { @@ -8844,13 +8824,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_CV_HAND if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); break; } } else if (EXPECTED(zobj->properties != NULL)) { retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); if (EXPECTED(retval)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); break; } } @@ -8864,7 +8844,7 @@ fetch_obj_r_no_object: retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); } } } while (0); @@ -9507,14 +9487,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CONST_CV_HANDLER(ZEN SAVE_OPLINE(); if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } else if ((IS_CONST & IS_VAR) && UNEXPECTED(Z_ISREF_P(op1))) { - /* Don't keep lock on reference, lock the value instead */ - if (UNEXPECTED(Z_REFCOUNT_P(op1) == 1)) { - ZVAL_UNREF(op1); - } else { - Z_DELREF_P(op1); - ZVAL_COPY(op1, Z_REFVAL_P(op1)); - } } if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); @@ -9979,7 +9951,7 @@ fetch_dim_r_index_array: offset = zval_get_long(dim); } ZEND_HASH_INDEX_FIND(Z_ARRVAL_P(container), offset, value, fetch_dim_r_index_undef); - ZVAL_COPY(EX_VAR(opline->result.var), value); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), value); if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { SAVE_OPLINE(); @@ -10625,7 +10597,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR_ fetch_dim_r_array: value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, (IS_TMP_VAR|IS_VAR), BP_VAR_R); result = EX_VAR(opline->result.var); - ZVAL_COPY(result, value); + ZVAL_COPY_UNREF(result, value); } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { container = Z_REFVAL_P(container); if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { @@ -10741,13 +10713,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR_ if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); break; } } else if (EXPECTED(zobj->properties != NULL)) { retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); if (EXPECTED(retval)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); break; } } @@ -10761,7 +10733,7 @@ fetch_obj_r_no_object: retval = zobj->handlers->read_property(container, offset, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); } } } while (0); @@ -11358,14 +11330,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CONST_TMPVAR_HANDLER SAVE_OPLINE(); if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } else if ((IS_CONST & IS_VAR) && UNEXPECTED(Z_ISREF_P(op1))) { - /* Don't keep lock on reference, lock the value instead */ - if (UNEXPECTED(Z_REFCOUNT_P(op1) == 1)) { - ZVAL_UNREF(op1); - } else { - Z_DELREF_P(op1); - ZVAL_COPY(op1, Z_REFVAL_P(op1)); - } } if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); @@ -11696,7 +11660,7 @@ fetch_dim_r_index_array: offset = zval_get_long(dim); } ZEND_HASH_INDEX_FIND(Z_ARRVAL_P(container), offset, value, fetch_dim_r_index_undef); - ZVAL_COPY(EX_VAR(opline->result.var), value); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), value); if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { SAVE_OPLINE(); @@ -13196,13 +13160,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMP_CONST_HAN if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); break; } } else if (EXPECTED(zobj->properties != NULL)) { retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); if (EXPECTED(retval)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); break; } } @@ -13216,7 +13180,7 @@ fetch_obj_r_no_object: retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); } } } while (0); @@ -14415,13 +14379,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMP_CV_HANDLE if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); break; } } else if (EXPECTED(zobj->properties != NULL)) { retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); if (EXPECTED(retval)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); break; } } @@ -14435,7 +14399,7 @@ fetch_obj_r_no_object: retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); } } } while (0); @@ -14936,13 +14900,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMP_TMPVAR_HA if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); break; } } else if (EXPECTED(zobj->properties != NULL)) { retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); if (EXPECTED(retval)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); break; } } @@ -14956,7 +14920,7 @@ fetch_obj_r_no_object: retval = zobj->handlers->read_property(container, offset, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); } } } while (0); @@ -18286,13 +18250,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_VAR_CONST_HAN if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); break; } } else if (EXPECTED(zobj->properties != NULL)) { retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); if (EXPECTED(retval)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); break; } } @@ -18306,7 +18270,7 @@ fetch_obj_r_no_object: retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); } } } while (0); @@ -23044,13 +23008,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_VAR_CV_HANDLE if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); break; } } else if (EXPECTED(zobj->properties != NULL)) { retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); if (EXPECTED(retval)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); break; } } @@ -23064,7 +23028,7 @@ fetch_obj_r_no_object: retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); } } } while (0); @@ -25988,13 +25952,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_VAR_TMPVAR_HA if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); break; } } else if (EXPECTED(zobj->properties != NULL)) { retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); if (EXPECTED(retval)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); break; } } @@ -26008,7 +25972,7 @@ fetch_obj_r_no_object: retval = zobj->handlers->read_property(container, offset, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); } } } while (0); @@ -28189,13 +28153,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_ if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); break; } } else if (EXPECTED(zobj->properties != NULL)) { retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); if (EXPECTED(retval)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); break; } } @@ -28209,7 +28173,7 @@ fetch_obj_r_no_object: retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); } } } while (0); @@ -30879,13 +30843,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_HAN if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); break; } } else if (EXPECTED(zobj->properties != NULL)) { retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); if (EXPECTED(retval)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); break; } } @@ -30899,7 +30863,7 @@ fetch_obj_r_no_object: retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); } } } while (0); @@ -32768,13 +32732,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); break; } } else if (EXPECTED(zobj->properties != NULL)) { retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); if (EXPECTED(retval)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); break; } } @@ -32788,7 +32752,7 @@ fetch_obj_r_no_object: retval = zobj->handlers->read_property(container, offset, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); } } } while (0); @@ -37609,10 +37573,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_ fetch_static_prop_return: ZEND_ASSERT(retval != NULL); if (type == BP_VAR_R || type == BP_VAR_IS) { - if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) { - ZVAL_UNREF(retval); - } - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); } else { ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); } @@ -37669,7 +37630,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_CONST_HAND fetch_dim_r_array: value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CONST, BP_VAR_R); result = EX_VAR(opline->result.var); - ZVAL_COPY(result, value); + ZVAL_COPY_UNREF(result, value); } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { container = Z_REFVAL_P(container); if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { @@ -37839,13 +37800,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_CONST_HAND if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); break; } } else if (EXPECTED(zobj->properties != NULL)) { retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); if (EXPECTED(retval)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); break; } } @@ -37859,7 +37820,7 @@ fetch_obj_r_no_object: retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); } } } while (0); @@ -39357,14 +39318,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CV_CONST_HANDLER(ZEN SAVE_OPLINE(); if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } else if ((IS_CV & IS_VAR) && UNEXPECTED(Z_ISREF_P(op1))) { - /* Don't keep lock on reference, lock the value instead */ - if (UNEXPECTED(Z_REFCOUNT_P(op1) == 1)) { - ZVAL_UNREF(op1); - } else { - Z_DELREF_P(op1); - ZVAL_COPY(op1, Z_REFVAL_P(op1)); - } } if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); @@ -40288,7 +40241,7 @@ fetch_dim_r_index_array: offset = zval_get_long(dim); } ZEND_HASH_INDEX_FIND(Z_ARRVAL_P(container), offset, value, fetch_dim_r_index_undef); - ZVAL_COPY(EX_VAR(opline->result.var), value); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), value); if (IS_CV & (IS_TMP_VAR|IS_VAR)) { SAVE_OPLINE(); @@ -40675,10 +40628,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_ fetch_static_prop_return: ZEND_ASSERT(retval != NULL); if (type == BP_VAR_R || type == BP_VAR_IS) { - if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) { - ZVAL_UNREF(retval); - } - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); } else { ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); } @@ -41592,10 +41542,7 @@ fetch_this: ZEND_ASSERT(retval != NULL); if (type == BP_VAR_R || type == BP_VAR_IS) { - if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) { - ZVAL_UNREF(retval); - } - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); } else { ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); } @@ -41731,10 +41678,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_ fetch_static_prop_return: ZEND_ASSERT(retval != NULL); if (type == BP_VAR_R || type == BP_VAR_IS) { - if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) { - ZVAL_UNREF(retval); - } - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); } else { ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); } @@ -44515,7 +44459,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_CV_HANDLER fetch_dim_r_array: value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CV, BP_VAR_R); result = EX_VAR(opline->result.var); - ZVAL_COPY(result, value); + ZVAL_COPY_UNREF(result, value); } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { container = Z_REFVAL_P(container); if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { @@ -44685,13 +44629,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_CV_HANDLER if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); break; } } else if (EXPECTED(zobj->properties != NULL)) { retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); if (EXPECTED(retval)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); break; } } @@ -44705,7 +44649,7 @@ fetch_obj_r_no_object: retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); } } } while (0); @@ -46256,14 +46200,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CV_CV_HANDLER(ZEND_O SAVE_OPLINE(); if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } else if ((IS_CV & IS_VAR) && UNEXPECTED(Z_ISREF_P(op1))) { - /* Don't keep lock on reference, lock the value instead */ - if (UNEXPECTED(Z_REFCOUNT_P(op1) == 1)) { - ZVAL_UNREF(op1); - } else { - Z_DELREF_P(op1); - ZVAL_COPY(op1, Z_REFVAL_P(op1)); - } } if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); @@ -46857,7 +46793,7 @@ fetch_dim_r_index_array: offset = zval_get_long(dim); } ZEND_HASH_INDEX_FIND(Z_ARRVAL_P(container), offset, value, fetch_dim_r_index_undef); - ZVAL_COPY(EX_VAR(opline->result.var), value); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), value); if (IS_CV & (IS_TMP_VAR|IS_VAR)) { SAVE_OPLINE(); @@ -48524,7 +48460,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR_HAN fetch_dim_r_array: value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, (IS_TMP_VAR|IS_VAR), BP_VAR_R); result = EX_VAR(opline->result.var); - ZVAL_COPY(result, value); + ZVAL_COPY_UNREF(result, value); } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { container = Z_REFVAL_P(container); if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { @@ -48694,13 +48630,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_HAN if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); break; } } else if (EXPECTED(zobj->properties != NULL)) { retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); if (EXPECTED(retval)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); break; } } @@ -48714,7 +48650,7 @@ fetch_obj_r_no_object: retval = zobj->handlers->read_property(container, offset, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); } } } while (0); @@ -50159,14 +50095,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CV_TMPVAR_HANDLER(ZE SAVE_OPLINE(); if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } else if ((IS_CV & IS_VAR) && UNEXPECTED(Z_ISREF_P(op1))) { - /* Don't keep lock on reference, lock the value instead */ - if (UNEXPECTED(Z_REFCOUNT_P(op1) == 1)) { - ZVAL_UNREF(op1); - } else { - Z_DELREF_P(op1); - ZVAL_COPY(op1, Z_REFVAL_P(op1)); - } } if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); @@ -50628,7 +50556,7 @@ fetch_dim_r_index_array: offset = zval_get_long(dim); } ZEND_HASH_INDEX_FIND(Z_ARRVAL_P(container), offset, value, fetch_dim_r_index_undef); - ZVAL_COPY(EX_VAR(opline->result.var), value); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), value); if (IS_CV & (IS_TMP_VAR|IS_VAR)) { SAVE_OPLINE(); @@ -51887,10 +51815,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_ fetch_static_prop_return: ZEND_ASSERT(retval != NULL); if (type == BP_VAR_R || type == BP_VAR_IS) { - if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) { - ZVAL_UNREF(retval); - } - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); } else { ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); } @@ -51947,7 +51872,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_ fetch_dim_r_array: value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CONST, BP_VAR_R); result = EX_VAR(opline->result.var); - ZVAL_COPY(result, value); + ZVAL_COPY_UNREF(result, value); } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { container = Z_REFVAL_P(container); if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { @@ -52313,14 +52238,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_TMPVAR_CONST_HANDLER SAVE_OPLINE(); if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } else if (((IS_TMP_VAR|IS_VAR) & IS_VAR) && UNEXPECTED(Z_ISREF_P(op1))) { - /* Don't keep lock on reference, lock the value instead */ - if (UNEXPECTED(Z_REFCOUNT_P(op1) == 1)) { - ZVAL_UNREF(op1); - } else { - Z_DELREF_P(op1); - ZVAL_COPY(op1, Z_REFVAL_P(op1)); - } } if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); @@ -52720,7 +52637,7 @@ fetch_dim_r_index_array: offset = zval_get_long(dim); } ZEND_HASH_INDEX_FIND(Z_ARRVAL_P(container), offset, value, fetch_dim_r_index_undef); - ZVAL_COPY(EX_VAR(opline->result.var), value); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), value); if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { SAVE_OPLINE(); zval_ptr_dtor_nogc(free_op1); @@ -52846,10 +52763,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_ fetch_static_prop_return: ZEND_ASSERT(retval != NULL); if (type == BP_VAR_R || type == BP_VAR_IS) { - if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) { - ZVAL_UNREF(retval); - } - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); } else { ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); } @@ -53202,10 +53116,7 @@ fetch_this: ZEND_ASSERT(retval != NULL); if (type == BP_VAR_R || type == BP_VAR_IS) { - if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) { - ZVAL_UNREF(retval); - } - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); } else { ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); } @@ -53343,10 +53254,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_ fetch_static_prop_return: ZEND_ASSERT(retval != NULL); if (type == BP_VAR_R || type == BP_VAR_IS) { - if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) { - ZVAL_UNREF(retval); - } - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); } else { ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); } @@ -54310,7 +54218,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_HAN fetch_dim_r_array: value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CV, BP_VAR_R); result = EX_VAR(opline->result.var); - ZVAL_COPY(result, value); + ZVAL_COPY_UNREF(result, value); } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { container = Z_REFVAL_P(container); if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { @@ -54676,14 +54584,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_TMPVAR_CV_HANDLER(ZE SAVE_OPLINE(); if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } else if (((IS_TMP_VAR|IS_VAR) & IS_VAR) && UNEXPECTED(Z_ISREF_P(op1))) { - /* Don't keep lock on reference, lock the value instead */ - if (UNEXPECTED(Z_REFCOUNT_P(op1) == 1)) { - ZVAL_UNREF(op1); - } else { - Z_DELREF_P(op1); - ZVAL_COPY(op1, Z_REFVAL_P(op1)); - } } if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); @@ -54890,7 +54790,7 @@ fetch_dim_r_index_array: offset = zval_get_long(dim); } ZEND_HASH_INDEX_FIND(Z_ARRVAL_P(container), offset, value, fetch_dim_r_index_undef); - ZVAL_COPY(EX_VAR(opline->result.var), value); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), value); if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { SAVE_OPLINE(); zval_ptr_dtor_nogc(free_op1); @@ -55536,7 +55436,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR fetch_dim_r_array: value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, (IS_TMP_VAR|IS_VAR), BP_VAR_R); result = EX_VAR(opline->result.var); - ZVAL_COPY(result, value); + ZVAL_COPY_UNREF(result, value); } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { container = Z_REFVAL_P(container); if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { @@ -55904,14 +55804,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_TMPVAR_TMPVAR_HANDLE SAVE_OPLINE(); if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } else if (((IS_TMP_VAR|IS_VAR) & IS_VAR) && UNEXPECTED(Z_ISREF_P(op1))) { - /* Don't keep lock on reference, lock the value instead */ - if (UNEXPECTED(Z_REFCOUNT_P(op1) == 1)) { - ZVAL_UNREF(op1); - } else { - Z_DELREF_P(op1); - ZVAL_COPY(op1, Z_REFVAL_P(op1)); - } } if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); @@ -56119,7 +56011,7 @@ fetch_dim_r_index_array: offset = zval_get_long(dim); } ZEND_HASH_INDEX_FIND(Z_ARRVAL_P(container), offset, value, fetch_dim_r_index_undef); - ZVAL_COPY(EX_VAR(opline->result.var), value); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), value); if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { SAVE_OPLINE(); zval_ptr_dtor_nogc(free_op1);