zval *var;
USE_OPLINE
- SAVE_OPLINE();
var = EX_VAR(opline->op1.var);
- if (Z_TYPE_P(var) != IS_ARRAY && Z_FE_ITER_P(var) != (uint32_t)-1) {
- zend_hash_iterator_del(Z_FE_ITER_P(var));
+ if (Z_TYPE_P(var) != IS_ARRAY) {
+ SAVE_OPLINE();
+ if (Z_FE_ITER_P(var) != (uint32_t)-1) {
+ zend_hash_iterator_del(Z_FE_ITER_P(var));
+ }
+ zval_ptr_dtor_nogc(var);
+ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
- zval_ptr_dtor_nogc(var);
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+
+ /* This is freeing an array. Use an inlined version of zval_ptr_dtor_nogc. */
+ /* PHP only needs to save the opline and check for an exception if the last reference to the array was garbage collected (destructors of elements in the array could throw an exception) */
+ if (Z_REFCOUNTED_P(var) && !Z_DELREF_P(var)) {
+ SAVE_OPLINE();
+ rc_dtor_func(Z_COUNTED_P(var));
+ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+ }
+ ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_COLD_CONSTCONST_HANDLER(53, ZEND_FAST_CONCAT, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
zval *var;
USE_OPLINE
- SAVE_OPLINE();
var = EX_VAR(opline->op1.var);
- if (Z_TYPE_P(var) != IS_ARRAY && Z_FE_ITER_P(var) != (uint32_t)-1) {
- zend_hash_iterator_del(Z_FE_ITER_P(var));
+ if (Z_TYPE_P(var) != IS_ARRAY) {
+ SAVE_OPLINE();
+ if (Z_FE_ITER_P(var) != (uint32_t)-1) {
+ zend_hash_iterator_del(Z_FE_ITER_P(var));
+ }
+ zval_ptr_dtor_nogc(var);
+ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
- zval_ptr_dtor_nogc(var);
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+
+ /* This is freeing an array. Use an inlined version of zval_ptr_dtor_nogc. */
+ /* PHP only needs to save the opline and check for an exception if the last reference to the array was garbage collected (destructors of elements in the array could throw an exception) */
+ if (Z_REFCOUNTED_P(var) && !Z_DELREF_P(var)) {
+ SAVE_OPLINE();
+ rc_dtor_func(Z_COUNTED_P(var));
+ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+ }
+ ZEND_VM_NEXT_OPCODE();
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_THROW_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)