mirror of
https://github.com/php/php-src.git
synced 2024-11-28 04:14:26 +08:00
Reimplemented silence operator (@) handling on exceptions. Now each silence region is stored in op_array->brk_cont_array. On exception ZEND_HANDLE_EXCEPTION handler traverse this array and restore original EG(error_reporting) if exception occured inside a "silence" region.
This commit is contained in:
parent
d1c83ef6a4
commit
303d73ecd2
@ -5524,13 +5524,11 @@ void zend_compile_silence(znode *result, zend_ast *ast TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_ast *expr_ast = ast->child[0];
|
||||
znode silence_node;
|
||||
uint32_t opline_num;
|
||||
zend_op *begin_silence, *end_silence;
|
||||
uint32_t begin_opline_num, end_opline_num;
|
||||
zend_brk_cont_element *brk_cont_element;
|
||||
|
||||
opline_num = get_next_op_number(CG(active_op_array));
|
||||
begin_silence = zend_emit_op_tmp(&silence_node, ZEND_BEGIN_SILENCE, NULL, NULL TSRMLS_CC);
|
||||
/* pair BEGIN_SILENCE and END_SILENCE opcodes */
|
||||
begin_silence->op2.num = opline_num;
|
||||
begin_opline_num = get_next_op_number(CG(active_op_array));
|
||||
zend_emit_op_tmp(&silence_node, ZEND_BEGIN_SILENCE, NULL, NULL TSRMLS_CC);
|
||||
|
||||
if (expr_ast->kind == ZEND_AST_VAR) {
|
||||
/* For @$var we need to force a FETCH instruction, otherwise the CV access will
|
||||
@ -5540,9 +5538,15 @@ void zend_compile_silence(znode *result, zend_ast *ast TSRMLS_DC) /* {{{ */
|
||||
zend_compile_expr(result, expr_ast TSRMLS_CC);
|
||||
}
|
||||
|
||||
end_silence = zend_emit_op(NULL, ZEND_END_SILENCE, &silence_node, NULL TSRMLS_CC);
|
||||
/* pair BEGIN_SILENCE and END_SILENCE opcodes */
|
||||
end_silence->op2.num = opline_num;
|
||||
end_opline_num = get_next_op_number(CG(active_op_array));
|
||||
zend_emit_op(NULL, ZEND_END_SILENCE, &silence_node, NULL TSRMLS_CC);
|
||||
|
||||
/* Store BEGIN_SILENCE/END_SILENCE pair to restore previous
|
||||
* EG(error_reporting) value on exception */
|
||||
brk_cont_element = get_next_brk_cont_element(CG(active_op_array));
|
||||
brk_cont_element->start = begin_opline_num;
|
||||
brk_cont_element->cont = brk_cont_element->brk = end_opline_num;
|
||||
brk_cont_element->parent = -1;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
@ -378,8 +378,6 @@ struct _zend_execute_data {
|
||||
zend_array *symbol_table;
|
||||
const zend_op *fast_ret; /* used by FAST_CALL/FAST_RET (finally keyword) */
|
||||
zend_object *delayed_exception;
|
||||
uint32_t silence_op_num;
|
||||
uint32_t old_error_reporting;
|
||||
};
|
||||
|
||||
#define VM_FRAME_KIND_MASK 0x000000ff
|
||||
|
@ -1486,7 +1486,6 @@ static zend_always_inline void i_init_func_execute_data(zend_execute_data *execu
|
||||
EX(call) = NULL;
|
||||
EX(return_value) = return_value;
|
||||
EX(delayed_exception) = NULL;
|
||||
EX(silence_op_num) = -1;
|
||||
|
||||
/* Handle arguments */
|
||||
first_extra_arg = op_array->num_args;
|
||||
@ -1553,7 +1552,6 @@ static zend_always_inline void i_init_code_execute_data(zend_execute_data *execu
|
||||
EX(return_value) = return_value;
|
||||
EX(scope) = EG(scope);
|
||||
EX(delayed_exception) = NULL;
|
||||
EX(silence_op_num) = -1;
|
||||
|
||||
zend_attach_symbol_table(execute_data);
|
||||
|
||||
@ -1580,7 +1578,6 @@ static zend_always_inline void i_init_execute_data(zend_execute_data *execute_da
|
||||
EX(return_value) = return_value;
|
||||
EX(scope) = EG(scope);
|
||||
EX(delayed_exception) = NULL;
|
||||
EX(silence_op_num) = -1;
|
||||
|
||||
if (UNEXPECTED(EX(symbol_table) != NULL)) {
|
||||
zend_attach_symbol_table(execute_data);
|
||||
|
@ -5113,10 +5113,6 @@ ZEND_VM_HANDLER(57, ZEND_BEGIN_SILENCE, ANY, ANY)
|
||||
|
||||
SAVE_OPLINE();
|
||||
ZVAL_LONG(EX_VAR(opline->result.var), EG(error_reporting));
|
||||
if (EX(silence_op_num) == -1) {
|
||||
EX(silence_op_num) = opline->op2.num;
|
||||
EX(old_error_reporting) = EG(error_reporting);
|
||||
}
|
||||
|
||||
if (EG(error_reporting)) {
|
||||
do {
|
||||
@ -5154,9 +5150,6 @@ ZEND_VM_HANDLER(58, ZEND_END_SILENCE, TMP, ANY)
|
||||
if (!EG(error_reporting) && Z_LVAL_P(EX_VAR(opline->op1.var)) != 0) {
|
||||
EG(error_reporting) = Z_LVAL_P(EX_VAR(opline->op1.var));
|
||||
}
|
||||
if (EX(silence_op_num) == opline->op2.num) {
|
||||
EX(silence_op_num) = -1;
|
||||
}
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
@ -5522,17 +5515,16 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
|
||||
if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
|
||||
zval_ptr_dtor_nogc(EX_VAR(brk_opline->op1.var));
|
||||
}
|
||||
} else if (brk_opline->opcode == ZEND_END_SILENCE) {
|
||||
/* restore previous error_reporting value */
|
||||
if (!EG(error_reporting) && Z_LVAL_P(EX_VAR(brk_opline->op1.var)) != 0) {
|
||||
EG(error_reporting) = Z_LVAL_P(EX_VAR(brk_opline->op1.var));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* restore previous error_reporting value */
|
||||
if (!EG(error_reporting) && EX(silence_op_num) != -1 && EX(old_error_reporting) != 0) {
|
||||
EG(error_reporting) = EX(old_error_reporting);
|
||||
}
|
||||
EX(silence_op_num) = -1;
|
||||
|
||||
if (finally_op_num && (!catch_op_num || catch_op_num >= finally_op_num)) {
|
||||
if (EX(delayed_exception)) {
|
||||
zend_exception_set_previous(EG(exception), EX(delayed_exception) TSRMLS_CC);
|
||||
|
@ -1029,10 +1029,6 @@ static int ZEND_FASTCALL ZEND_BEGIN_SILENCE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_AR
|
||||
|
||||
SAVE_OPLINE();
|
||||
ZVAL_LONG(EX_VAR(opline->result.var), EG(error_reporting));
|
||||
if (EX(silence_op_num) == -1) {
|
||||
EX(silence_op_num) = opline->op2.num;
|
||||
EX(old_error_reporting) = EG(error_reporting);
|
||||
}
|
||||
|
||||
if (EG(error_reporting)) {
|
||||
do {
|
||||
@ -1264,17 +1260,16 @@ static int ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER
|
||||
if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
|
||||
zval_ptr_dtor_nogc(EX_VAR(brk_opline->op1.var));
|
||||
}
|
||||
} else if (brk_opline->opcode == ZEND_END_SILENCE) {
|
||||
/* restore previous error_reporting value */
|
||||
if (!EG(error_reporting) && Z_LVAL_P(EX_VAR(brk_opline->op1.var)) != 0) {
|
||||
EG(error_reporting) = Z_LVAL_P(EX_VAR(brk_opline->op1.var));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* restore previous error_reporting value */
|
||||
if (!EG(error_reporting) && EX(silence_op_num) != -1 && EX(old_error_reporting) != 0) {
|
||||
EG(error_reporting) = EX(old_error_reporting);
|
||||
}
|
||||
EX(silence_op_num) = -1;
|
||||
|
||||
if (finally_op_num && (!catch_op_num || catch_op_num >= finally_op_num)) {
|
||||
if (EX(delayed_exception)) {
|
||||
zend_exception_set_previous(EG(exception), EX(delayed_exception) TSRMLS_CC);
|
||||
@ -10251,9 +10246,6 @@ static int ZEND_FASTCALL ZEND_END_SILENCE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_
|
||||
if (!EG(error_reporting) && Z_LVAL_P(EX_VAR(opline->op1.var)) != 0) {
|
||||
EG(error_reporting) = Z_LVAL_P(EX_VAR(opline->op1.var));
|
||||
}
|
||||
if (EX(silence_op_num) == opline->op2.num) {
|
||||
EX(silence_op_num) = -1;
|
||||
}
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
|
@ -204,7 +204,8 @@ static int find_code_blocks(zend_op_array *op_array, zend_cfg *cfg, zend_optimiz
|
||||
j = 0;
|
||||
for (i = 0; i< op_array->last_brk_cont; i++) {
|
||||
if (op_array->brk_cont_array[i].start >= 0 &&
|
||||
op_array->opcodes[op_array->brk_cont_array[i].brk].opcode == ZEND_FREE) {
|
||||
(op_array->opcodes[op_array->brk_cont_array[i].brk].opcode == ZEND_FREE ||
|
||||
op_array->opcodes[op_array->brk_cont_array[i].brk].opcode == ZEND_END_SILENCE)) {
|
||||
int parent = op_array->brk_cont_array[i].parent;
|
||||
|
||||
while (parent >= 0 &&
|
||||
@ -223,7 +224,8 @@ static int find_code_blocks(zend_op_array *op_array, zend_cfg *cfg, zend_optimiz
|
||||
j = 0;
|
||||
for (i = 0; i< op_array->last_brk_cont; i++) {
|
||||
if (op_array->brk_cont_array[i].start >= 0 &&
|
||||
op_array->opcodes[op_array->brk_cont_array[i].brk].opcode == ZEND_FREE) {
|
||||
(op_array->opcodes[op_array->brk_cont_array[i].brk].opcode == ZEND_FREE ||
|
||||
op_array->opcodes[op_array->brk_cont_array[i].brk].opcode == ZEND_END_SILENCE)) {
|
||||
if (i != j) {
|
||||
op_array->brk_cont_array[j] = op_array->brk_cont_array[i];
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user