diff options
| -rw-r--r-- | Zend/zend_execute.c | 34 | ||||
| -rw-r--r-- | Zend/zend_vm_def.h | 30 | ||||
| -rw-r--r-- | Zend/zend_vm_execute.h | 222 |
3 files changed, 164 insertions, 122 deletions
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 5ae02f7d79..54a7b0166a 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -766,19 +766,19 @@ static zend_always_inline void zend_assign_to_object(zval *retval, zval *object, if (object_op_type != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { do { - if (Z_ISREF_P(object)) { - object = Z_REFVAL_P(object); - if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { - break; - } - } - if (UNEXPECTED(object == &EG(error_zval))) { + if (object_op_type == IS_VAR && UNEXPECTED(object == &EG(error_zval))) { if (retval) { ZVAL_NULL(retval); } FREE_OP(free_value); return; } + if (Z_ISREF_P(object)) { + object = Z_REFVAL_P(object); + if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + break; + } + } if (EXPECTED(Z_TYPE_P(object) <= IS_FALSE || (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) { zend_object *obj; @@ -1189,6 +1189,7 @@ static zend_always_inline void zend_fetch_dimension_address(zval *result, zval * { zval *retval; +try_again: if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { SEPARATE_ARRAY(container); fetch_from_array: @@ -1259,6 +1260,9 @@ convert_to_array: /* for read-mode only */ ZVAL_NULL(result); } + } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + goto try_again; } else { if (type == BP_VAR_UNSET) { zend_error(E_WARNING, "Cannot unset offset in a non-array variable"); @@ -1383,14 +1387,20 @@ ZEND_API void zend_fetch_dimension_by_zval(zval *result, zval *container, zval * static zend_always_inline void zend_fetch_property_address(zval *result, zval *container, uint32_t container_op_type, zval *prop_ptr, uint32_t prop_op_type, void **cache_slot, int type TSRMLS_DC) { - if (container_op_type != IS_UNUSED) { - ZVAL_DEREF(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - if (UNEXPECTED(container == &EG(error_zval))) { + if (container_op_type != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { + do { + if (container_op_type != IS_VAR && UNEXPECTED(container == &EG(error_zval))) { ZVAL_INDIRECT(result, &EG(error_zval)); return; } + if (Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + break; + } + } + /* this should modify object only if it's empty */ if (type != BP_VAR_UNSET && EXPECTED(Z_TYPE_P(container) <= IS_FALSE || @@ -1402,7 +1412,7 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c ZVAL_INDIRECT(result, &EG(error_zval)); return; } - } + } while (0); } if (prop_op_type == IS_CONST && EXPECTED(Z_OBJCE_P(container) == CACHED_PTR_EX(cache_slot))) { diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 3dca5680f1..8e0cdab956 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -1283,12 +1283,11 @@ ZEND_VM_HANDLER(84, ZEND_FETCH_DIM_W, VAR|CV, CONST|TMPVAR|UNUSED|CV) zval *container; SAVE_OPLINE(); - container = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W); + container = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W); if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE TSRMLS_CC); FREE_OP2(); if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) { @@ -1311,7 +1310,6 @@ ZEND_VM_HANDLER(87, ZEND_FETCH_DIM_RW, VAR|CV, CONST|TMPVAR|UNUSED|CV) if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - ZVAL_DEREF(container); zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE TSRMLS_CC); FREE_OP2(); if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) { @@ -1349,11 +1347,10 @@ ZEND_VM_HANDLER(93, ZEND_FETCH_DIM_FUNC_ARG, CONST|TMP|VAR|CV, CONST|TMPVAR|UNUS if (OP1_TYPE == IS_CONST || OP1_TYPE == IS_TMP_VAR) { zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); } - container = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W); + container = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W); if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE TSRMLS_CC); if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -1385,7 +1382,6 @@ ZEND_VM_HANDLER(96, ZEND_FETCH_DIM_UNSET, VAR|CV, CONST|TMPVAR|CV) if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - ZVAL_DEREF(container); zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE TSRMLS_CC); FREE_OP2(); if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) { @@ -1471,7 +1467,7 @@ ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|CV, CONST|TMPVAR|CV) SAVE_OPLINE(); property = GET_OP2_ZVAL_PTR(BP_VAR_R); - container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_W); + container = GET_OP1_OBJ_ZVAL_PTR_PTR_UNDEF(BP_VAR_W); if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } @@ -1586,7 +1582,7 @@ ZEND_VM_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ARG, CONST|TMP|VAR|UNUSED|CV, CONST|TMPV SAVE_OPLINE(); property = GET_OP2_ZVAL_PTR(BP_VAR_R); - container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_W); + container = GET_OP1_OBJ_ZVAL_PTR_PTR_UNDEF(BP_VAR_W); if (OP1_TYPE == IS_CONST || OP1_TYPE == IS_TMP_VAR) { zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); @@ -4587,16 +4583,24 @@ ZEND_VM_HANDLER(76, ZEND_UNSET_OBJ, VAR|UNUSED|CV, CONST|TMPVAR|CV) } offset = GET_OP2_ZVAL_PTR(BP_VAR_R); - if (OP1_TYPE != IS_UNUSED) { - ZVAL_DEREF(container); - } - if (OP1_TYPE == IS_UNUSED || Z_TYPE_P(container) == IS_OBJECT) { + do { + if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { + if (Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (Z_TYPE_P(container) != IS_OBJECT) { + break; + } + } else { + break; + } + } if (Z_OBJ_HT_P(container)->unset_property) { Z_OBJ_HT_P(container)->unset_property(container, offset, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC); } else { zend_error(E_NOTICE, "Trying to unset property of non-object"); } - } + } while (0); + FREE_OP2(); FREE_OP1_VAR_PTR(); CHECK_EXCEPTION(); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 72735a2bca..b6034caf25 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -3863,7 +3863,6 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CONST_HANDLER(ZEND_ if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC); if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -5752,7 +5751,6 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_UNUSED_HANDLER(ZEND if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC); if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -6638,7 +6636,6 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CV_HANDLER(ZEND_OPC if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC); if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -7772,7 +7769,6 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR_HANDLER(ZEND if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2), (IS_TMP_VAR|IS_VAR) TSRMLS_CC); if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -9102,7 +9098,6 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CONST_HANDLER(ZEND_OP if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC); if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -9847,7 +9842,6 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_UNUSED_HANDLER(ZEND_O if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC); if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -10164,7 +10158,6 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CV_HANDLER(ZEND_OPCOD if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC); if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -10587,7 +10580,6 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR_HANDLER(ZEND_O if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2), (IS_TMP_VAR|IS_VAR) TSRMLS_CC); if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -12724,7 +12716,6 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { @@ -12747,7 +12738,6 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - ZVAL_DEREF(container); zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { @@ -12774,7 +12764,6 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OP if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -12806,7 +12795,6 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCOD if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - ZVAL_DEREF(container); zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { @@ -13550,16 +13538,23 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND } offset = opline->op2.zv; - if (IS_VAR != IS_UNUSED) { - ZVAL_DEREF(container); - } - if (IS_VAR == IS_UNUSED || Z_TYPE_P(container) == IS_OBJECT) { + do { + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { + if (Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (Z_TYPE_P(container) != IS_OBJECT) { + break; + } + } else { + break; + } + } if (Z_OBJ_HT_P(container)->unset_property) { Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC); } else { zend_error(E_NOTICE, "Trying to unset property of non-object"); } - } + } while (0); if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); @@ -14449,7 +14444,6 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_H if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { @@ -14472,7 +14466,6 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - ZVAL_DEREF(container); zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { @@ -14499,7 +14492,6 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED_HANDLER(ZEND_O if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -15604,7 +15596,6 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { @@ -15627,7 +15618,6 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - ZVAL_DEREF(container); zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { @@ -15654,7 +15644,6 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCOD if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -15686,7 +15675,6 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_H if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - ZVAL_DEREF(container); zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { @@ -16396,16 +16384,23 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER } offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - if (IS_VAR != IS_UNUSED) { - ZVAL_DEREF(container); - } - if (IS_VAR == IS_UNUSED || Z_TYPE_P(container) == IS_OBJECT) { + do { + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { + if (Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (Z_TYPE_P(container) != IS_OBJECT) { + break; + } + } else { + break; + } + } if (Z_OBJ_HT_P(container)->unset_property) { Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC); } else { zend_error(E_NOTICE, "Trying to unset property of non-object"); } - } + } while (0); if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); @@ -17146,7 +17141,6 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_H if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2), (IS_TMP_VAR|IS_VAR) TSRMLS_CC); zval_ptr_dtor_nogc(free_op2); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { @@ -17169,7 +17163,6 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - ZVAL_DEREF(container); zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2), (IS_TMP_VAR|IS_VAR) TSRMLS_CC); zval_ptr_dtor_nogc(free_op2); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { @@ -17196,7 +17189,6 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR_HANDLER(ZEND_O if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2), (IS_TMP_VAR|IS_VAR) TSRMLS_CC); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -17228,7 +17220,6 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCO if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - ZVAL_DEREF(container); zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2), (IS_TMP_VAR|IS_VAR) TSRMLS_CC); zval_ptr_dtor_nogc(free_op2); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { @@ -17843,16 +17834,24 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HAN } offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); - if (IS_VAR != IS_UNUSED) { - ZVAL_DEREF(container); - } - if (IS_VAR == IS_UNUSED || Z_TYPE_P(container) == IS_OBJECT) { + do { + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { + if (Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (Z_TYPE_P(container) != IS_OBJECT) { + break; + } + } else { + break; + } + } if (Z_OBJ_HT_P(container)->unset_property) { Z_OBJ_HT_P(container)->unset_property(container, offset, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC); } else { zend_error(E_NOTICE, "Trying to unset property of non-object"); } - } + } while (0); + zval_ptr_dtor_nogc(free_op2); if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); @@ -19141,16 +19140,23 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_H } offset = opline->op2.zv; - if (IS_UNUSED != IS_UNUSED) { - ZVAL_DEREF(container); - } - if (IS_UNUSED == IS_UNUSED || Z_TYPE_P(container) == IS_OBJECT) { + do { + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { + if (Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (Z_TYPE_P(container) != IS_OBJECT) { + break; + } + } else { + break; + } + } if (Z_OBJ_HT_P(container)->unset_property) { Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC); } else { zend_error(E_NOTICE, "Trying to unset property of non-object"); } - } + } while (0); CHECK_EXCEPTION(); @@ -21230,16 +21236,23 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HAND } offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - if (IS_UNUSED != IS_UNUSED) { - ZVAL_DEREF(container); - } - if (IS_UNUSED == IS_UNUSED || Z_TYPE_P(container) == IS_OBJECT) { + do { + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { + if (Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (Z_TYPE_P(container) != IS_OBJECT) { + break; + } + } else { + break; + } + } if (Z_OBJ_HT_P(container)->unset_property) { Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC); } else { zend_error(E_NOTICE, "Trying to unset property of non-object"); } - } + } while (0); CHECK_EXCEPTION(); @@ -22625,16 +22638,24 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_ } offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); - if (IS_UNUSED != IS_UNUSED) { - ZVAL_DEREF(container); - } - if (IS_UNUSED == IS_UNUSED || Z_TYPE_P(container) == IS_OBJECT) { + do { + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { + if (Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (Z_TYPE_P(container) != IS_OBJECT) { + break; + } + } else { + break; + } + } if (Z_OBJ_HT_P(container)->unset_property) { Z_OBJ_HT_P(container)->unset_property(container, offset, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC); } else { zend_error(E_NOTICE, "Trying to unset property of non-object"); } - } + } while (0); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); @@ -25262,12 +25283,11 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); + container = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { @@ -25290,7 +25310,6 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HA if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - ZVAL_DEREF(container); zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { @@ -25328,11 +25347,10 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPC if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR) { zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); } - container = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); + container = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -25364,7 +25382,6 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - ZVAL_DEREF(container); zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { @@ -25449,7 +25466,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN SAVE_OPLINE(); property = opline->op2.zv; - container = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); + container = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } @@ -25563,7 +25580,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPC SAVE_OPLINE(); property = opline->op2.zv; - container = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); + container = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR) { zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); @@ -26191,16 +26208,23 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDL } offset = opline->op2.zv; - if (IS_CV != IS_UNUSED) { - ZVAL_DEREF(container); - } - if (IS_CV == IS_UNUSED || Z_TYPE_P(container) == IS_OBJECT) { + do { + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { + if (Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (Z_TYPE_P(container) != IS_OBJECT) { + break; + } + } else { + break; + } + } if (Z_OBJ_HT_P(container)->unset_property) { Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC); } else { zend_error(E_NOTICE, "Trying to unset property of non-object"); } - } + } while (0); CHECK_EXCEPTION(); @@ -27907,12 +27931,11 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HA zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); + container = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { @@ -27935,7 +27958,6 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_H if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - ZVAL_DEREF(container); zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { @@ -27958,11 +27980,10 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED_HANDLER(ZEND_OP if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR) { zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); } - container = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); + container = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -29323,12 +29344,11 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLE zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); + container = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { @@ -29351,7 +29371,6 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDL if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - ZVAL_DEREF(container); zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { @@ -29389,11 +29408,10 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR) { zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); } - container = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); + container = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -29425,7 +29443,6 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HA if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - ZVAL_DEREF(container); zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { @@ -29510,7 +29527,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLE SAVE_OPLINE(); property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - container = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); + container = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } @@ -29624,7 +29641,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE SAVE_OPLINE(); property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - container = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); + container = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR) { zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); @@ -30203,16 +30220,23 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ } offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - if (IS_CV != IS_UNUSED) { - ZVAL_DEREF(container); - } - if (IS_CV == IS_UNUSED || Z_TYPE_P(container) == IS_OBJECT) { + do { + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { + if (Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (Z_TYPE_P(container) != IS_OBJECT) { + break; + } + } else { + break; + } + } if (Z_OBJ_HT_P(container)->unset_property) { Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC); } else { zend_error(E_NOTICE, "Trying to unset property of non-object"); } - } + } while (0); CHECK_EXCEPTION(); @@ -31376,12 +31400,11 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HA zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); + container = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2), (IS_TMP_VAR|IS_VAR) TSRMLS_CC); zval_ptr_dtor_nogc(free_op2); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { @@ -31404,7 +31427,6 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_H if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - ZVAL_DEREF(container); zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2), (IS_TMP_VAR|IS_VAR) TSRMLS_CC); zval_ptr_dtor_nogc(free_op2); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { @@ -31442,11 +31464,10 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR_HANDLER(ZEND_OP if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR) { zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); } - container = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); + container = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2), (IS_TMP_VAR|IS_VAR) TSRMLS_CC); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -31478,7 +31499,6 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCOD if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - ZVAL_DEREF(container); zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2), (IS_TMP_VAR|IS_VAR) TSRMLS_CC); zval_ptr_dtor_nogc(free_op2); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { @@ -31564,7 +31584,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HA SAVE_OPLINE(); property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); - container = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); + container = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } @@ -31679,7 +31699,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR_HANDLER(ZEND_OP SAVE_OPLINE(); property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); - container = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); + container = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR) { zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); @@ -32165,16 +32185,24 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HAND } offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); - if (IS_CV != IS_UNUSED) { - ZVAL_DEREF(container); - } - if (IS_CV == IS_UNUSED || Z_TYPE_P(container) == IS_OBJECT) { + do { + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { + if (Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (Z_TYPE_P(container) != IS_OBJECT) { + break; + } + } else { + break; + } + } if (Z_OBJ_HT_P(container)->unset_property) { Z_OBJ_HT_P(container)->unset_property(container, offset, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC); } else { zend_error(E_NOTICE, "Trying to unset property of non-object"); } - } + } while (0); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); |
