diff options
author | Dmitry Stogov <dmitry@zend.com> | 2014-09-22 14:41:44 +0400 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2014-09-22 14:41:44 +0400 |
commit | a057f060e864ff26753a25cf578b0f26999f4532 (patch) | |
tree | e35c66098385aa3aeeabc76d4cbe4cbd72312bbf /Zend | |
parent | 9c0fa4106c1dcd9ad9bea26285e919ba0e36fb0f (diff) | |
download | php-git-a057f060e864ff26753a25cf578b0f26999f4532.tar.gz |
Optimized unset()
Diffstat (limited to 'Zend')
-rw-r--r-- | Zend/zend_vm_def.h | 46 | ||||
-rw-r--r-- | Zend/zend_vm_execute.h | 552 |
2 files changed, 247 insertions, 351 deletions
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 4931972c5c..873c9f478d 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -4251,29 +4251,37 @@ ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMP|VAR|CV, UNUSED|CONST|VAR) zval tmp, *varname; HashTable *target_symbol_table; zend_free_op free_op1; - zend_bool tmp_is_dup = 0; SAVE_OPLINE(); if (OP1_TYPE == IS_CV && OP2_TYPE == IS_UNUSED && (opline->extended_value & ZEND_QUICK_SET)) { - ZVAL_COPY_VALUE(&tmp, EX_VAR(opline->op1.var)); - ZVAL_UNDEF(EX_VAR(opline->op1.var)); - zval_ptr_dtor(&tmp); + zval *var = EX_VAR(opline->op1.var); + + if (Z_REFCOUNTED_P(var)) { + zend_refcounted *garbage = Z_COUNTED_P(var); + + if (!--GC_REFCOUNT(garbage)) { + ZVAL_UNDEF(var); + _zval_dtor_func_for_ptr(garbage ZEND_FILE_LINE_CC); + } else { + GC_ZVAL_CHECK_POSSIBLE_ROOT(var); + ZVAL_UNDEF(var); + } + } else { + ZVAL_UNDEF(var); + } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } varname = GET_OP1_ZVAL_PTR(BP_VAR_R); + ZVAL_UNDEF(&tmp); if (OP1_TYPE != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { ZVAL_DUP(&tmp, varname); convert_to_string(&tmp); varname = &tmp; - tmp_is_dup = 1; - } else if (OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) { - ZVAL_COPY(&tmp, varname); - varname = &tmp; } if (OP2_TYPE != IS_UNUSED) { @@ -4285,10 +4293,8 @@ ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMP|VAR|CV, UNUSED|CONST|VAR) } else { ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, 0 TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { - if (OP1_TYPE != IS_CONST && tmp_is_dup) { + if (OP1_TYPE != IS_CONST) { zval_dtor(&tmp); - } else if (OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) { - zval_ptr_dtor(&tmp); } FREE_OP1(); HANDLE_EXCEPTION(); @@ -4307,10 +4313,8 @@ ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMP|VAR|CV, UNUSED|CONST|VAR) zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); } - if (OP1_TYPE != IS_CONST && tmp_is_dup) { + if (OP1_TYPE != IS_CONST) { zval_dtor(&tmp); - } else if (OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) { - zval_ptr_dtor(&tmp); } FREE_OP1(); CHECK_EXCEPTION(); @@ -4351,12 +4355,9 @@ ZEND_VM_C_LABEL(num_index_dim): zend_hash_index_del(ht, hval); break; case IS_STRING: - if (OP2_TYPE == IS_CV || OP2_TYPE == IS_VAR) { - if (Z_REFCOUNTED_P(offset)) Z_ADDREF_P(offset); - } if (OP2_TYPE != IS_CONST) { if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) { - ZEND_VM_C_GOTO(numeric_index_dim); + ZEND_VM_C_GOTO(num_index_dim); } } if (ht == &EG(symbol_table).ht) { @@ -4364,15 +4365,6 @@ ZEND_VM_C_LABEL(num_index_dim): } else { zend_hash_del(ht, Z_STR_P(offset)); } - if (OP2_TYPE == IS_CV || OP2_TYPE == IS_VAR) { - zval_ptr_dtor(offset); - } - break; -ZEND_VM_C_LABEL(numeric_index_dim): - zend_hash_index_del(ht, hval); - if (OP2_TYPE == IS_CV || OP2_TYPE == IS_VAR) { - zval_ptr_dtor(offset); - } break; case IS_NULL: zend_hash_del(ht, STR_EMPTY_ALLOC()); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 7b6cc11d83..a2b547544d 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -4440,29 +4440,37 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HA zval tmp, *varname; HashTable *target_symbol_table; - zend_bool tmp_is_dup = 0; SAVE_OPLINE(); if (IS_CONST == IS_CV && IS_CONST == IS_UNUSED && (opline->extended_value & ZEND_QUICK_SET)) { - ZVAL_COPY_VALUE(&tmp, EX_VAR(opline->op1.var)); - ZVAL_UNDEF(EX_VAR(opline->op1.var)); - zval_ptr_dtor(&tmp); + zval *var = EX_VAR(opline->op1.var); + + if (Z_REFCOUNTED_P(var)) { + zend_refcounted *garbage = Z_COUNTED_P(var); + + if (!--GC_REFCOUNT(garbage)) { + ZVAL_UNDEF(var); + _zval_dtor_func_for_ptr(garbage ZEND_FILE_LINE_CC); + } else { + GC_ZVAL_CHECK_POSSIBLE_ROOT(var); + ZVAL_UNDEF(var); + } + } else { + ZVAL_UNDEF(var); + } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } varname = opline->op1.zv; + ZVAL_UNDEF(&tmp); if (IS_CONST != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { ZVAL_DUP(&tmp, varname); convert_to_string(&tmp); varname = &tmp; - tmp_is_dup = 1; - } else if (IS_CONST == IS_VAR || IS_CONST == IS_CV) { - ZVAL_COPY(&tmp, varname); - varname = &tmp; } if (IS_CONST != IS_UNUSED) { @@ -4474,10 +4482,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HA } else { ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, 0 TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { - if (IS_CONST != IS_CONST && tmp_is_dup) { + if (IS_CONST != IS_CONST) { zval_dtor(&tmp); - } else if (IS_CONST == IS_VAR || IS_CONST == IS_CV) { - zval_ptr_dtor(&tmp); } HANDLE_EXCEPTION(); @@ -4496,10 +4502,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HA zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); } - if (IS_CONST != IS_CONST && tmp_is_dup) { + if (IS_CONST != IS_CONST) { zval_dtor(&tmp); - } else if (IS_CONST == IS_VAR || IS_CONST == IS_CV) { - zval_ptr_dtor(&tmp); } CHECK_EXCEPTION(); @@ -6834,29 +6838,37 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HAND zval tmp, *varname; HashTable *target_symbol_table; - zend_bool tmp_is_dup = 0; SAVE_OPLINE(); if (IS_CONST == IS_CV && IS_VAR == IS_UNUSED && (opline->extended_value & ZEND_QUICK_SET)) { - ZVAL_COPY_VALUE(&tmp, EX_VAR(opline->op1.var)); - ZVAL_UNDEF(EX_VAR(opline->op1.var)); - zval_ptr_dtor(&tmp); + zval *var = EX_VAR(opline->op1.var); + + if (Z_REFCOUNTED_P(var)) { + zend_refcounted *garbage = Z_COUNTED_P(var); + + if (!--GC_REFCOUNT(garbage)) { + ZVAL_UNDEF(var); + _zval_dtor_func_for_ptr(garbage ZEND_FILE_LINE_CC); + } else { + GC_ZVAL_CHECK_POSSIBLE_ROOT(var); + ZVAL_UNDEF(var); + } + } else { + ZVAL_UNDEF(var); + } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } varname = opline->op1.zv; + ZVAL_UNDEF(&tmp); if (IS_CONST != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { ZVAL_DUP(&tmp, varname); convert_to_string(&tmp); varname = &tmp; - tmp_is_dup = 1; - } else if (IS_CONST == IS_VAR || IS_CONST == IS_CV) { - ZVAL_COPY(&tmp, varname); - varname = &tmp; } if (IS_VAR != IS_UNUSED) { @@ -6868,10 +6880,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HAND } else { ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, 0 TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { - if (IS_CONST != IS_CONST && tmp_is_dup) { + if (IS_CONST != IS_CONST) { zval_dtor(&tmp); - } else if (IS_CONST == IS_VAR || IS_CONST == IS_CV) { - zval_ptr_dtor(&tmp); } HANDLE_EXCEPTION(); @@ -6890,10 +6900,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HAND zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); } - if (IS_CONST != IS_CONST && tmp_is_dup) { + if (IS_CONST != IS_CONST) { zval_dtor(&tmp); - } else if (IS_CONST == IS_VAR || IS_CONST == IS_CV) { - zval_ptr_dtor(&tmp); } CHECK_EXCEPTION(); @@ -7699,29 +7707,37 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_H zval tmp, *varname; HashTable *target_symbol_table; - zend_bool tmp_is_dup = 0; SAVE_OPLINE(); if (IS_CONST == IS_CV && IS_UNUSED == IS_UNUSED && (opline->extended_value & ZEND_QUICK_SET)) { - ZVAL_COPY_VALUE(&tmp, EX_VAR(opline->op1.var)); - ZVAL_UNDEF(EX_VAR(opline->op1.var)); - zval_ptr_dtor(&tmp); + zval *var = EX_VAR(opline->op1.var); + + if (Z_REFCOUNTED_P(var)) { + zend_refcounted *garbage = Z_COUNTED_P(var); + + if (!--GC_REFCOUNT(garbage)) { + ZVAL_UNDEF(var); + _zval_dtor_func_for_ptr(garbage ZEND_FILE_LINE_CC); + } else { + GC_ZVAL_CHECK_POSSIBLE_ROOT(var); + ZVAL_UNDEF(var); + } + } else { + ZVAL_UNDEF(var); + } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } varname = opline->op1.zv; + ZVAL_UNDEF(&tmp); if (IS_CONST != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { ZVAL_DUP(&tmp, varname); convert_to_string(&tmp); varname = &tmp; - tmp_is_dup = 1; - } else if (IS_CONST == IS_VAR || IS_CONST == IS_CV) { - ZVAL_COPY(&tmp, varname); - varname = &tmp; } if (IS_UNUSED != IS_UNUSED) { @@ -7733,10 +7749,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_H } else { ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, 0 TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { - if (IS_CONST != IS_CONST && tmp_is_dup) { + if (IS_CONST != IS_CONST) { zval_dtor(&tmp); - } else if (IS_CONST == IS_VAR || IS_CONST == IS_CV) { - zval_ptr_dtor(&tmp); } HANDLE_EXCEPTION(); @@ -7755,10 +7769,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_H zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); } - if (IS_CONST != IS_CONST && tmp_is_dup) { + if (IS_CONST != IS_CONST) { zval_dtor(&tmp); - } else if (IS_CONST == IS_VAR || IS_CONST == IS_CV) { - zval_ptr_dtor(&tmp); } CHECK_EXCEPTION(); @@ -11028,29 +11040,37 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HAND zval tmp, *varname; HashTable *target_symbol_table; zend_free_op free_op1; - zend_bool tmp_is_dup = 0; SAVE_OPLINE(); if (IS_TMP_VAR == IS_CV && IS_CONST == IS_UNUSED && (opline->extended_value & ZEND_QUICK_SET)) { - ZVAL_COPY_VALUE(&tmp, EX_VAR(opline->op1.var)); - ZVAL_UNDEF(EX_VAR(opline->op1.var)); - zval_ptr_dtor(&tmp); + zval *var = EX_VAR(opline->op1.var); + + if (Z_REFCOUNTED_P(var)) { + zend_refcounted *garbage = Z_COUNTED_P(var); + + if (!--GC_REFCOUNT(garbage)) { + ZVAL_UNDEF(var); + _zval_dtor_func_for_ptr(garbage ZEND_FILE_LINE_CC); + } else { + GC_ZVAL_CHECK_POSSIBLE_ROOT(var); + ZVAL_UNDEF(var); + } + } else { + ZVAL_UNDEF(var); + } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } varname = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + ZVAL_UNDEF(&tmp); if (IS_TMP_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { ZVAL_DUP(&tmp, varname); convert_to_string(&tmp); varname = &tmp; - tmp_is_dup = 1; - } else if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) { - ZVAL_COPY(&tmp, varname); - varname = &tmp; } if (IS_CONST != IS_UNUSED) { @@ -11062,10 +11082,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HAND } else { ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, 0 TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { - if (IS_TMP_VAR != IS_CONST && tmp_is_dup) { + if (IS_TMP_VAR != IS_CONST) { zval_dtor(&tmp); - } else if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) { - zval_ptr_dtor(&tmp); } zval_dtor(free_op1.var); HANDLE_EXCEPTION(); @@ -11084,10 +11102,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HAND zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); } - if (IS_TMP_VAR != IS_CONST && tmp_is_dup) { + if (IS_TMP_VAR != IS_CONST) { zval_dtor(&tmp); - } else if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) { - zval_ptr_dtor(&tmp); } zval_dtor(free_op1.var); CHECK_EXCEPTION(); @@ -13303,29 +13319,37 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLE zval tmp, *varname; HashTable *target_symbol_table; zend_free_op free_op1; - zend_bool tmp_is_dup = 0; SAVE_OPLINE(); if (IS_TMP_VAR == IS_CV && IS_VAR == IS_UNUSED && (opline->extended_value & ZEND_QUICK_SET)) { - ZVAL_COPY_VALUE(&tmp, EX_VAR(opline->op1.var)); - ZVAL_UNDEF(EX_VAR(opline->op1.var)); - zval_ptr_dtor(&tmp); + zval *var = EX_VAR(opline->op1.var); + + if (Z_REFCOUNTED_P(var)) { + zend_refcounted *garbage = Z_COUNTED_P(var); + + if (!--GC_REFCOUNT(garbage)) { + ZVAL_UNDEF(var); + _zval_dtor_func_for_ptr(garbage ZEND_FILE_LINE_CC); + } else { + GC_ZVAL_CHECK_POSSIBLE_ROOT(var); + ZVAL_UNDEF(var); + } + } else { + ZVAL_UNDEF(var); + } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } varname = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + ZVAL_UNDEF(&tmp); if (IS_TMP_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { ZVAL_DUP(&tmp, varname); convert_to_string(&tmp); varname = &tmp; - tmp_is_dup = 1; - } else if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) { - ZVAL_COPY(&tmp, varname); - varname = &tmp; } if (IS_VAR != IS_UNUSED) { @@ -13337,10 +13361,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLE } else { ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, 0 TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { - if (IS_TMP_VAR != IS_CONST && tmp_is_dup) { + if (IS_TMP_VAR != IS_CONST) { zval_dtor(&tmp); - } else if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) { - zval_ptr_dtor(&tmp); } zval_dtor(free_op1.var); HANDLE_EXCEPTION(); @@ -13359,10 +13381,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLE zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); } - if (IS_TMP_VAR != IS_CONST && tmp_is_dup) { + if (IS_TMP_VAR != IS_CONST) { zval_dtor(&tmp); - } else if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) { - zval_ptr_dtor(&tmp); } zval_dtor(free_op1.var); CHECK_EXCEPTION(); @@ -14052,29 +14072,37 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HAN zval tmp, *varname; HashTable *target_symbol_table; zend_free_op free_op1; - zend_bool tmp_is_dup = 0; SAVE_OPLINE(); if (IS_TMP_VAR == IS_CV && IS_UNUSED == IS_UNUSED && (opline->extended_value & ZEND_QUICK_SET)) { - ZVAL_COPY_VALUE(&tmp, EX_VAR(opline->op1.var)); - ZVAL_UNDEF(EX_VAR(opline->op1.var)); - zval_ptr_dtor(&tmp); + zval *var = EX_VAR(opline->op1.var); + + if (Z_REFCOUNTED_P(var)) { + zend_refcounted *garbage = Z_COUNTED_P(var); + + if (!--GC_REFCOUNT(garbage)) { + ZVAL_UNDEF(var); + _zval_dtor_func_for_ptr(garbage ZEND_FILE_LINE_CC); + } else { + GC_ZVAL_CHECK_POSSIBLE_ROOT(var); + ZVAL_UNDEF(var); + } + } else { + ZVAL_UNDEF(var); + } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } varname = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + ZVAL_UNDEF(&tmp); if (IS_TMP_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { ZVAL_DUP(&tmp, varname); convert_to_string(&tmp); varname = &tmp; - tmp_is_dup = 1; - } else if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) { - ZVAL_COPY(&tmp, varname); - varname = &tmp; } if (IS_UNUSED != IS_UNUSED) { @@ -14086,10 +14114,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HAN } else { ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, 0 TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { - if (IS_TMP_VAR != IS_CONST && tmp_is_dup) { + if (IS_TMP_VAR != IS_CONST) { zval_dtor(&tmp); - } else if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) { - zval_ptr_dtor(&tmp); } zval_dtor(free_op1.var); HANDLE_EXCEPTION(); @@ -14108,10 +14134,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HAN zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); } - if (IS_TMP_VAR != IS_CONST && tmp_is_dup) { + if (IS_TMP_VAR != IS_CONST) { zval_dtor(&tmp); - } else if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) { - zval_ptr_dtor(&tmp); } zval_dtor(free_op1.var); CHECK_EXCEPTION(); @@ -18822,29 +18846,37 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND zval tmp, *varname; HashTable *target_symbol_table; zend_free_op free_op1; - zend_bool tmp_is_dup = 0; SAVE_OPLINE(); if (IS_VAR == IS_CV && IS_CONST == IS_UNUSED && (opline->extended_value & ZEND_QUICK_SET)) { - ZVAL_COPY_VALUE(&tmp, EX_VAR(opline->op1.var)); - ZVAL_UNDEF(EX_VAR(opline->op1.var)); - zval_ptr_dtor(&tmp); + zval *var = EX_VAR(opline->op1.var); + + if (Z_REFCOUNTED_P(var)) { + zend_refcounted *garbage = Z_COUNTED_P(var); + + if (!--GC_REFCOUNT(garbage)) { + ZVAL_UNDEF(var); + _zval_dtor_func_for_ptr(garbage ZEND_FILE_LINE_CC); + } else { + GC_ZVAL_CHECK_POSSIBLE_ROOT(var); + ZVAL_UNDEF(var); + } + } else { + ZVAL_UNDEF(var); + } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + ZVAL_UNDEF(&tmp); if (IS_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { ZVAL_DUP(&tmp, varname); convert_to_string(&tmp); varname = &tmp; - tmp_is_dup = 1; - } else if (IS_VAR == IS_VAR || IS_VAR == IS_CV) { - ZVAL_COPY(&tmp, varname); - varname = &tmp; } if (IS_CONST != IS_UNUSED) { @@ -18856,10 +18888,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND } else { ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, 0 TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { - if (IS_VAR != IS_CONST && tmp_is_dup) { + if (IS_VAR != IS_CONST) { zval_dtor(&tmp); - } else if (IS_VAR == IS_VAR || IS_VAR == IS_CV) { - zval_ptr_dtor(&tmp); } zval_ptr_dtor_nogc(free_op1.var); HANDLE_EXCEPTION(); @@ -18878,10 +18908,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); } - if (IS_VAR != IS_CONST && tmp_is_dup) { + if (IS_VAR != IS_CONST) { zval_dtor(&tmp); - } else if (IS_VAR == IS_VAR || IS_VAR == IS_CV) { - zval_ptr_dtor(&tmp); } zval_ptr_dtor_nogc(free_op1.var); CHECK_EXCEPTION(); @@ -18922,12 +18950,9 @@ num_index_dim: zend_hash_index_del(ht, hval); break; case IS_STRING: - if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { - if (Z_REFCOUNTED_P(offset)) Z_ADDREF_P(offset); - } if (IS_CONST != IS_CONST) { if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) { - goto numeric_index_dim; + goto num_index_dim; } } if (ht == &EG(symbol_table).ht) { @@ -18935,15 +18960,6 @@ num_index_dim: } else { zend_hash_del(ht, Z_STR_P(offset)); } - if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { - zval_ptr_dtor(offset); - } - break; -numeric_index_dim: - zend_hash_index_del(ht, hval); - if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { - zval_ptr_dtor(offset); - } break; case IS_NULL: zend_hash_del(ht, STR_EMPTY_ALLOC()); @@ -20984,12 +21000,9 @@ num_index_dim: zend_hash_index_del(ht, hval); break; case IS_STRING: - if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { - if (Z_REFCOUNTED_P(offset)) Z_ADDREF_P(offset); - } if (IS_TMP_VAR != IS_CONST) { if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) { - goto numeric_index_dim; + goto num_index_dim; } } if (ht == &EG(symbol_table).ht) { @@ -20997,15 +21010,6 @@ num_index_dim: } else { zend_hash_del(ht, Z_STR_P(offset)); } - if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { - zval_ptr_dtor(offset); - } - break; -numeric_index_dim: - zend_hash_index_del(ht, hval); - if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { - zval_ptr_dtor(offset); - } break; case IS_NULL: zend_hash_del(ht, STR_EMPTY_ALLOC()); @@ -23155,29 +23159,37 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLE zval tmp, *varname; HashTable *target_symbol_table; zend_free_op free_op1; - zend_bool tmp_is_dup = 0; SAVE_OPLINE(); if (IS_VAR == IS_CV && IS_VAR == IS_UNUSED && (opline->extended_value & ZEND_QUICK_SET)) { - ZVAL_COPY_VALUE(&tmp, EX_VAR(opline->op1.var)); - ZVAL_UNDEF(EX_VAR(opline->op1.var)); - zval_ptr_dtor(&tmp); + zval *var = EX_VAR(opline->op1.var); + + if (Z_REFCOUNTED_P(var)) { + zend_refcounted *garbage = Z_COUNTED_P(var); + + if (!--GC_REFCOUNT(garbage)) { + ZVAL_UNDEF(var); + _zval_dtor_func_for_ptr(garbage ZEND_FILE_LINE_CC); + } else { + GC_ZVAL_CHECK_POSSIBLE_ROOT(var); + ZVAL_UNDEF(var); + } + } else { + ZVAL_UNDEF(var); + } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + ZVAL_UNDEF(&tmp); if (IS_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { ZVAL_DUP(&tmp, varname); convert_to_string(&tmp); varname = &tmp; - tmp_is_dup = 1; - } else if (IS_VAR == IS_VAR || IS_VAR == IS_CV) { - ZVAL_COPY(&tmp, varname); - varname = &tmp; } if (IS_VAR != IS_UNUSED) { @@ -23189,10 +23201,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLE } else { ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, 0 TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { - if (IS_VAR != IS_CONST && tmp_is_dup) { + if (IS_VAR != IS_CONST) { zval_dtor(&tmp); - } else if (IS_VAR == IS_VAR || IS_VAR == IS_CV) { - zval_ptr_dtor(&tmp); } zval_ptr_dtor_nogc(free_op1.var); HANDLE_EXCEPTION(); @@ -23211,10 +23221,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLE zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); } - if (IS_VAR != IS_CONST && tmp_is_dup) { + if (IS_VAR != IS_CONST) { zval_dtor(&tmp); - } else if (IS_VAR == IS_VAR || IS_VAR == IS_CV) { - zval_ptr_dtor(&tmp); } zval_ptr_dtor_nogc(free_op1.var); CHECK_EXCEPTION(); @@ -23255,12 +23263,9 @@ num_index_dim: zend_hash_index_del(ht, hval); break; case IS_STRING: - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - if (Z_REFCOUNTED_P(offset)) Z_ADDREF_P(offset); - } if (IS_VAR != IS_CONST) { if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) { - goto numeric_index_dim; + goto num_index_dim; } } if (ht == &EG(symbol_table).ht) { @@ -23268,15 +23273,6 @@ num_index_dim: } else { zend_hash_del(ht, Z_STR_P(offset)); } - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - zval_ptr_dtor(offset); - } - break; -numeric_index_dim: - zend_hash_index_del(ht, hval); - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - zval_ptr_dtor(offset); - } break; case IS_NULL: zend_hash_del(ht, STR_EMPTY_ALLOC()); @@ -24614,29 +24610,37 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HAN zval tmp, *varname; HashTable *target_symbol_table; zend_free_op free_op1; - zend_bool tmp_is_dup = 0; SAVE_OPLINE(); if (IS_VAR == IS_CV && IS_UNUSED == IS_UNUSED && (opline->extended_value & ZEND_QUICK_SET)) { - ZVAL_COPY_VALUE(&tmp, EX_VAR(opline->op1.var)); - ZVAL_UNDEF(EX_VAR(opline->op1.var)); - zval_ptr_dtor(&tmp); + zval *var = EX_VAR(opline->op1.var); + + if (Z_REFCOUNTED_P(var)) { + zend_refcounted *garbage = Z_COUNTED_P(var); + + if (!--GC_REFCOUNT(garbage)) { + ZVAL_UNDEF(var); + _zval_dtor_func_for_ptr(garbage ZEND_FILE_LINE_CC); + } else { + GC_ZVAL_CHECK_POSSIBLE_ROOT(var); + ZVAL_UNDEF(var); + } + } else { + ZVAL_UNDEF(var); + } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + ZVAL_UNDEF(&tmp); if (IS_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { ZVAL_DUP(&tmp, varname); convert_to_string(&tmp); varname = &tmp; - tmp_is_dup = 1; - } else if (IS_VAR == IS_VAR || IS_VAR == IS_CV) { - ZVAL_COPY(&tmp, varname); - varname = &tmp; } if (IS_UNUSED != IS_UNUSED) { @@ -24648,10 +24652,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HAN } else { ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, 0 TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { - if (IS_VAR != IS_CONST && tmp_is_dup) { + if (IS_VAR != IS_CONST) { zval_dtor(&tmp); - } else if (IS_VAR == IS_VAR || IS_VAR == IS_CV) { - zval_ptr_dtor(&tmp); } zval_ptr_dtor_nogc(free_op1.var); HANDLE_EXCEPTION(); @@ -24670,10 +24672,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HAN zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); } - if (IS_VAR != IS_CONST && tmp_is_dup) { + if (IS_VAR != IS_CONST) { zval_dtor(&tmp); - } else if (IS_VAR == IS_VAR || IS_VAR == IS_CV) { - zval_ptr_dtor(&tmp); } zval_ptr_dtor_nogc(free_op1.var); CHECK_EXCEPTION(); @@ -26559,12 +26559,9 @@ num_index_dim: zend_hash_index_del(ht, hval); break; case IS_STRING: - if (IS_CV == IS_CV || IS_CV == IS_VAR) { - if (Z_REFCOUNTED_P(offset)) Z_ADDREF_P(offset); - } if (IS_CV != IS_CONST) { if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) { - goto numeric_index_dim; + goto num_index_dim; } } if (ht == &EG(symbol_table).ht) { @@ -26572,15 +26569,6 @@ num_index_dim: } else { zend_hash_del(ht, Z_STR_P(offset)); } - if (IS_CV == IS_CV || IS_CV == IS_VAR) { - zval_ptr_dtor(offset); - } - break; -numeric_index_dim: - zend_hash_index_del(ht, hval); - if (IS_CV == IS_CV || IS_CV == IS_VAR) { - zval_ptr_dtor(offset); - } break; case IS_NULL: zend_hash_del(ht, STR_EMPTY_ALLOC()); @@ -28024,12 +28012,9 @@ num_index_dim: zend_hash_index_del(ht, hval); break; case IS_STRING: - if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { - if (Z_REFCOUNTED_P(offset)) Z_ADDREF_P(offset); - } if (IS_CONST != IS_CONST) { if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) { - goto numeric_index_dim; + goto num_index_dim; } } if (ht == &EG(symbol_table).ht) { @@ -28037,15 +28022,6 @@ num_index_dim: } else { zend_hash_del(ht, Z_STR_P(offset)); } - if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { - zval_ptr_dtor(offset); - } - break; -numeric_index_dim: - zend_hash_index_del(ht, hval); - if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { - zval_ptr_dtor(offset); - } break; case IS_NULL: zend_hash_del(ht, STR_EMPTY_ALLOC()); @@ -29309,12 +29285,9 @@ num_index_dim: zend_hash_index_del(ht, hval); break; case IS_STRING: - if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { - if (Z_REFCOUNTED_P(offset)) Z_ADDREF_P(offset); - } if (IS_TMP_VAR != IS_CONST) { if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) { - goto numeric_index_dim; + goto num_index_dim; } } if (ht == &EG(symbol_table).ht) { @@ -29322,15 +29295,6 @@ num_index_dim: } else { zend_hash_del(ht, Z_STR_P(offset)); } - if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { - zval_ptr_dtor(offset); - } - break; -numeric_index_dim: - zend_hash_index_del(ht, hval); - if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { - zval_ptr_dtor(offset); - } break; case IS_NULL: zend_hash_del(ht, STR_EMPTY_ALLOC()); @@ -30596,12 +30560,9 @@ num_index_dim: zend_hash_index_del(ht, hval); break; case IS_STRING: - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - if (Z_REFCOUNTED_P(offset)) Z_ADDREF_P(offset); - } if (IS_VAR != IS_CONST) { if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) { - goto numeric_index_dim; + goto num_index_dim; } } if (ht == &EG(symbol_table).ht) { @@ -30609,15 +30570,6 @@ num_index_dim: } else { zend_hash_del(ht, Z_STR_P(offset)); } - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - zval_ptr_dtor(offset); - } - break; -numeric_index_dim: - zend_hash_index_del(ht, hval); - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - zval_ptr_dtor(offset); - } break; case IS_NULL: zend_hash_del(ht, STR_EMPTY_ALLOC()); @@ -32392,12 +32344,9 @@ num_index_dim: zend_hash_index_del(ht, hval); break; case IS_STRING: - if (IS_CV == IS_CV || IS_CV == IS_VAR) { - if (Z_REFCOUNTED_P(offset)) Z_ADDREF_P(offset); - } if (IS_CV != IS_CONST) { if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) { - goto numeric_index_dim; + goto num_index_dim; } } if (ht == &EG(symbol_table).ht) { @@ -32405,15 +32354,6 @@ num_index_dim: } else { zend_hash_del(ht, Z_STR_P(offset)); } - if (IS_CV == IS_CV || IS_CV == IS_VAR) { - zval_ptr_dtor(offset); - } - break; -numeric_index_dim: - zend_hash_index_del(ht, hval); - if (IS_CV == IS_CV || IS_CV == IS_VAR) { - zval_ptr_dtor(offset); - } break; case IS_NULL: zend_hash_del(ht, STR_EMPTY_ALLOC()); @@ -35789,29 +35729,37 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDL zval tmp, *varname; HashTable *target_symbol_table; - zend_bool tmp_is_dup = 0; SAVE_OPLINE(); if (IS_CV == IS_CV && IS_CONST == IS_UNUSED && (opline->extended_value & ZEND_QUICK_SET)) { - ZVAL_COPY_VALUE(&tmp, EX_VAR(opline->op1.var)); - ZVAL_UNDEF(EX_VAR(opline->op1.var)); - zval_ptr_dtor(&tmp); + zval *var = EX_VAR(opline->op1.var); + + if (Z_REFCOUNTED_P(var)) { + zend_refcounted *garbage = Z_COUNTED_P(var); + + if (!--GC_REFCOUNT(garbage)) { + ZVAL_UNDEF(var); + _zval_dtor_func_for_ptr(garbage ZEND_FILE_LINE_CC); + } else { + GC_ZVAL_CHECK_POSSIBLE_ROOT(var); + ZVAL_UNDEF(var); + } + } else { + ZVAL_UNDEF(var); + } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } varname = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); + ZVAL_UNDEF(&tmp); if (IS_CV != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { ZVAL_DUP(&tmp, varname); convert_to_string(&tmp); varname = &tmp; - tmp_is_dup = 1; - } else if (IS_CV == IS_VAR || IS_CV == IS_CV) { - ZVAL_COPY(&tmp, varname); - varname = &tmp; } if (IS_CONST != IS_UNUSED) { @@ -35823,10 +35771,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDL } else { ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, 0 TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { - if (IS_CV != IS_CONST && tmp_is_dup) { + if (IS_CV != IS_CONST) { zval_dtor(&tmp); - } else if (IS_CV == IS_VAR || IS_CV == IS_CV) { - zval_ptr_dtor(&tmp); } HANDLE_EXCEPTION(); @@ -35845,10 +35791,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDL zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); } - if (IS_CV != IS_CONST && tmp_is_dup) { + if (IS_CV != IS_CONST) { zval_dtor(&tmp); - } else if (IS_CV == IS_VAR || IS_CV == IS_CV) { - zval_ptr_dtor(&tmp); } CHECK_EXCEPTION(); @@ -35889,12 +35833,9 @@ num_index_dim: zend_hash_index_del(ht, hval); break; case IS_STRING: - if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { - if (Z_REFCOUNTED_P(offset)) Z_ADDREF_P(offset); - } if (IS_CONST != IS_CONST) { if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) { - goto numeric_index_dim; + goto num_index_dim; } } if (ht == &EG(symbol_table).ht) { @@ -35902,15 +35843,6 @@ num_index_dim: } else { zend_hash_del(ht, Z_STR_P(offset)); } - if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { - zval_ptr_dtor(offset); - } - break; -numeric_index_dim: - zend_hash_index_del(ht, hval); - if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { - zval_ptr_dtor(offset); - } break; case IS_NULL: zend_hash_del(ht, STR_EMPTY_ALLOC()); @@ -37889,12 +37821,9 @@ num_index_dim: zend_hash_index_del(ht, hval); break; case IS_STRING: - if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { - if (Z_REFCOUNTED_P(offset)) Z_ADDREF_P(offset); - } if (IS_TMP_VAR != IS_CONST) { if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) { - goto numeric_index_dim; + goto num_index_dim; } } if (ht == &EG(symbol_table).ht) { @@ -37902,15 +37831,6 @@ num_index_dim: } else { zend_hash_del(ht, Z_STR_P(offset)); } - if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { - zval_ptr_dtor(offset); - } - break; -numeric_index_dim: - zend_hash_index_del(ht, hval); - if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { - zval_ptr_dtor(offset); - } break; case IS_NULL: zend_hash_del(ht, STR_EMPTY_ALLOC()); @@ -39940,29 +39860,37 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER zval tmp, *varname; HashTable *target_symbol_table; - zend_bool tmp_is_dup = 0; SAVE_OPLINE(); if (IS_CV == IS_CV && IS_VAR == IS_UNUSED && (opline->extended_value & ZEND_QUICK_SET)) { - ZVAL_COPY_VALUE(&tmp, EX_VAR(opline->op1.var)); - ZVAL_UNDEF(EX_VAR(opline->op1.var)); - zval_ptr_dtor(&tmp); + zval *var = EX_VAR(opline->op1.var); + + if (Z_REFCOUNTED_P(var)) { + zend_refcounted *garbage = Z_COUNTED_P(var); + + if (!--GC_REFCOUNT(garbage)) { + ZVAL_UNDEF(var); + _zval_dtor_func_for_ptr(garbage ZEND_FILE_LINE_CC); + } else { + GC_ZVAL_CHECK_POSSIBLE_ROOT(var); + ZVAL_UNDEF(var); + } + } else { + ZVAL_UNDEF(var); + } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } varname = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); + ZVAL_UNDEF(&tmp); if (IS_CV != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { ZVAL_DUP(&tmp, varname); convert_to_string(&tmp); varname = &tmp; - tmp_is_dup = 1; - } else if (IS_CV == IS_VAR || IS_CV == IS_CV) { - ZVAL_COPY(&tmp, varname); - varname = &tmp; } if (IS_VAR != IS_UNUSED) { @@ -39974,10 +39902,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER } else { ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, 0 TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { - if (IS_CV != IS_CONST && tmp_is_dup) { + if (IS_CV != IS_CONST) { zval_dtor(&tmp); - } else if (IS_CV == IS_VAR || IS_CV == IS_CV) { - zval_ptr_dtor(&tmp); } HANDLE_EXCEPTION(); @@ -39996,10 +39922,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); } - if (IS_CV != IS_CONST && tmp_is_dup) { + if (IS_CV != IS_CONST) { zval_dtor(&tmp); - } else if (IS_CV == IS_VAR || IS_CV == IS_CV) { - zval_ptr_dtor(&tmp); } CHECK_EXCEPTION(); @@ -40040,12 +39964,9 @@ num_index_dim: zend_hash_index_del(ht, hval); break; case IS_STRING: - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - if (Z_REFCOUNTED_P(offset)) Z_ADDREF_P(offset); - } if (IS_VAR != IS_CONST) { if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) { - goto numeric_index_dim; + goto num_index_dim; } } if (ht == &EG(symbol_table).ht) { @@ -40053,15 +39974,6 @@ num_index_dim: } else { zend_hash_del(ht, Z_STR_P(offset)); } - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - zval_ptr_dtor(offset); - } - break; -numeric_index_dim: - zend_hash_index_del(ht, hval); - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - zval_ptr_dtor(offset); - } break; case IS_NULL: zend_hash_del(ht, STR_EMPTY_ALLOC()); @@ -41281,29 +41193,37 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAND zval tmp, *varname; HashTable *target_symbol_table; - zend_bool tmp_is_dup = 0; SAVE_OPLINE(); if (IS_CV == IS_CV && IS_UNUSED == IS_UNUSED && (opline->extended_value & ZEND_QUICK_SET)) { - ZVAL_COPY_VALUE(&tmp, EX_VAR(opline->op1.var)); - ZVAL_UNDEF(EX_VAR(opline->op1.var)); - zval_ptr_dtor(&tmp); + zval *var = EX_VAR(opline->op1.var); + + if (Z_REFCOUNTED_P(var)) { + zend_refcounted *garbage = Z_COUNTED_P(var); + + if (!--GC_REFCOUNT(garbage)) { + ZVAL_UNDEF(var); + _zval_dtor_func_for_ptr(garbage ZEND_FILE_LINE_CC); + } else { + GC_ZVAL_CHECK_POSSIBLE_ROOT(var); + ZVAL_UNDEF(var); + } + } else { + ZVAL_UNDEF(var); + } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } varname = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); + ZVAL_UNDEF(&tmp); if (IS_CV != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { ZVAL_DUP(&tmp, varname); convert_to_string(&tmp); varname = &tmp; - tmp_is_dup = 1; - } else if (IS_CV == IS_VAR || IS_CV == IS_CV) { - ZVAL_COPY(&tmp, varname); - varname = &tmp; } if (IS_UNUSED != IS_UNUSED) { @@ -41315,10 +41235,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAND } else { ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, 0 TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { - if (IS_CV != IS_CONST && tmp_is_dup) { + if (IS_CV != IS_CONST) { zval_dtor(&tmp); - } else if (IS_CV == IS_VAR || IS_CV == IS_CV) { - zval_ptr_dtor(&tmp); } HANDLE_EXCEPTION(); @@ -41337,10 +41255,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAND zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); } - if (IS_CV != IS_CONST && tmp_is_dup) { + if (IS_CV != IS_CONST) { zval_dtor(&tmp); - } else if (IS_CV == IS_VAR || IS_CV == IS_CV) { - zval_ptr_dtor(&tmp); } CHECK_EXCEPTION(); @@ -43088,12 +43004,9 @@ num_index_dim: zend_hash_index_del(ht, hval); break; case IS_STRING: - if (IS_CV == IS_CV || IS_CV == IS_VAR) { - if (Z_REFCOUNTED_P(offset)) Z_ADDREF_P(offset); - } if (IS_CV != IS_CONST) { if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) { - goto numeric_index_dim; + goto num_index_dim; } } if (ht == &EG(symbol_table).ht) { @@ -43101,15 +43014,6 @@ num_index_dim: } else { zend_hash_del(ht, Z_STR_P(offset)); } - if (IS_CV == IS_CV || IS_CV == IS_VAR) { - zval_ptr_dtor(offset); - } - break; -numeric_index_dim: - zend_hash_index_del(ht, hval); - if (IS_CV == IS_CV || IS_CV == IS_VAR) { - zval_ptr_dtor(offset); - } break; case IS_NULL: zend_hash_del(ht, STR_EMPTY_ALLOC()); |