]> granicus.if.org Git - php/commitdiff
Reimplemented silence operator (@) handling on exceptions. Now each silence region...
authorDmitry Stogov <dmitry@zend.com>
Wed, 26 Nov 2014 19:44:58 +0000 (22:44 +0300)
committerDmitry Stogov <dmitry@zend.com>
Wed, 26 Nov 2014 19:44:58 +0000 (22:44 +0300)
Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_execute.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h
ext/opcache/Optimizer/block_pass.c

index 6caa294448111e4d3ce46a4aab2694fd4daabd96..0905c3ce5f31f7fff3f404436cd3bb207caeefdf 100644 (file)
@@ -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;
 }
 /* }}} */
 
index f9a66a37d8086627c3e8f82dab522bf001b6ebe5..d6184c9dc33920cfb47c3a56e693095a1fef8d34 100644 (file)
@@ -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
index 6c8ebca70706bee511182e9acdb44b9d1974067f..fc8cd57cedb7cf851f7d3d38d968bd532645bfbc 100644 (file)
@@ -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);
index 223f43dda784ee8d49a6a1fc099caa666370555b..85342eaf43bfe1589d0adab62b248fee0c9814a5 100644 (file)
@@ -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);
index 52104843702bc97ce307eb0b0bd90d7aa5ad91eb..c80229f738f0efb799d4dcfded209b524d5025b6 100644 (file)
@@ -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();
 }
 
index 5c6880beeaf8d612c2b873f24f8244c99295ede3..6f3f1310a0f51df068a2aaf4bda7644748cb5be3 100644 (file)
@@ -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];
                                        }