diff --git a/Zend/tests/self_xor.phpt b/Zend/tests/self_xor.phpt index 02df865b570..c097930d6dd 100644 --- a/Zend/tests/self_xor.phpt +++ b/Zend/tests/self_xor.phpt @@ -6,7 +6,6 @@ XORing strings $s = "123"; $s1 = "test"; $s2 = "45345some"; -$s3 = "f"; $s ^= 22; var_dump($s); @@ -17,9 +16,6 @@ var_dump($s1); $s2 ^= 33; var_dump($s2); -$s3 ^= " "; -var_dump($s3); - echo "Done\n"; ?> --EXPECTF-- @@ -30,5 +26,4 @@ int(11) Notice: A non well formed numeric value encountered in %s on line %d int(45312) -string(1) "F" Done diff --git a/Zend/tests/shift_003.phpt b/Zend/tests/shift_003.phpt deleted file mode 100644 index 77545dc9fe1..00000000000 --- a/Zend/tests/shift_003.phpt +++ /dev/null @@ -1,19 +0,0 @@ ---TEST-- -Test behavior of failing bitshift assign ---FILE-- ->= -1; -} catch (Error $e) { var_dump($a); } - -try { - $a = 1; - $a <<= -1; -} catch (Error $e) { var_dump($a); } - -?> ---EXPECT-- -int(1) -int(1) diff --git a/Zend/tests/temporary_cleaning_013.phpt b/Zend/tests/temporary_cleaning_013.phpt deleted file mode 100644 index 34e4080f568..00000000000 --- a/Zend/tests/temporary_cleaning_013.phpt +++ /dev/null @@ -1,311 +0,0 @@ ---TEST-- -Exceptions thrown in operand cleaning must cause leak of return value ---FILE-- - [0]]; - var_dump($foo->foo += [new class { - function __destruct() { throw new Exception; } - }]); -} catch (Exception $e) { print "caught Exception 4\n"; } - -try { - $foo = new class { - function __get($x) { return [0]; } - function __set($x, $y) {} - }; - var_dump($foo->foo += [new class { - function __destruct() { throw new Exception; } - }]); -} catch (Exception $e) { print "caught Exception 5\n"; } - -try { - $foo = new class { - public $bar = [0]; - function &__get($x) { return $this->bar; } - }; - var_dump($foo->foo += [new class { - function __destruct() { throw new Exception; } - }]); -} catch (Exception $e) { print "caught Exception 6\n"; } - -try { - $foo = new class implements ArrayAccess { - function offsetGet($x) { return [0]; } - function offsetSet($x, $y) {} - function offsetExists($x) { return true; } - function offsetUnset($x) {} - }; - var_dump($foo[0] += [new class { - function __destruct() { throw new Exception; } - }]); -} catch (Exception $e) { print "caught Exception 7\n"; } - -try { - $foo = new class implements ArrayAccess { - public $foo = [0]; - function &offsetGet($x) { return $this->foo; } - function offsetSet($x, $y) {} - function offsetExists($x) { return true; } - function offsetUnset($x) {} - }; - var_dump($foo[0] += [new class { - function __destruct() { throw new Exception; } - }]); -} catch (Exception $e) { print "caught Exception 8\n"; } - -try { - var_dump((function() { return new class { - function __construct() { $this->foo = new stdClass; } - function __destruct() { throw new Exception; } - }; })()->foo++); -} catch (Exception $e) { print "caught Exception 9\n"; } - -try { - var_dump((function() { return new class { - function __get($x) { return new stdClass; } - function __set($x, $y) {} - function __destruct() { throw new Exception; } - }; })()->foo++); -} catch (Exception $e) { print "caught Exception 10\n"; } - -try { - var_dump((function() { return new class { - function __construct() { $this->bar = new stdClass; } - function &__get($x) { return $this->bar; } - function __destruct() { throw new Exception; } - }; })()->foo++); -} catch (Exception $e) { print "caught Exception 11\n"; } - -try { - var_dump(++(function() { return new class { - function __construct() { $this->foo = new stdClass; } - function __destruct() { throw new Exception; } - }; })()->foo); -} catch (Exception $e) { print "caught Exception 12\n"; } - -try { - var_dump(++(function() { return new class { - function __get($x) { return new stdClass; } - function __set($x, $y) {} - function __destruct() { throw new Exception; } - }; })()->foo); -} catch (Exception $e) { print "caught Exception 13\n"; } - -try { - var_dump(++(function() { return new class { - function __construct() { $this->bar = new stdClass; } - function &__get($x) { return $this->bar; } - function __destruct() { throw new Exception; } - }; })()->foo); -} catch (Exception $e) { print "caught Exception 14\n"; } - -try { - var_dump((function() { return new class implements ArrayAccess { - function offsetGet($x) { return [new stdClass]; } - function offsetSet($x, $y) {} - function offsetExists($x) { return true; } - function offsetUnset($x) {} - function __destruct() { throw new Exception; } - }; })()[0]++); -} catch (Exception $e) { print "caught Exception 15\n"; } - -try { - var_dump(++(function() { return new class implements ArrayAccess { - function offsetGet($x) { return [new stdClass]; } - function offsetSet($x, $y) {} - function offsetExists($x) { return true; } - function offsetUnset($x) {} - function __destruct() { throw new Exception; } - }; })()[0]); -} catch (Exception $e) { print "caught Exception 16\n"; } - -try { - var_dump((new class { - function __construct() { $this->foo = new stdClass; } - function __destruct() { throw new Exception; } - })->foo); -} catch (Exception $e) { print "caught Exception 17\n"; } - -try { - var_dump((new class { - function __get($x) { return new stdClass; } - function __set($x, $y) {} - function __destruct() { throw new Exception; } - })->foo); -} catch (Exception $e) { print "caught Exception 18\n"; } - -try { - var_dump((new class implements ArrayAccess { - function offsetGet($x) { return [new stdClass]; } - function offsetSet($x, $y) {} - function offsetExists($x) { return true; } - function offsetUnset($x) {} - function __destruct() { throw new Exception; } - })[0]); -} catch (Exception $e) { print "caught Exception 19\n"; } - -try { - var_dump(isset((new class { - function __construct() { $this->foo = new stdClass; } - function __destruct() { throw new Exception; } - })->foo->bar)); -} catch (Exception $e) { print "caught Exception 20\n"; } - -try { - var_dump(isset((new class { - function __get($x) { return new stdClass; } - function __set($x, $y) {} - function __destruct() { throw new Exception; } - })->foo->bar)); -} catch (Exception $e) { print "caught Exception 21\n"; } - -try { - var_dump(isset((new class implements ArrayAccess { - function offsetGet($x) { return [new stdClass]; } - function offsetSet($x, $y) {} - function offsetExists($x) { return true; } - function offsetUnset($x) {} - function __destruct() { throw new Exception; } - })[0]->bar)); -} catch (Exception $e) { print "caught Exception 22\n"; } - -try { - $foo = new class { - function __destruct() { throw new Exception; } - }; - var_dump($foo = new stdClass); -} catch (Exception $e) { print "caught Exception 23\n"; } - -try { - $foo = [new class { - function __destruct() { throw new Exception; } - }]; - var_dump($foo[0] = new stdClass); -} catch (Exception $e) { print "caught Exception 24\n"; } - -try { - $foo = (object) ["foo" => new class { - function __destruct() { throw new Exception; } - }]; - var_dump($foo->foo = new stdClass); -} catch (Exception $e) { print "caught Exception 25\n"; } - -try { - $foo = new class { - function __get($x) {} - function __set($x, $y) { throw new Exception; } - }; - var_dump($foo->foo = new stdClass); -} catch (Exception $e) { print "caught Exception 26\n"; } - -try { - $foo = new class implements ArrayAccess { - function offsetGet($x) {} - function offsetSet($x, $y) { throw new Exception; } - function offsetExists($x) { return true; } - function offsetUnset($x) {} - }; - var_dump($foo[0] = new stdClass); -} catch (Exception $e) { print "caught Exception 27\n"; } - -try { - $foo = new class { - function __destruct() { throw new Exception; } - }; - $bar = new stdClass; - var_dump($foo = &$bar); -} catch (Exception $e) { print "caught Exception 28\n"; } - -try { - $f = function() { - return new class { - function __toString() { return "a"; } - function __destruct() { throw new Exception; } - }; - }; - var_dump("{$f()}foo"); -} catch (Exception $e) { print "caught Exception 29\n"; } - -try { - $f = function() { - return new class { - function __toString() { return "a"; } - function __destruct() { throw new Exception; } - }; - }; - var_dump("bar{$f()}foo"); -} catch (Exception $e) { print "caught Exception 30\n"; } - -try { - var_dump((string) new class { - function __toString() { $x = "Z"; return ++$x; } - function __destruct() { throw new Exception; } - }); -} catch (Exception $e) { print "caught Exception 31\n"; } - -try { - var_dump(clone (new class { - function __clone() { throw new Exception; } - })); -} catch (Exception $e) { print "caught Exception 32\n"; } - -?> ---EXPECTF-- -caught Exception 1 -caught Exception 2 -caught Exception 3 -caught Exception 4 -caught Exception 5 -caught Exception 6 -caught Exception 7 -caught Exception 8 -caught Exception 9 -caught Exception 10 -caught Exception 11 -caught Exception 12 -caught Exception 13 -caught Exception 14 - -Notice: Indirect modification of overloaded element of class@anonymous has no effect in %s on line %d -caught Exception 15 - -Notice: Indirect modification of overloaded element of class@anonymous has no effect in %s on line %d -caught Exception 16 -caught Exception 17 -caught Exception 18 -caught Exception 19 -caught Exception 20 -caught Exception 21 -caught Exception 22 -caught Exception 23 -caught Exception 24 -caught Exception 25 -caught Exception 26 -caught Exception 27 -caught Exception 28 -caught Exception 29 -caught Exception 30 -caught Exception 31 -caught Exception 32 diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 4f692ac454f..a2df1ef0485 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1369,7 +1369,6 @@ static zend_never_inline void zend_post_incdec_overloaded_property(zval *object, z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, cache_slot, &rv); if (UNEXPECTED(EG(exception))) { OBJ_RELEASE(Z_OBJ(obj)); - ZVAL_UNDEF(result); return; } @@ -1415,7 +1414,6 @@ static zend_never_inline void zend_pre_incdec_overloaded_property(zval *object, zptr = z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, cache_slot, &rv); if (UNEXPECTED(EG(exception))) { OBJ_RELEASE(Z_OBJ(obj)); - ZVAL_UNDEF(result); return; } @@ -1461,9 +1459,6 @@ static zend_never_inline void zend_assign_op_overloaded_property(zval *object, z z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, cache_slot, &rv); if (UNEXPECTED(EG(exception))) { OBJ_RELEASE(Z_OBJ(obj)); - if (result) { - ZVAL_UNDEF(result); - } return; } if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) { @@ -2946,16 +2941,12 @@ ZEND_API int ZEND_FASTCALL zend_do_fcall_overloaded(zend_execute_data *call, zva #define ZEND_VM_SET_RELATIVE_OPCODE(opline, offset) \ ZEND_VM_SET_OPCODE(ZEND_OFFSET_TO_OPLINE(opline, offset)) -#define ZEND_VM_JMP_NO_EXCEPTION(new_op) do { \ - ZEND_VM_SET_OPCODE(new_op); \ - ZEND_VM_CONTINUE(); \ - } while (0) - #define ZEND_VM_JMP(new_op) do { \ if (UNEXPECTED(EG(exception))) { \ HANDLE_EXCEPTION(); \ } \ - ZEND_VM_JMP_NO_EXCEPTION(new_op); \ + ZEND_VM_SET_OPCODE(new_op); \ + ZEND_VM_CONTINUE(); \ } while (0) #define ZEND_VM_INC_OPCODE() \ @@ -3033,11 +3024,6 @@ ZEND_API int ZEND_FASTCALL zend_do_fcall_overloaded(zend_execute_data *call, zva #define GET_OP2_UNDEF_CV(ptr, type) \ _get_zval_cv_lookup_ ## type(ptr, opline->op2.var, execute_data) -#define ZEND_VM_UNDEF_RETVAL() \ - if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { \ - ZVAL_UNDEF(EX_VAR(opline->result.var)); \ - } - #include "zend_vm_execute.h" ZEND_API int zend_set_user_opcode_handler(zend_uchar opcode, user_opcode_handler_t handler) diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index c850c917662..80055776944 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -926,9 +926,6 @@ ZEND_API int ZEND_FASTCALL add_function(zval *result, zval *op1, zval *op2) /* { zendi_convert_scalar_to_number(op2, op2_copy, result, 0); converted = 1; } else { - if (result != op1) { - ZVAL_UNDEF(result); - } zend_throw_error(NULL, "Unsupported operand types"); return FAILURE; /* unknown datatype */ } @@ -971,9 +968,6 @@ ZEND_API int ZEND_FASTCALL sub_function(zval *result, zval *op1, zval *op2) /* { zendi_convert_scalar_to_number(op2, op2_copy, result, 0); converted = 1; } else { - if (result != op1) { - ZVAL_UNDEF(result); - } zend_throw_error(NULL, "Unsupported operand types"); return FAILURE; /* unknown datatype */ } @@ -1021,9 +1015,6 @@ ZEND_API int ZEND_FASTCALL mul_function(zval *result, zval *op1, zval *op2) /* { zendi_convert_scalar_to_number(op2, op2_copy, result, 0); converted = 1; } else { - if (result != op1) { - ZVAL_UNDEF(result); - } zend_throw_error(NULL, "Unsupported operand types"); return FAILURE; /* unknown datatype */ } @@ -1112,9 +1103,6 @@ ZEND_API int ZEND_FASTCALL pow_function(zval *result, zval *op1, zval *op2) /* { } converted = 1; } else { - if (result != op1) { - ZVAL_UNDEF(result); - } zend_throw_error(NULL, "Unsupported operand types"); return FAILURE; } @@ -1180,9 +1168,6 @@ ZEND_API int ZEND_FASTCALL div_function(zval *result, zval *op1, zval *op2) /* { zendi_convert_scalar_to_number(op2, op2_copy, result, 0); converted = 1; } else { - if (result != op1) { - ZVAL_UNDEF(result); - } zend_throw_error(NULL, "Unsupported operand types"); return FAILURE; /* unknown datatype */ } @@ -1197,6 +1182,10 @@ ZEND_API int ZEND_FASTCALL mod_function(zval *result, zval *op1, zval *op2) /* { convert_op1_op2_long(op1, op1_lval, op2, op2_lval, ZEND_MOD, mod_function); + if (op1 == result) { + zval_dtor(result); + } + if (op2_lval == 0) { /* modulus by zero */ if (EG(current_execute_data) && !CG(in_compilation)) { @@ -1204,16 +1193,10 @@ ZEND_API int ZEND_FASTCALL mod_function(zval *result, zval *op1, zval *op2) /* { } else { zend_error_noreturn(E_ERROR, "Modulo by zero"); } - if (op1 != result) { - ZVAL_UNDEF(result); - } + ZVAL_UNDEF(result); return FAILURE; } - if (op1 == result) { - zval_dtor(result); - } - if (op2_lval == -1) { /* Prevent overflow error/crash if op1==LONG_MIN */ ZVAL_LONG(result, 0); @@ -1335,9 +1318,6 @@ try_again: default: ZEND_TRY_UNARY_OBJECT_OPERATION(ZEND_BW_NOT); - if (result != op1) { - ZVAL_UNDEF(result); - } zend_throw_error(NULL, "Unsupported operand types"); return FAILURE; } @@ -1364,9 +1344,6 @@ ZEND_API int ZEND_FASTCALL bitwise_or_function(zval *result, zval *op1, zval *op if (EXPECTED(Z_STRLEN_P(op1) >= Z_STRLEN_P(op2))) { if (EXPECTED(Z_STRLEN_P(op1) == Z_STRLEN_P(op2)) && Z_STRLEN_P(op1) == 1) { zend_uchar or = (zend_uchar) (*Z_STRVAL_P(op1) | *Z_STRVAL_P(op2)); - if (result==op1) { - zend_string_release(Z_STR_P(result)); - } if (CG(one_char_string)[or]) { ZVAL_INTERNED_STR(result, CG(one_char_string)[or]); } else { @@ -1434,9 +1411,6 @@ ZEND_API int ZEND_FASTCALL bitwise_and_function(zval *result, zval *op1, zval *o if (EXPECTED(Z_STRLEN_P(op1) >= Z_STRLEN_P(op2))) { if (EXPECTED(Z_STRLEN_P(op1) == Z_STRLEN_P(op2)) && Z_STRLEN_P(op1) == 1) { zend_uchar and = (zend_uchar) (*Z_STRVAL_P(op1) & *Z_STRVAL_P(op2)); - if (result==op1) { - zend_string_release(Z_STR_P(result)); - } if (CG(one_char_string)[and]) { ZVAL_INTERNED_STR(result, CG(one_char_string)[and]); } else { @@ -1504,9 +1478,6 @@ ZEND_API int ZEND_FASTCALL bitwise_xor_function(zval *result, zval *op1, zval *o if (EXPECTED(Z_STRLEN_P(op1) >= Z_STRLEN_P(op2))) { if (EXPECTED(Z_STRLEN_P(op1) == Z_STRLEN_P(op2)) && Z_STRLEN_P(op1) == 1) { zend_uchar xor = (zend_uchar) (*Z_STRVAL_P(op1) ^ *Z_STRVAL_P(op2)); - if (result==op1) { - zend_string_release(Z_STR_P(result)); - } if (CG(one_char_string)[xor]) { ZVAL_INTERNED_STR(result, CG(one_char_string)[xor]); } else { @@ -1560,13 +1531,13 @@ ZEND_API int ZEND_FASTCALL shift_left_function(zval *result, zval *op1, zval *op convert_op1_op2_long(op1, op1_lval, op2, op2_lval, ZEND_SL, shift_left_function); + if (op1 == result) { + zval_dtor(result); + } + /* prevent wrapping quirkiness on some processors where << 64 + x == << x */ if (UNEXPECTED((zend_ulong)op2_lval >= SIZEOF_ZEND_LONG * 8)) { if (EXPECTED(op2_lval > 0)) { - if (op1 == result) { - zval_dtor(result); - } - ZVAL_LONG(result, 0); return SUCCESS; } else { @@ -1575,17 +1546,11 @@ ZEND_API int ZEND_FASTCALL shift_left_function(zval *result, zval *op1, zval *op } else { zend_error_noreturn(E_ERROR, "Bit shift by negative number"); } - if (op1 != result) { - ZVAL_UNDEF(result); - } + ZVAL_UNDEF(result); return FAILURE; } } - if (op1 == result) { - zval_dtor(result); - } - ZVAL_LONG(result, op1_lval << op2_lval); return SUCCESS; } @@ -1597,13 +1562,13 @@ ZEND_API int ZEND_FASTCALL shift_right_function(zval *result, zval *op1, zval *o convert_op1_op2_long(op1, op1_lval, op2, op2_lval, ZEND_SR, shift_right_function); + if (op1 == result) { + zval_dtor(result); + } + /* prevent wrapping quirkiness on some processors where >> 64 + x == >> x */ if (UNEXPECTED((zend_ulong)op2_lval >= SIZEOF_ZEND_LONG * 8)) { if (EXPECTED(op2_lval > 0)) { - if (op1 == result) { - zval_dtor(result); - } - ZVAL_LONG(result, (op1_lval < 0) ? -1 : 0); return SUCCESS; } else { @@ -1612,17 +1577,11 @@ ZEND_API int ZEND_FASTCALL shift_right_function(zval *result, zval *op1, zval *o } else { zend_error_noreturn(E_ERROR, "Bit shift by negative number"); } - if (op1 != result) { - ZVAL_UNDEF(result); - } + ZVAL_UNDEF(result); return FAILURE; } } - if (op1 == result) { - zval_dtor(result); - } - ZVAL_LONG(result, op1_lval >> op2_lval); return SUCCESS; } @@ -1630,7 +1589,7 @@ ZEND_API int ZEND_FASTCALL shift_right_function(zval *result, zval *op1, zval *o ZEND_API int ZEND_FASTCALL concat_function(zval *result, zval *op1, zval *op2) /* {{{ */ { - zval op1_copy, op2_copy, orig_op1; + zval op1_copy, op2_copy; int use_copy1 = 0, use_copy2 = 0; do { @@ -1646,12 +1605,10 @@ ZEND_API int ZEND_FASTCALL concat_function(zval *result, zval *op1, zval *op2) / * we have to free it. */ if (result == op1) { - ZVAL_COPY_VALUE(&orig_op1, result); + zval_dtor(op1); if (UNEXPECTED(op1 == op2)) { op2 = &op1_copy; } - } else { - ZVAL_UNDEF(&orig_op1); } op1 = &op1_copy; } @@ -1679,19 +1636,7 @@ ZEND_API int ZEND_FASTCALL concat_function(zval *result, zval *op1, zval *op2) / if (UNEXPECTED(op1_len > SIZE_MAX - op2_len)) { zend_throw_error(NULL, "String size overflow"); - - if (UNEXPECTED(use_copy1)) { - zval_dtor(op1); - if (Z_ISUNDEF(orig_op1)) { - ZVAL_UNDEF(result); - } - } else if (result != op1) { - ZVAL_UNDEF(result); - } - if (UNEXPECTED(use_copy2)) { - zval_dtor(op2); - } - + ZVAL_FALSE(result); return FAILURE; } @@ -1714,7 +1659,6 @@ ZEND_API int ZEND_FASTCALL concat_function(zval *result, zval *op1, zval *op2) / if (UNEXPECTED(use_copy1)) { zval_dtor(op1); - zval_dtor(&orig_op1); } if (UNEXPECTED(use_copy2)) { zval_dtor(op2); diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index f08342d4f19..cb2b6178573 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -893,7 +893,6 @@ ZEND_VM_C_LABEL(assign_dim_op_convert_to_array): zend_check_string_offset(dim, BP_VAR_RW); zend_wrong_string_offset(); } - ZVAL_UNDEF(EX_VAR(opline->result.var)); } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { ZEND_VM_C_GOTO(assign_dim_op_convert_to_array); } else { @@ -1555,11 +1554,9 @@ ZEND_VM_C_LABEL(fetch_this): break; case BP_VAR_RW: case BP_VAR_W: - ZVAL_UNDEF(result); zend_throw_error(NULL, "Cannot re-assign $this"); break; case BP_VAR_UNSET: - ZVAL_UNDEF(result); zend_throw_error(NULL, "Cannot unset $this"); break; EMPTY_SWITCH_DEFAULT_CASE() @@ -1740,7 +1737,6 @@ ZEND_VM_HELPER(zend_fetch_static_prop_helper, CONST|TMPVAR|CV, UNUSED|CONST|VAR, ZEND_VM_C_GOTO(fetch_static_prop_return); } } - retval = zend_std_get_static_property(ce, name, 0); if (UNEXPECTED(retval == NULL)) { ZEND_ASSERT(EG(exception)); @@ -1750,7 +1746,6 @@ ZEND_VM_HELPER(zend_fetch_static_prop_helper, CONST|TMPVAR|CV, UNUSED|CONST|VAR, FREE_OP1(); HANDLE_EXCEPTION(); } - if (OP1_TYPE == IS_CONST && retval) { CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); } @@ -2365,7 +2360,7 @@ ZEND_VM_C_LABEL(fast_assign_obj): Z_OBJ_HT_P(object)->write_property(object, property_name, value, (OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } FREE_OP_DATA(); @@ -2427,7 +2422,7 @@ ZEND_VM_C_LABEL(try_assign_dim_array): zend_assign_to_object_dim(object_ptr, dim, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -2579,7 +2574,11 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY) execute_data = EX(prev_execute_data); if (UNEXPECTED(EG(exception) != NULL)) { + const zend_op *old_opline = EX(opline); zend_throw_exception_internal(NULL); + if (RETURN_VALUE_USED(old_opline)) { + zval_ptr_dtor(EX_VAR(old_opline->result.var)); + } HANDLE_EXCEPTION_LEAVE(); } @@ -2613,7 +2612,11 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY) zend_vm_stack_free_call_frame_ex(call_info, old_execute_data); if (UNEXPECTED(EG(exception) != NULL)) { + const zend_op *old_opline = EX(opline); zend_throw_exception_internal(NULL); + if (RETURN_VALUE_USED(old_opline)) { + zval_ptr_dtor(EX_VAR(old_opline->result.var)); + } HANDLE_EXCEPTION_LEAVE(); } @@ -2694,7 +2697,8 @@ ZEND_VM_HANDLER(43, ZEND_JMPZ, CONST|TMPVAR|CV, JMP_ADDR) GET_OP1_UNDEF_CV(val, BP_VAR_R); ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); } else { - ZEND_VM_JMP_NO_EXCEPTION(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_CONTINUE(); } } @@ -2717,7 +2721,8 @@ ZEND_VM_HANDLER(44, ZEND_JMPNZ, CONST|TMPVAR|CV, JMP_ADDR) val = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); if (Z_TYPE_INFO_P(val) == IS_TRUE) { - ZEND_VM_JMP_NO_EXCEPTION(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_CONTINUE(); } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { SAVE_OPLINE(); @@ -2750,12 +2755,15 @@ ZEND_VM_HANDLER(45, ZEND_JMPZNZ, CONST|TMPVAR|CV, JMP_ADDR, JMP_ADDR) ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); ZEND_VM_CONTINUE(); } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { - if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { - SAVE_OPLINE(); - GET_OP1_UNDEF_CV(val, BP_VAR_R); + if (OP1_TYPE == IS_CV) { + if (UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { + SAVE_OPLINE(); + GET_OP1_UNDEF_CV(val, BP_VAR_R); + } ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); } else { - ZEND_VM_JMP_NO_EXCEPTION(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_CONTINUE(); } } @@ -2780,15 +2788,19 @@ ZEND_VM_HANDLER(46, ZEND_JMPZ_EX, CONST|TMPVAR|CV, JMP_ADDR) if (Z_TYPE_INFO_P(val) == IS_TRUE) { ZVAL_TRUE(EX_VAR(opline->result.var)); - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_SET_NEXT_OPCODE(opline + 1); + ZEND_VM_CONTINUE(); } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { ZVAL_FALSE(EX_VAR(opline->result.var)); - if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { - SAVE_OPLINE(); - GET_OP1_UNDEF_CV(val, BP_VAR_R); + if (OP1_TYPE == IS_CV) { + if (UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { + SAVE_OPLINE(); + GET_OP1_UNDEF_CV(val, BP_VAR_R); + } ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); } else { - ZEND_VM_JMP_NO_EXCEPTION(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_CONTINUE(); } } @@ -2816,7 +2828,8 @@ ZEND_VM_HANDLER(47, ZEND_JMPNZ_EX, CONST|TMPVAR|CV, JMP_ADDR) if (Z_TYPE_INFO_P(val) == IS_TRUE) { ZVAL_TRUE(EX_VAR(opline->result.var)); - ZEND_VM_JMP_NO_EXCEPTION(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_CONTINUE(); } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { ZVAL_FALSE(EX_VAR(opline->result.var)); if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { @@ -3929,6 +3942,12 @@ ZEND_VM_HANDLER(124, ZEND_VERIFY_RETURN_TYPE, CONST|TMP|VAR|UNUSED|CV, UNUSED) retval_ptr = retval_ref; } zend_verify_return_type(EX(func), retval_ptr, CACHE_ADDR(opline->op2.num)); + + if (UNEXPECTED(EG(exception) != NULL)) { + if (OP1_TYPE == IS_CONST) { + zval_ptr_dtor_nogc(retval_ptr); + } + } #endif } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -5000,6 +5019,7 @@ ZEND_VM_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|THIS|CV, ANY) USE_OPLINE zend_free_op free_op1; zval *obj; + zend_object *clone_obj; zend_class_entry *ce, *scope; zend_function *clone; zend_object_clone_obj_t clone_call; @@ -5064,7 +5084,12 @@ ZEND_VM_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|THIS|CV, ANY) } } - ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(obj)); + clone_obj = clone_call(obj); + if (EXPECTED(EG(exception) == NULL)) { + ZVAL_OBJ(EX_VAR(opline->result.var), clone_obj); + } else { + OBJ_RELEASE(clone_obj); + } FREE_OP1(); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -5720,7 +5745,7 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET_R, CONST|TMP|VAR|CV, JMP_ADDR) Z_FE_POS_P(result) = 0; FREE_OP1_IF_VAR(); - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } else if (OP1_TYPE != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) { if (!Z_OBJCE_P(array_ptr)->get_iterator) { HashPosition pos = 0; @@ -5873,7 +5898,7 @@ ZEND_VM_HANDLER(125, ZEND_FE_RESET_RW, CONST|TMP|VAR|CV, JMP_ADDR) Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(fe_ht, pos); FREE_OP1_VAR_PTR(); - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } else if (OP1_TYPE != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) { if (!Z_OBJCE_P(array_ptr)->get_iterator) { if (OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) { @@ -6825,15 +6850,11 @@ ZEND_VM_HANDLER(169, ZEND_COALESCE, CONST|TMP|VAR|CV, JMP_ADDR) Z_ADDREF_P(result); } } - if (UNEXPECTED(EG(exception))) { - zval_ptr_dtor_nogc(result); - HANDLE_EXCEPTION(); - } - ZEND_VM_JMP_NO_EXCEPTION(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); } FREE_OP1(); - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } ZEND_VM_HANDLER(22, ZEND_QM_ASSIGN, CONST|TMP|VAR|CV, ANY) @@ -7196,8 +7217,7 @@ ZEND_VM_HELPER(zend_dispatch_try_catch_finally_helper, ANY, ANY, uint32_t try_ca ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY) { - const zend_op *throw_op = EG(opline_before_exception); - uint32_t throw_op_num = throw_op - EX(func)->op_array.opcodes; + uint32_t throw_op_num = EG(opline_before_exception) - EX(func)->op_array.opcodes; int i, current_try_catch_offset = -1; { @@ -7226,27 +7246,6 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY) cleanup_unfinished_calls(execute_data, throw_op_num); - if (throw_op->result_type & (IS_VAR | IS_TMP_VAR)) { - switch (throw_op->opcode) { - case ZEND_ADD_ARRAY_ELEMENT: - case ZEND_ROPE_ADD: - break; /* exception while building structures, live range handling will free those */ - - case ZEND_FETCH_CLASS: - case ZEND_DECLARE_CLASS: - case ZEND_DECLARE_INHERITED_CLASS: - case ZEND_DECLARE_ANON_CLASS: - case ZEND_DECLARE_ANON_INHERITED_CLASS: - break; /* return value is zend_class_entry pointer */ - - case ZEND_JMP_SET: - break; /* takes care of handling itself */ - - default: - zval_ptr_dtor_nogc(EX_VAR(throw_op->result.var)); - } - } - ZEND_VM_DISPATCH_TO_HELPER(zend_dispatch_try_catch_finally_helper, try_catch_offset, current_try_catch_offset, op_num, throw_op_num); } @@ -7850,7 +7849,7 @@ ZEND_VM_HANDLER(151, ZEND_ASSERT_CHECK, ANY, JMP_ADDR) if (RETURN_VALUE_USED(opline)) { ZVAL_TRUE(EX_VAR(opline->result.var)); } - ZEND_VM_JMP_NO_EXCEPTION(target); + ZEND_VM_JMP(target); } else { ZEND_VM_NEXT_OPCODE(); } @@ -8009,6 +8008,9 @@ ZEND_VM_C_LABEL(call_trampoline_end): if (UNEXPECTED(EG(exception) != NULL)) { zend_throw_exception_internal(NULL); + if (RETURN_VALUE_USED(opline)) { + zval_ptr_dtor(EX_VAR(opline->result.var)); + } HANDLE_EXCEPTION_LEAVE(); } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 9a051acf909..1e601c46c70 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -385,7 +385,7 @@ typedef ZEND_OPCODE_HANDLER_RET (ZEND_FASTCALL *opcode_handler_t) (ZEND_OPCODE_H #endif #undef HANDLE_EXCEPTION #undef HANDLE_EXCEPTION_LEAVE -#define HANDLE_EXCEPTION() ZEND_VM_UNDEF_RETVAL(); LOAD_OPLINE(); ZEND_VM_CONTINUE() +#define HANDLE_EXCEPTION() LOAD_OPLINE(); ZEND_VM_CONTINUE() #define HANDLE_EXCEPTION_LEAVE() LOAD_OPLINE(); ZEND_VM_LEAVE() #if defined(ZEND_VM_FP_GLOBAL_REG) # define ZEND_VM_ENTER() execute_data = EG(current_execute_data); LOAD_OPLINE(); ZEND_VM_INTERRUPT_CHECK(); ZEND_VM_CONTINUE() @@ -502,7 +502,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_ execute_data = EX(prev_execute_data); if (UNEXPECTED(EG(exception) != NULL)) { + const zend_op *old_opline = EX(opline); zend_throw_exception_internal(NULL); + if (RETURN_VALUE_USED(old_opline)) { + zval_ptr_dtor(EX_VAR(old_opline->result.var)); + } HANDLE_EXCEPTION_LEAVE(); } @@ -536,7 +540,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_ zend_vm_stack_free_call_frame_ex(call_info, old_execute_data); if (UNEXPECTED(EG(exception) != NULL)) { + const zend_op *old_opline = EX(opline); zend_throw_exception_internal(NULL); + if (RETURN_VALUE_USED(old_opline)) { + zval_ptr_dtor(EX_VAR(old_opline->result.var)); + } HANDLE_EXCEPTION_LEAVE(); } @@ -1742,8 +1750,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_dispatch_try_catch_finally_hel static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - const zend_op *throw_op = EG(opline_before_exception); - uint32_t throw_op_num = throw_op - EX(func)->op_array.opcodes; + uint32_t throw_op_num = EG(opline_before_exception) - EX(func)->op_array.opcodes; int i, current_try_catch_offset = -1; { @@ -1772,27 +1779,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER( cleanup_unfinished_calls(execute_data, throw_op_num); - if (throw_op->result_type & (IS_VAR | IS_TMP_VAR)) { - switch (throw_op->opcode) { - case ZEND_ADD_ARRAY_ELEMENT: - case ZEND_ROPE_ADD: - break; /* exception while building structures, live range handling will free those */ - - case ZEND_FETCH_CLASS: - case ZEND_DECLARE_CLASS: - case ZEND_DECLARE_INHERITED_CLASS: - case ZEND_DECLARE_ANON_CLASS: - case ZEND_DECLARE_ANON_INHERITED_CLASS: - break; /* return value is zend_class_entry pointer */ - - case ZEND_JMP_SET: - break; /* takes care of handling itself */ - - default: - zval_ptr_dtor_nogc(EX_VAR(throw_op->result.var)); - } - } - ZEND_VM_TAIL_CALL(zend_dispatch_try_catch_finally_helper_SPEC(current_try_catch_offset, throw_op_num ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } @@ -1902,7 +1888,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSERT_CHECK_SPEC_HANDLER(ZEND if (RETURN_VALUE_USED(opline)) { ZVAL_TRUE(EX_VAR(opline->result.var)); } - ZEND_VM_JMP_NO_EXCEPTION(target); + ZEND_VM_JMP(target); } else { ZEND_VM_NEXT_OPCODE(); } @@ -2061,6 +2047,9 @@ call_trampoline_end: if (UNEXPECTED(EG(exception) != NULL)) { zend_throw_exception_internal(NULL); + if (RETURN_VALUE_USED(opline)) { + zval_ptr_dtor(EX_VAR(opline->result.var)); + } HANDLE_EXCEPTION_LEAVE(); } @@ -2702,7 +2691,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_SPEC_CONST_HANDLER(ZEND_O GET_OP1_UNDEF_CV(val, BP_VAR_R); ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); } else { - ZEND_VM_JMP_NO_EXCEPTION(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_CONTINUE(); } } @@ -2725,7 +2715,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPNZ_SPEC_CONST_HANDLER(ZEND_ val = EX_CONSTANT(opline->op1); if (Z_TYPE_INFO_P(val) == IS_TRUE) { - ZEND_VM_JMP_NO_EXCEPTION(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_CONTINUE(); } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { SAVE_OPLINE(); @@ -2758,12 +2749,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZNZ_SPEC_CONST_HANDLER(ZEND ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); ZEND_VM_CONTINUE(); } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { - SAVE_OPLINE(); - GET_OP1_UNDEF_CV(val, BP_VAR_R); + if (IS_CONST == IS_CV) { + if (UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { + SAVE_OPLINE(); + GET_OP1_UNDEF_CV(val, BP_VAR_R); + } ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); } else { - ZEND_VM_JMP_NO_EXCEPTION(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_CONTINUE(); } } @@ -2788,15 +2782,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_CONST_HANDLER(ZEN if (Z_TYPE_INFO_P(val) == IS_TRUE) { ZVAL_TRUE(EX_VAR(opline->result.var)); - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_SET_NEXT_OPCODE(opline + 1); + ZEND_VM_CONTINUE(); } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { ZVAL_FALSE(EX_VAR(opline->result.var)); - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { - SAVE_OPLINE(); - GET_OP1_UNDEF_CV(val, BP_VAR_R); + if (IS_CONST == IS_CV) { + if (UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { + SAVE_OPLINE(); + GET_OP1_UNDEF_CV(val, BP_VAR_R); + } ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); } else { - ZEND_VM_JMP_NO_EXCEPTION(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_CONTINUE(); } } @@ -2824,7 +2822,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPNZ_EX_SPEC_CONST_HANDLER(ZE if (Z_TYPE_INFO_P(val) == IS_TRUE) { ZVAL_TRUE(EX_VAR(opline->result.var)); - ZEND_VM_JMP_NO_EXCEPTION(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_CONTINUE(); } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { ZVAL_FALSE(EX_VAR(opline->result.var)); if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { @@ -3258,6 +3257,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_CONST_HANDLER(ZEND_ USE_OPLINE zval *obj; + zend_object *clone_obj; zend_class_entry *ce, *scope; zend_function *clone; zend_object_clone_obj_t clone_call; @@ -3322,7 +3322,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_CONST_HANDLER(ZEND_ } } - ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(obj)); + clone_obj = clone_call(obj); + if (EXPECTED(EG(exception) == NULL)) { + ZVAL_OBJ(EX_VAR(opline->result.var), clone_obj); + } else { + OBJ_RELEASE(clone_obj); + } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -3490,7 +3495,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CONST_HANDLER( } Z_FE_POS_P(result) = 0; - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } else if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) { if (!Z_OBJCE_P(array_ptr)->get_iterator) { HashPosition pos = 0; @@ -3640,7 +3645,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_CONST_HANDLER } Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(fe_ht, pos); - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } else if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) { if (!Z_OBJCE_P(array_ptr)->get_iterator) { if (IS_CONST == IS_VAR || IS_CONST == IS_CV) { @@ -3855,14 +3860,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COALESCE_SPEC_CONST_HANDLER(ZE Z_ADDREF_P(result); } } - if (UNEXPECTED(EG(exception))) { - zval_ptr_dtor_nogc(result); - HANDLE_EXCEPTION(); - } - ZEND_VM_JMP_NO_EXCEPTION(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); } - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -4890,7 +4891,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_ goto fetch_static_prop_return; } } - retval = zend_std_get_static_property(ce, name, 0); if (UNEXPECTED(retval == NULL)) { ZEND_ASSERT(EG(exception)); @@ -4900,7 +4900,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_ HANDLE_EXCEPTION(); } - if (IS_CONST == IS_CONST && retval) { CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); } @@ -6745,7 +6744,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_ goto fetch_static_prop_return; } } - retval = zend_std_get_static_property(ce, name, 0); if (UNEXPECTED(retval == NULL)) { ZEND_ASSERT(EG(exception)); @@ -6755,7 +6753,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_ HANDLE_EXCEPTION(); } - if (IS_CONST == IS_CONST && retval) { CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); } @@ -7136,11 +7133,9 @@ fetch_this: break; case BP_VAR_RW: case BP_VAR_W: - ZVAL_UNDEF(result); zend_throw_error(NULL, "Cannot re-assign $this"); break; case BP_VAR_UNSET: - ZVAL_UNDEF(result); zend_throw_error(NULL, "Cannot unset $this"); break; EMPTY_SWITCH_DEFAULT_CASE() @@ -7321,7 +7316,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_ goto fetch_static_prop_return; } } - retval = zend_std_get_static_property(ce, name, 0); if (UNEXPECTED(retval == NULL)) { ZEND_ASSERT(EG(exception)); @@ -7331,7 +7325,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_ HANDLE_EXCEPTION(); } - if (IS_CONST == IS_CONST && retval) { CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); } @@ -7622,6 +7615,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_CONST_ retval_ptr = retval_ref; } zend_verify_return_type(EX(func), retval_ptr, CACHE_ADDR(opline->op2.num)); + + if (UNEXPECTED(EG(exception) != NULL)) { + if (IS_CONST == IS_CONST) { + zval_ptr_dtor_nogc(retval_ptr); + } + } #endif } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -12804,7 +12803,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_TMP_HANDLER(ZE } Z_FE_POS_P(result) = 0; - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } else if (IS_TMP_VAR != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) { if (!Z_OBJCE_P(array_ptr)->get_iterator) { HashPosition pos = 0; @@ -12955,7 +12954,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_TMP_HANDLER(Z } Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(fe_ht, pos); - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } else if (IS_TMP_VAR != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) { if (!Z_OBJCE_P(array_ptr)->get_iterator) { if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) { @@ -13152,15 +13151,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COALESCE_SPEC_TMP_HANDLER(ZEND Z_ADDREF_P(result); } } - if (UNEXPECTED(EG(exception))) { - zval_ptr_dtor_nogc(result); - HANDLE_EXCEPTION(); - } - ZEND_VM_JMP_NO_EXCEPTION(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); } zval_ptr_dtor_nogc(free_op1); - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -14284,6 +14279,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_TMP_UN retval_ptr = retval_ref; } zend_verify_return_type(EX(func), retval_ptr, CACHE_ADDR(opline->op2.num)); + + if (UNEXPECTED(EG(exception) != NULL)) { + if (IS_TMP_VAR == IS_CONST) { + zval_ptr_dtor_nogc(retval_ptr); + } + } #endif } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -16363,7 +16364,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_VAR_HANDLER(ZE Z_FE_POS_P(result) = 0; zval_ptr_dtor_nogc(free_op1); - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } else if (IS_VAR != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) { if (!Z_OBJCE_P(array_ptr)->get_iterator) { HashPosition pos = 0; @@ -16516,7 +16517,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_VAR_HANDLER(Z Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(fe_ht, pos); if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } else if (IS_VAR != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) { if (!Z_OBJCE_P(array_ptr)->get_iterator) { if (IS_VAR == IS_VAR || IS_VAR == IS_CV) { @@ -17074,15 +17075,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COALESCE_SPEC_VAR_HANDLER(ZEND Z_ADDREF_P(result); } } - if (UNEXPECTED(EG(exception))) { - zval_ptr_dtor_nogc(result); - HANDLE_EXCEPTION(); - } - ZEND_VM_JMP_NO_EXCEPTION(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); } zval_ptr_dtor_nogc(free_op1); - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -17499,7 +17496,6 @@ assign_dim_op_convert_to_array: zend_check_string_offset(dim, BP_VAR_RW); zend_wrong_string_offset(); } - ZVAL_UNDEF(EX_VAR(opline->result.var)); } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { goto assign_dim_op_convert_to_array; } else { @@ -18807,7 +18803,7 @@ fast_assign_obj: Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -18963,7 +18959,7 @@ fast_assign_obj: Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } zval_ptr_dtor_nogc(free_op_data); @@ -19119,7 +19115,7 @@ fast_assign_obj: Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } zval_ptr_dtor_nogc(free_op_data); @@ -19275,7 +19271,7 @@ fast_assign_obj: Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -19337,7 +19333,7 @@ try_assign_dim_array: zend_assign_to_object_dim(object_ptr, dim, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -19428,7 +19424,7 @@ try_assign_dim_array: zend_assign_to_object_dim(object_ptr, dim, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -19520,7 +19516,7 @@ try_assign_dim_array: zend_assign_to_object_dim(object_ptr, dim, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -19612,7 +19608,7 @@ try_assign_dim_array: zend_assign_to_object_dim(object_ptr, dim, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -20914,7 +20910,6 @@ assign_dim_op_convert_to_array: zend_check_string_offset(dim, BP_VAR_RW); zend_wrong_string_offset(); } - ZVAL_UNDEF(EX_VAR(opline->result.var)); } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { goto assign_dim_op_convert_to_array; } else { @@ -21287,7 +21282,7 @@ try_assign_dim_array: zend_assign_to_object_dim(object_ptr, dim, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -21378,7 +21373,7 @@ try_assign_dim_array: zend_assign_to_object_dim(object_ptr, dim, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -21470,7 +21465,7 @@ try_assign_dim_array: zend_assign_to_object_dim(object_ptr, dim, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -21562,7 +21557,7 @@ try_assign_dim_array: zend_assign_to_object_dim(object_ptr, dim, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -21802,6 +21797,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_VAR_UN retval_ptr = retval_ref; } zend_verify_return_type(EX(func), retval_ptr, CACHE_ADDR(opline->op2.num)); + + if (UNEXPECTED(EG(exception) != NULL)) { + if (IS_VAR == IS_CONST) { + zval_ptr_dtor_nogc(retval_ptr); + } + } #endif } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -22280,7 +22281,6 @@ assign_dim_op_convert_to_array: zend_check_string_offset(dim, BP_VAR_RW); zend_wrong_string_offset(); } - ZVAL_UNDEF(EX_VAR(opline->result.var)); } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { goto assign_dim_op_convert_to_array; } else { @@ -23588,7 +23588,7 @@ fast_assign_obj: Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -23744,7 +23744,7 @@ fast_assign_obj: Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } zval_ptr_dtor_nogc(free_op_data); @@ -23900,7 +23900,7 @@ fast_assign_obj: Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } zval_ptr_dtor_nogc(free_op_data); @@ -24056,7 +24056,7 @@ fast_assign_obj: Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -24118,7 +24118,7 @@ try_assign_dim_array: zend_assign_to_object_dim(object_ptr, dim, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -24209,7 +24209,7 @@ try_assign_dim_array: zend_assign_to_object_dim(object_ptr, dim, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -24301,7 +24301,7 @@ try_assign_dim_array: zend_assign_to_object_dim(object_ptr, dim, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -24393,7 +24393,7 @@ try_assign_dim_array: zend_assign_to_object_dim(object_ptr, dim, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -25222,7 +25222,6 @@ assign_dim_op_convert_to_array: zend_check_string_offset(dim, BP_VAR_RW); zend_wrong_string_offset(); } - ZVAL_UNDEF(EX_VAR(opline->result.var)); } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { goto assign_dim_op_convert_to_array; } else { @@ -26535,7 +26534,7 @@ fast_assign_obj: Z_OBJ_HT_P(object)->write_property(object, property_name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -26691,7 +26690,7 @@ fast_assign_obj: Z_OBJ_HT_P(object)->write_property(object, property_name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } zval_ptr_dtor_nogc(free_op_data); @@ -26847,7 +26846,7 @@ fast_assign_obj: Z_OBJ_HT_P(object)->write_property(object, property_name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } zval_ptr_dtor_nogc(free_op_data); @@ -27003,7 +27002,7 @@ fast_assign_obj: Z_OBJ_HT_P(object)->write_property(object, property_name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -27065,7 +27064,7 @@ try_assign_dim_array: zend_assign_to_object_dim(object_ptr, dim, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -27156,7 +27155,7 @@ try_assign_dim_array: zend_assign_to_object_dim(object_ptr, dim, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -27248,7 +27247,7 @@ try_assign_dim_array: zend_assign_to_object_dim(object_ptr, dim, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -27340,7 +27339,7 @@ try_assign_dim_array: zend_assign_to_object_dim(object_ptr, dim, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -27867,6 +27866,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND USE_OPLINE zval *obj; + zend_object *clone_obj; zend_class_entry *ce, *scope; zend_function *clone; zend_object_clone_obj_t clone_call; @@ -27931,7 +27931,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND } } - ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(obj)); + clone_obj = clone_call(obj); + if (EXPECTED(EG(exception) == NULL)) { + ZVAL_OBJ(EX_VAR(opline->result.var), clone_obj); + } else { + OBJ_RELEASE(clone_obj); + } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -28810,7 +28815,7 @@ fast_assign_obj: Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -28966,7 +28971,7 @@ fast_assign_obj: Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } zval_ptr_dtor_nogc(free_op_data); @@ -29122,7 +29127,7 @@ fast_assign_obj: Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } zval_ptr_dtor_nogc(free_op_data); @@ -29278,7 +29283,7 @@ fast_assign_obj: Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -30446,6 +30451,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_UNUSED retval_ptr = retval_ref; } zend_verify_return_type(EX(func), retval_ptr, CACHE_ADDR(opline->op2.num)); + + if (UNEXPECTED(EG(exception) != NULL)) { + if (IS_UNUSED == IS_CONST) { + zval_ptr_dtor_nogc(retval_ptr); + } + } #endif } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -31490,7 +31501,7 @@ fast_assign_obj: Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -31646,7 +31657,7 @@ fast_assign_obj: Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } zval_ptr_dtor_nogc(free_op_data); @@ -31802,7 +31813,7 @@ fast_assign_obj: Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } zval_ptr_dtor_nogc(free_op_data); @@ -31958,7 +31969,7 @@ fast_assign_obj: Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -33382,7 +33393,7 @@ fast_assign_obj: Z_OBJ_HT_P(object)->write_property(object, property_name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -33538,7 +33549,7 @@ fast_assign_obj: Z_OBJ_HT_P(object)->write_property(object, property_name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } zval_ptr_dtor_nogc(free_op_data); @@ -33694,7 +33705,7 @@ fast_assign_obj: Z_OBJ_HT_P(object)->write_property(object, property_name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } zval_ptr_dtor_nogc(free_op_data); @@ -33850,7 +33861,7 @@ fast_assign_obj: Z_OBJ_HT_P(object)->write_property(object, property_name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -34596,7 +34607,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_SPEC_CV_HANDLER(ZEND_OPCO GET_OP1_UNDEF_CV(val, BP_VAR_R); ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); } else { - ZEND_VM_JMP_NO_EXCEPTION(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_CONTINUE(); } } @@ -34619,7 +34631,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPNZ_SPEC_CV_HANDLER(ZEND_OPC val = _get_zval_ptr_cv_undef(execute_data, opline->op1.var); if (Z_TYPE_INFO_P(val) == IS_TRUE) { - ZEND_VM_JMP_NO_EXCEPTION(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_CONTINUE(); } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { SAVE_OPLINE(); @@ -34652,12 +34665,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZNZ_SPEC_CV_HANDLER(ZEND_OP ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); ZEND_VM_CONTINUE(); } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { - SAVE_OPLINE(); - GET_OP1_UNDEF_CV(val, BP_VAR_R); + if (IS_CV == IS_CV) { + if (UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { + SAVE_OPLINE(); + GET_OP1_UNDEF_CV(val, BP_VAR_R); + } ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); } else { - ZEND_VM_JMP_NO_EXCEPTION(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_CONTINUE(); } } @@ -34682,15 +34698,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_CV_HANDLER(ZEND_O if (Z_TYPE_INFO_P(val) == IS_TRUE) { ZVAL_TRUE(EX_VAR(opline->result.var)); - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_SET_NEXT_OPCODE(opline + 1); + ZEND_VM_CONTINUE(); } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { ZVAL_FALSE(EX_VAR(opline->result.var)); - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { - SAVE_OPLINE(); - GET_OP1_UNDEF_CV(val, BP_VAR_R); + if (IS_CV == IS_CV) { + if (UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { + SAVE_OPLINE(); + GET_OP1_UNDEF_CV(val, BP_VAR_R); + } ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); } else { - ZEND_VM_JMP_NO_EXCEPTION(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_CONTINUE(); } } @@ -34718,7 +34738,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPNZ_EX_SPEC_CV_HANDLER(ZEND_ if (Z_TYPE_INFO_P(val) == IS_TRUE) { ZVAL_TRUE(EX_VAR(opline->result.var)); - ZEND_VM_JMP_NO_EXCEPTION(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_CONTINUE(); } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { ZVAL_FALSE(EX_VAR(opline->result.var)); if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { @@ -35168,6 +35189,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_CV_HANDLER(ZEND_OPC USE_OPLINE zval *obj; + zend_object *clone_obj; zend_class_entry *ce, *scope; zend_function *clone; zend_object_clone_obj_t clone_call; @@ -35232,7 +35254,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_CV_HANDLER(ZEND_OPC } } - ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(obj)); + clone_obj = clone_call(obj); + if (EXPECTED(EG(exception) == NULL)) { + ZVAL_OBJ(EX_VAR(opline->result.var), clone_obj); + } else { + OBJ_RELEASE(clone_obj); + } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -35400,7 +35427,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CV_HANDLER(ZEN } Z_FE_POS_P(result) = 0; - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } else if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) { if (!Z_OBJCE_P(array_ptr)->get_iterator) { HashPosition pos = 0; @@ -35550,7 +35577,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_CV_HANDLER(ZE } Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(fe_ht, pos); - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } else if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) { if (!Z_OBJCE_P(array_ptr)->get_iterator) { if (IS_CV == IS_VAR || IS_CV == IS_CV) { @@ -35765,14 +35792,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COALESCE_SPEC_CV_HANDLER(ZEND_ Z_ADDREF_P(result); } } - if (UNEXPECTED(EG(exception))) { - zval_ptr_dtor_nogc(result); - HANDLE_EXCEPTION(); - } - ZEND_VM_JMP_NO_EXCEPTION(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); } - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -36892,7 +36915,6 @@ assign_dim_op_convert_to_array: zend_check_string_offset(dim, BP_VAR_RW); zend_wrong_string_offset(); } - ZVAL_UNDEF(EX_VAR(opline->result.var)); } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { goto assign_dim_op_convert_to_array; } else { @@ -37853,7 +37875,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_ goto fetch_static_prop_return; } } - retval = zend_std_get_static_property(ce, name, 0); if (UNEXPECTED(retval == NULL)) { ZEND_ASSERT(EG(exception)); @@ -37863,7 +37884,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_ HANDLE_EXCEPTION(); } - if (IS_CV == IS_CONST && retval) { CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); } @@ -38474,7 +38494,7 @@ fast_assign_obj: Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -38630,7 +38650,7 @@ fast_assign_obj: Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } zval_ptr_dtor_nogc(free_op_data); @@ -38786,7 +38806,7 @@ fast_assign_obj: Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } zval_ptr_dtor_nogc(free_op_data); @@ -38942,7 +38962,7 @@ fast_assign_obj: Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -39004,7 +39024,7 @@ try_assign_dim_array: zend_assign_to_object_dim(object_ptr, dim, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -39095,7 +39115,7 @@ try_assign_dim_array: zend_assign_to_object_dim(object_ptr, dim, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -39187,7 +39207,7 @@ try_assign_dim_array: zend_assign_to_object_dim(object_ptr, dim, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -39279,7 +39299,7 @@ try_assign_dim_array: zend_assign_to_object_dim(object_ptr, dim, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -40915,7 +40935,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_ goto fetch_static_prop_return; } } - retval = zend_std_get_static_property(ce, name, 0); if (UNEXPECTED(retval == NULL)) { ZEND_ASSERT(EG(exception)); @@ -40925,7 +40944,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_ HANDLE_EXCEPTION(); } - if (IS_CV == IS_CONST && retval) { CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); } @@ -41482,7 +41500,6 @@ assign_dim_op_convert_to_array: zend_check_string_offset(dim, BP_VAR_RW); zend_wrong_string_offset(); } - ZVAL_UNDEF(EX_VAR(opline->result.var)); } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { goto assign_dim_op_convert_to_array; } else { @@ -41783,11 +41800,9 @@ fetch_this: break; case BP_VAR_RW: case BP_VAR_W: - ZVAL_UNDEF(result); zend_throw_error(NULL, "Cannot re-assign $this"); break; case BP_VAR_UNSET: - ZVAL_UNDEF(result); zend_throw_error(NULL, "Cannot unset $this"); break; EMPTY_SWITCH_DEFAULT_CASE() @@ -41968,7 +41983,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_ goto fetch_static_prop_return; } } - retval = zend_std_get_static_property(ce, name, 0); if (UNEXPECTED(retval == NULL)) { ZEND_ASSERT(EG(exception)); @@ -41978,7 +41992,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_ HANDLE_EXCEPTION(); } - if (IS_CV == IS_CONST && retval) { CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); } @@ -42156,7 +42169,7 @@ try_assign_dim_array: zend_assign_to_object_dim(object_ptr, dim, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -42247,7 +42260,7 @@ try_assign_dim_array: zend_assign_to_object_dim(object_ptr, dim, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -42339,7 +42352,7 @@ try_assign_dim_array: zend_assign_to_object_dim(object_ptr, dim, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -42431,7 +42444,7 @@ try_assign_dim_array: zend_assign_to_object_dim(object_ptr, dim, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -42516,6 +42529,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_CV_UNU retval_ptr = retval_ref; } zend_verify_return_type(EX(func), retval_ptr, CACHE_ADDR(opline->op2.num)); + + if (UNEXPECTED(EG(exception) != NULL)) { + if (IS_CV == IS_CONST) { + zval_ptr_dtor_nogc(retval_ptr); + } + } #endif } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -43947,7 +43966,6 @@ assign_dim_op_convert_to_array: zend_check_string_offset(dim, BP_VAR_RW); zend_wrong_string_offset(); } - ZVAL_UNDEF(EX_VAR(opline->result.var)); } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { goto assign_dim_op_convert_to_array; } else { @@ -45390,7 +45408,7 @@ fast_assign_obj: Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -45546,7 +45564,7 @@ fast_assign_obj: Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } zval_ptr_dtor_nogc(free_op_data); @@ -45702,7 +45720,7 @@ fast_assign_obj: Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } zval_ptr_dtor_nogc(free_op_data); @@ -45858,7 +45876,7 @@ fast_assign_obj: Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -45920,7 +45938,7 @@ try_assign_dim_array: zend_assign_to_object_dim(object_ptr, dim, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -46011,7 +46029,7 @@ try_assign_dim_array: zend_assign_to_object_dim(object_ptr, dim, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -46103,7 +46121,7 @@ try_assign_dim_array: zend_assign_to_object_dim(object_ptr, dim, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -46195,7 +46213,7 @@ try_assign_dim_array: zend_assign_to_object_dim(object_ptr, dim, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -48015,7 +48033,6 @@ assign_dim_op_convert_to_array: zend_check_string_offset(dim, BP_VAR_RW); zend_wrong_string_offset(); } - ZVAL_UNDEF(EX_VAR(opline->result.var)); } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { goto assign_dim_op_convert_to_array; } else { @@ -49464,7 +49481,7 @@ fast_assign_obj: Z_OBJ_HT_P(object)->write_property(object, property_name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -49620,7 +49637,7 @@ fast_assign_obj: Z_OBJ_HT_P(object)->write_property(object, property_name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } zval_ptr_dtor_nogc(free_op_data); @@ -49776,7 +49793,7 @@ fast_assign_obj: Z_OBJ_HT_P(object)->write_property(object, property_name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } zval_ptr_dtor_nogc(free_op_data); @@ -49932,7 +49949,7 @@ fast_assign_obj: Z_OBJ_HT_P(object)->write_property(object, property_name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -49994,7 +50011,7 @@ try_assign_dim_array: zend_assign_to_object_dim(object_ptr, dim, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -50085,7 +50102,7 @@ try_assign_dim_array: zend_assign_to_object_dim(object_ptr, dim, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -50177,7 +50194,7 @@ try_assign_dim_array: zend_assign_to_object_dim(object_ptr, dim, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -50269,7 +50286,7 @@ try_assign_dim_array: zend_assign_to_object_dim(object_ptr, dim, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -51137,7 +51154,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_SPEC_TMPVAR_HANDLER(ZEND_ GET_OP1_UNDEF_CV(val, BP_VAR_R); ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); } else { - ZEND_VM_JMP_NO_EXCEPTION(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_CONTINUE(); } } @@ -51160,7 +51178,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPNZ_SPEC_TMPVAR_HANDLER(ZEND val = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); if (Z_TYPE_INFO_P(val) == IS_TRUE) { - ZEND_VM_JMP_NO_EXCEPTION(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_CONTINUE(); } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { SAVE_OPLINE(); @@ -51193,12 +51212,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZNZ_SPEC_TMPVAR_HANDLER(ZEN ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); ZEND_VM_CONTINUE(); } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { - SAVE_OPLINE(); - GET_OP1_UNDEF_CV(val, BP_VAR_R); + if ((IS_TMP_VAR|IS_VAR) == IS_CV) { + if (UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { + SAVE_OPLINE(); + GET_OP1_UNDEF_CV(val, BP_VAR_R); + } ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); } else { - ZEND_VM_JMP_NO_EXCEPTION(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_CONTINUE(); } } @@ -51223,15 +51245,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_TMPVAR_HANDLER(ZE if (Z_TYPE_INFO_P(val) == IS_TRUE) { ZVAL_TRUE(EX_VAR(opline->result.var)); - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_SET_NEXT_OPCODE(opline + 1); + ZEND_VM_CONTINUE(); } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { ZVAL_FALSE(EX_VAR(opline->result.var)); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { - SAVE_OPLINE(); - GET_OP1_UNDEF_CV(val, BP_VAR_R); + if ((IS_TMP_VAR|IS_VAR) == IS_CV) { + if (UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { + SAVE_OPLINE(); + GET_OP1_UNDEF_CV(val, BP_VAR_R); + } ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); } else { - ZEND_VM_JMP_NO_EXCEPTION(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_CONTINUE(); } } @@ -51259,7 +51285,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPNZ_EX_SPEC_TMPVAR_HANDLER(Z if (Z_TYPE_INFO_P(val) == IS_TRUE) { ZVAL_TRUE(EX_VAR(opline->result.var)); - ZEND_VM_JMP_NO_EXCEPTION(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_CONTINUE(); } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { ZVAL_FALSE(EX_VAR(opline->result.var)); if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { @@ -51354,6 +51381,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_TMPVAR_HANDLER(ZEND USE_OPLINE zend_free_op free_op1; zval *obj; + zend_object *clone_obj; zend_class_entry *ce, *scope; zend_function *clone; zend_object_clone_obj_t clone_call; @@ -51418,7 +51446,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_TMPVAR_HANDLER(ZEND } } - ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(obj)); + clone_obj = clone_call(obj); + if (EXPECTED(EG(exception) == NULL)) { + ZVAL_OBJ(EX_VAR(opline->result.var), clone_obj); + } else { + OBJ_RELEASE(clone_obj); + } zval_ptr_dtor_nogc(free_op1); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -52299,7 +52332,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_ goto fetch_static_prop_return; } } - retval = zend_std_get_static_property(ce, name, 0); if (UNEXPECTED(retval == NULL)) { ZEND_ASSERT(EG(exception)); @@ -52309,7 +52341,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_ zval_ptr_dtor_nogc(free_op1); HANDLE_EXCEPTION(); } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && retval) { CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); } @@ -53250,7 +53281,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_ goto fetch_static_prop_return; } } - retval = zend_std_get_static_property(ce, name, 0); if (UNEXPECTED(retval == NULL)) { ZEND_ASSERT(EG(exception)); @@ -53260,7 +53290,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_ zval_ptr_dtor_nogc(free_op1); HANDLE_EXCEPTION(); } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && retval) { CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); } @@ -53557,11 +53586,9 @@ fetch_this: break; case BP_VAR_RW: case BP_VAR_W: - ZVAL_UNDEF(result); zend_throw_error(NULL, "Cannot re-assign $this"); break; case BP_VAR_UNSET: - ZVAL_UNDEF(result); zend_throw_error(NULL, "Cannot unset $this"); break; EMPTY_SWITCH_DEFAULT_CASE() @@ -53742,7 +53769,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_ goto fetch_static_prop_return; } } - retval = zend_std_get_static_property(ce, name, 0); if (UNEXPECTED(retval == NULL)) { ZEND_ASSERT(EG(exception)); @@ -53752,7 +53778,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_ zval_ptr_dtor_nogc(free_op1); HANDLE_EXCEPTION(); } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && retval) { CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); } diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php index 3b7e1d7d2d6..d379599a16c 100644 --- a/Zend/zend_vm_gen.php +++ b/Zend/zend_vm_gen.php @@ -1607,7 +1607,7 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name) out($f,"#endif\n"); out($f,"#undef HANDLE_EXCEPTION\n"); out($f,"#undef HANDLE_EXCEPTION_LEAVE\n"); - out($f,"#define HANDLE_EXCEPTION() ZEND_VM_UNDEF_RETVAL(); LOAD_OPLINE(); ZEND_VM_CONTINUE()\n"); + out($f,"#define HANDLE_EXCEPTION() LOAD_OPLINE(); ZEND_VM_CONTINUE()\n"); out($f,"#define HANDLE_EXCEPTION_LEAVE() LOAD_OPLINE(); ZEND_VM_LEAVE()\n"); out($f,"#if defined(ZEND_VM_FP_GLOBAL_REG)\n"); out($f,"# define ZEND_VM_ENTER() execute_data = EG(current_execute_data); LOAD_OPLINE(); ZEND_VM_INTERRUPT_CHECK(); ZEND_VM_CONTINUE()\n"); @@ -1646,7 +1646,7 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name) out($f,"#define SAVE_OPLINE() EX(opline) = opline\n"); out($f,"#undef HANDLE_EXCEPTION\n"); out($f,"#undef HANDLE_EXCEPTION_LEAVE\n"); - out($f,"#define HANDLE_EXCEPTION() ZEND_VM_UNDEF_RETVAL(); LOAD_OPLINE(); ZEND_VM_CONTINUE()\n"); + out($f,"#define HANDLE_EXCEPTION() LOAD_OPLINE(); ZEND_VM_CONTINUE()\n"); out($f,"#define HANDLE_EXCEPTION_LEAVE() LOAD_OPLINE(); ZEND_VM_LEAVE()\n"); out($f,"#define ZEND_VM_CONTINUE() goto zend_vm_continue\n"); out($f,"#define ZEND_VM_RETURN() return\n"); @@ -1678,10 +1678,10 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name) out($f,"#undef HANDLE_EXCEPTION\n"); out($f,"#undef HANDLE_EXCEPTION_LEAVE\n"); if (ZEND_VM_SPEC) { - out($f,"#define HANDLE_EXCEPTION() ZEND_VM_UNDEF_RETVAL(); goto ZEND_HANDLE_EXCEPTION_SPEC_HANDLER\n"); + out($f,"#define HANDLE_EXCEPTION() goto ZEND_HANDLE_EXCEPTION_SPEC_HANDLER\n"); out($f,"#define HANDLE_EXCEPTION_LEAVE() goto ZEND_HANDLE_EXCEPTION_SPEC_HANDLER\n"); } else { - out($f,"#define HANDLE_EXCEPTION() ZEND_VM_UNDEF_RETVAL(); goto ZEND_HANDLE_EXCEPTION_HANDLER\n"); + out($f,"#define HANDLE_EXCEPTION() goto ZEND_HANDLE_EXCEPTION_HANDLER\n"); out($f,"#define HANDLE_EXCEPTION_LEAVE() goto ZEND_HANDLE_EXCEPTION_HANDLER\n"); } out($f,"#define ZEND_VM_CONTINUE() goto *(void**)(OPLINE->handler)\n"); @@ -2441,7 +2441,7 @@ function gen_vm($def, $skel) { out($f,"#define SAVE_OPLINE()\n"); out($f,"#undef HANDLE_EXCEPTION\n"); out($f,"#undef HANDLE_EXCEPTION_LEAVE\n"); - out($f,"#define HANDLE_EXCEPTION() ZEND_VM_UNDEF_RETVAL(); LOAD_OPLINE(); ZEND_VM_CONTINUE()\n"); + out($f,"#define HANDLE_EXCEPTION() LOAD_OPLINE(); ZEND_VM_CONTINUE()\n"); out($f,"#define HANDLE_EXCEPTION_LEAVE() LOAD_OPLINE(); ZEND_VM_LEAVE()\n"); out($f,"#undef ZEND_VM_CONTINUE\n"); out($f,"#undef ZEND_VM_RETURN\n");