mirror of
https://github.com/php/php-src.git
synced 2024-09-21 18:07:23 +00:00
Fix return value memory leaks upon exceptions in opcode operand freeing
This commit is contained in:
parent
c406d1e9b5
commit
9ad9d7ae37
@ -6,6 +6,7 @@ XORing strings
|
||||
$s = "123";
|
||||
$s1 = "test";
|
||||
$s2 = "45345some";
|
||||
$s3 = "f";
|
||||
|
||||
$s ^= 22;
|
||||
var_dump($s);
|
||||
@ -16,6 +17,9 @@ var_dump($s1);
|
||||
$s2 ^= 33;
|
||||
var_dump($s2);
|
||||
|
||||
$s3 ^= " ";
|
||||
var_dump($s3);
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
@ -26,4 +30,5 @@ int(11)
|
||||
|
||||
Notice: A non well formed numeric value encountered in %s on line %d
|
||||
int(45312)
|
||||
string(1) "F"
|
||||
Done
|
||||
|
19
Zend/tests/shift_003.phpt
Normal file
19
Zend/tests/shift_003.phpt
Normal file
@ -0,0 +1,19 @@
|
||||
--TEST--
|
||||
Test behavior of failing bitshift assign
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
try {
|
||||
$a = 1;
|
||||
$a >>= -1;
|
||||
} catch (Error $e) { var_dump($a); }
|
||||
|
||||
try {
|
||||
$a = 1;
|
||||
$a <<= -1;
|
||||
} catch (Error $e) { var_dump($a); }
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
int(1)
|
||||
int(1)
|
311
Zend/tests/temporary_cleaning_013.phpt
Normal file
311
Zend/tests/temporary_cleaning_013.phpt
Normal file
@ -0,0 +1,311 @@
|
||||
--TEST--
|
||||
Exceptions thrown in operand cleaning must cause leak of return value
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
try {
|
||||
var_dump(new class {
|
||||
function __toString() { return "a"; }
|
||||
function __destruct() { throw new Exception; }
|
||||
} . "foo");
|
||||
} catch (Exception $e) { print "caught Exception 1\n"; }
|
||||
|
||||
try {
|
||||
var_dump([0] + [new class {
|
||||
function __destruct() { throw new Exception; }
|
||||
}]);
|
||||
} catch (Exception $e) { print "caught Exception 2\n"; }
|
||||
|
||||
try {
|
||||
$foo = [0];
|
||||
var_dump($foo += [new class {
|
||||
function __destruct() { throw new Exception; }
|
||||
}]);
|
||||
} catch (Exception $e) { print "caught Exception 3\n"; }
|
||||
|
||||
try {
|
||||
$foo = (object)["foo" => [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
|
@ -1369,6 +1369,7 @@ 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;
|
||||
}
|
||||
|
||||
@ -1414,6 +1415,7 @@ 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;
|
||||
}
|
||||
|
||||
@ -1459,6 +1461,9 @@ 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) {
|
||||
@ -2941,12 +2946,16 @@ 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_SET_OPCODE(new_op); \
|
||||
ZEND_VM_CONTINUE(); \
|
||||
ZEND_VM_JMP_NO_EXCEPTION(new_op); \
|
||||
} while (0)
|
||||
|
||||
#define ZEND_VM_INC_OPCODE() \
|
||||
@ -3024,6 +3033,11 @@ 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)
|
||||
|
@ -926,6 +926,9 @@ 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 */
|
||||
}
|
||||
@ -968,6 +971,9 @@ 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 */
|
||||
}
|
||||
@ -1015,6 +1021,9 @@ 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 */
|
||||
}
|
||||
@ -1103,6 +1112,9 @@ 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;
|
||||
}
|
||||
@ -1168,6 +1180,9 @@ 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 */
|
||||
}
|
||||
@ -1182,10 +1197,6 @@ 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)) {
|
||||
@ -1193,10 +1204,16 @@ ZEND_API int ZEND_FASTCALL mod_function(zval *result, zval *op1, zval *op2) /* {
|
||||
} else {
|
||||
zend_error_noreturn(E_ERROR, "Modulo by zero");
|
||||
}
|
||||
ZVAL_UNDEF(result);
|
||||
if (op1 != 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);
|
||||
@ -1318,6 +1335,9 @@ 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;
|
||||
}
|
||||
@ -1344,6 +1364,9 @@ 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 {
|
||||
@ -1411,6 +1434,9 @@ 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 {
|
||||
@ -1478,6 +1504,9 @@ 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 {
|
||||
@ -1531,13 +1560,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 {
|
||||
@ -1546,11 +1575,17 @@ 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");
|
||||
}
|
||||
ZVAL_UNDEF(result);
|
||||
if (op1 != result) {
|
||||
ZVAL_UNDEF(result);
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (op1 == result) {
|
||||
zval_dtor(result);
|
||||
}
|
||||
|
||||
ZVAL_LONG(result, op1_lval << op2_lval);
|
||||
return SUCCESS;
|
||||
}
|
||||
@ -1562,13 +1597,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 {
|
||||
@ -1577,11 +1612,17 @@ 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");
|
||||
}
|
||||
ZVAL_UNDEF(result);
|
||||
if (op1 != result) {
|
||||
ZVAL_UNDEF(result);
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (op1 == result) {
|
||||
zval_dtor(result);
|
||||
}
|
||||
|
||||
ZVAL_LONG(result, op1_lval >> op2_lval);
|
||||
return SUCCESS;
|
||||
}
|
||||
@ -1589,7 +1630,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;
|
||||
zval op1_copy, op2_copy, orig_op1;
|
||||
int use_copy1 = 0, use_copy2 = 0;
|
||||
|
||||
do {
|
||||
@ -1605,10 +1646,12 @@ ZEND_API int ZEND_FASTCALL concat_function(zval *result, zval *op1, zval *op2) /
|
||||
* we have to free it.
|
||||
*/
|
||||
if (result == op1) {
|
||||
zval_dtor(op1);
|
||||
ZVAL_COPY_VALUE(&orig_op1, result);
|
||||
if (UNEXPECTED(op1 == op2)) {
|
||||
op2 = &op1_copy;
|
||||
}
|
||||
} else {
|
||||
ZVAL_UNDEF(&orig_op1);
|
||||
}
|
||||
op1 = &op1_copy;
|
||||
}
|
||||
@ -1636,7 +1679,19 @@ 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");
|
||||
ZVAL_FALSE(result);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
@ -1659,6 +1714,7 @@ 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);
|
||||
|
@ -893,6 +893,7 @@ 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 {
|
||||
@ -1554,9 +1555,11 @@ 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()
|
||||
@ -1737,6 +1740,7 @@ 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));
|
||||
@ -1746,6 +1750,7 @@ 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);
|
||||
}
|
||||
@ -2360,7 +2365,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)) && EXPECTED(!EG(exception))) {
|
||||
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
|
||||
ZVAL_COPY(EX_VAR(opline->result.var), value);
|
||||
}
|
||||
FREE_OP_DATA();
|
||||
@ -2422,7 +2427,7 @@ ZEND_VM_C_LABEL(try_assign_dim_array):
|
||||
|
||||
zend_assign_to_object_dim(object_ptr, dim, value);
|
||||
|
||||
if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) {
|
||||
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
|
||||
ZVAL_COPY(EX_VAR(opline->result.var), value);
|
||||
}
|
||||
|
||||
@ -2574,11 +2579,7 @@ 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();
|
||||
}
|
||||
|
||||
@ -2612,11 +2613,7 @@ 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();
|
||||
}
|
||||
|
||||
@ -2697,8 +2694,7 @@ 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_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
|
||||
ZEND_VM_CONTINUE();
|
||||
ZEND_VM_JMP_NO_EXCEPTION(OP_JMP_ADDR(opline, opline->op2));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2721,8 +2717,7 @@ 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_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
|
||||
ZEND_VM_CONTINUE();
|
||||
ZEND_VM_JMP_NO_EXCEPTION(OP_JMP_ADDR(opline, opline->op2));
|
||||
} 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();
|
||||
@ -2755,15 +2750,12 @@ 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) {
|
||||
if (UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
|
||||
SAVE_OPLINE();
|
||||
GET_OP1_UNDEF_CV(val, BP_VAR_R);
|
||||
}
|
||||
if (OP1_TYPE == IS_CV && 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_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
|
||||
ZEND_VM_CONTINUE();
|
||||
ZEND_VM_JMP_NO_EXCEPTION(OP_JMP_ADDR(opline, opline->op2));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2788,19 +2780,15 @@ 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_SET_NEXT_OPCODE(opline + 1);
|
||||
ZEND_VM_CONTINUE();
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
|
||||
ZVAL_FALSE(EX_VAR(opline->result.var));
|
||||
if (OP1_TYPE == IS_CV) {
|
||||
if (UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
|
||||
SAVE_OPLINE();
|
||||
GET_OP1_UNDEF_CV(val, BP_VAR_R);
|
||||
}
|
||||
if (OP1_TYPE == IS_CV && 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_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
|
||||
ZEND_VM_CONTINUE();
|
||||
ZEND_VM_JMP_NO_EXCEPTION(OP_JMP_ADDR(opline, opline->op2));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2828,8 +2816,7 @@ 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_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
|
||||
ZEND_VM_CONTINUE();
|
||||
ZEND_VM_JMP_NO_EXCEPTION(OP_JMP_ADDR(opline, opline->op2));
|
||||
} 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)) {
|
||||
@ -3942,12 +3929,6 @@ 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();
|
||||
@ -5019,7 +5000,6 @@ 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;
|
||||
@ -5084,12 +5064,7 @@ ZEND_VM_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|THIS|CV, ANY)
|
||||
}
|
||||
}
|
||||
|
||||
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_OBJ(EX_VAR(opline->result.var), clone_call(obj));
|
||||
|
||||
FREE_OP1();
|
||||
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
|
||||
@ -5745,7 +5720,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_CHECK_EXCEPTION();
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
} 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;
|
||||
@ -5898,7 +5873,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_CHECK_EXCEPTION();
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
} 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) {
|
||||
@ -6850,11 +6825,15 @@ ZEND_VM_HANDLER(169, ZEND_COALESCE, CONST|TMP|VAR|CV, JMP_ADDR)
|
||||
Z_ADDREF_P(result);
|
||||
}
|
||||
}
|
||||
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
|
||||
if (UNEXPECTED(EG(exception))) {
|
||||
zval_ptr_dtor_nogc(result);
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
ZEND_VM_JMP_NO_EXCEPTION(OP_JMP_ADDR(opline, opline->op2));
|
||||
}
|
||||
|
||||
FREE_OP1();
|
||||
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_HANDLER(22, ZEND_QM_ASSIGN, CONST|TMP|VAR|CV, ANY)
|
||||
@ -7217,7 +7196,8 @@ ZEND_VM_HELPER(zend_dispatch_try_catch_finally_helper, ANY, ANY, uint32_t try_ca
|
||||
|
||||
ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
|
||||
{
|
||||
uint32_t throw_op_num = EG(opline_before_exception) - EX(func)->op_array.opcodes;
|
||||
const zend_op *throw_op = EG(opline_before_exception);
|
||||
uint32_t throw_op_num = throw_op - EX(func)->op_array.opcodes;
|
||||
int i, current_try_catch_offset = -1;
|
||||
|
||||
{
|
||||
@ -7246,6 +7226,27 @@ 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);
|
||||
}
|
||||
|
||||
@ -7849,7 +7850,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(target);
|
||||
ZEND_VM_JMP_NO_EXCEPTION(target);
|
||||
} else {
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
@ -8008,9 +8009,6 @@ 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();
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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() LOAD_OPLINE(); ZEND_VM_CONTINUE()\n");
|
||||
out($f,"#define HANDLE_EXCEPTION() ZEND_VM_UNDEF_RETVAL(); 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() LOAD_OPLINE(); ZEND_VM_CONTINUE()\n");
|
||||
out($f,"#define HANDLE_EXCEPTION() ZEND_VM_UNDEF_RETVAL(); 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() goto ZEND_HANDLE_EXCEPTION_SPEC_HANDLER\n");
|
||||
out($f,"#define HANDLE_EXCEPTION() ZEND_VM_UNDEF_RETVAL(); 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() goto ZEND_HANDLE_EXCEPTION_HANDLER\n");
|
||||
out($f,"#define HANDLE_EXCEPTION() ZEND_VM_UNDEF_RETVAL(); 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() LOAD_OPLINE(); ZEND_VM_CONTINUE()\n");
|
||||
out($f,"#define HANDLE_EXCEPTION() ZEND_VM_UNDEF_RETVAL(); 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");
|
||||
|
Loading…
Reference in New Issue
Block a user