]> granicus.if.org Git - php/commitdiff
Simplify BEGIN_SILENCE/END_SILENCE to not modify ini entry value back and force
authorDmitry Stogov <dmitry@zend.com>
Wed, 3 Sep 2014 11:17:50 +0000 (15:17 +0400)
committerDmitry Stogov <dmitry@zend.com>
Wed, 3 Sep 2014 11:17:50 +0000 (15:17 +0400)
Zend/zend_compile.c
Zend/zend_types.h
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index 4fbdff3059df7085ba6f7b742cd5e9a74d5c2261..a8ee529a80998467269a35118b9f1024e08f02c5 100644 (file)
@@ -7096,8 +7096,13 @@ 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;
 
-       zend_emit_op_tmp(&silence_node, ZEND_BEGIN_SILENCE, NULL, NULL TSRMLS_CC);
+       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;
 
        if (expr_ast->kind == ZEND_AST_VAR) {
                /* For @$var we need to force a FETCH instruction, otherwise the CV access will
@@ -7107,7 +7112,9 @@ void zend_compile_silence(znode *result, zend_ast *ast TSRMLS_DC) /* {{{ */
                zend_compile_expr(result, expr_ast TSRMLS_CC);
        }
 
-       zend_emit_op(NULL, ZEND_END_SILENCE, &silence_node, NULL 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;
 }
 /* }}} */
 
index 368311aedb697084702ae5a293944f6046b8f26d..548bd5a2e0727cdddf9a613f117b076320443947 100644 (file)
@@ -134,7 +134,7 @@ struct _zval_struct {
                uint32_t     str_offset;           /* string offset */
                uint32_t     cache_slot;           /* literal cache slot */
                uint32_t     lineno;               /* line number (for ast nodes) */
-               int          error_reporting;      /* old error_reporting (@) */
+               uint32_t     silence_num;          /* BEGIN_SILENCE op number */
        } u2;
 };
 
index a1fbba752e46b5618ef3881ed95a1fa44b7e6a0d..fc8f28b47ef965ff936989fed70a0760f61efa7f 100644 (file)
@@ -5048,27 +5048,23 @@ ZEND_VM_HANDLER(57, ZEND_BEGIN_SILENCE, ANY, ANY)
        USE_OPLINE
 
        SAVE_OPLINE();
+       ZVAL_LONG(EX_VAR(opline->result.var), EG(error_reporting));
+       if (Z_TYPE(EX(old_error_reporting)) == IS_UNDEF) {
+               ZVAL_LONG(&EX(old_error_reporting), EG(error_reporting));
+               EX(old_error_reporting).u2.silence_num = opline->op2.num;
+       }
 
-       EX_VAR(opline->result.var)->u2.error_reporting = EG(error_reporting);
-       do {
-               if (!EG(error_reporting_ini_entry)) {
-                       zend_ini_entry *p = zend_hash_str_find_ptr(EG(ini_directives), "error_reporting", sizeof("error_reporting")-1);
-                       if (p) {
-                               EG(error_reporting_ini_entry) = p;
-                       } else {
-                               EG(error_reporting) = 0;
-                               break;
-                       }
-               }
-               ZVAL_NEW_STR(EX_VAR(opline->result.var), EG(error_reporting_ini_entry)->value);
-               if (EG(error_reporting_ini_entry)->value) {
-                       zend_string_addref(EG(error_reporting_ini_entry)->value);
-               }
-               if (Z_TYPE(EX(old_error_reporting)) == IS_UNDEF) {
-                       ZVAL_NEW_STR(&EX(old_error_reporting), EG(error_reporting_ini_entry)->value);
-               }
-               if (EG(error_reporting)) {
+       if (EG(error_reporting)) {
+               do {
                        EG(error_reporting) = 0;
+                       if (!EG(error_reporting_ini_entry)) {
+                               zend_ini_entry *p = zend_hash_str_find_ptr(EG(ini_directives), "error_reporting", sizeof("error_reporting")-1);
+                               if (p) {
+                                       EG(error_reporting_ini_entry) = p;
+                               } else {
+                                       break;
+                               }
+                       }
                        if (!EG(error_reporting_ini_entry)->modified) {
                                if (!EG(modified_ini_directives)) {
                                        ALLOC_HASHTABLE(EG(modified_ini_directives));
@@ -5079,16 +5075,10 @@ ZEND_VM_HANDLER(57, ZEND_BEGIN_SILENCE, ANY, ANY)
                                        EG(error_reporting_ini_entry)->orig_modifiable = EG(error_reporting_ini_entry)->modifiable;
                                        EG(error_reporting_ini_entry)->modified = 1;
                                }
-                       } else if (EG(error_reporting_ini_entry)->value != EG(error_reporting_ini_entry)->orig_value) {
-                               zend_string_release(EG(error_reporting_ini_entry)->value);
-                       }
-                       if (CG(one_char_string)['0']) {
-                               EG(error_reporting_ini_entry)->value = CG(one_char_string)['0'];
-                       } else {
-                               EG(error_reporting_ini_entry)->value = zend_string_init("0", sizeof("0")-1, 0);
                        }
-               }
-       } while (0);
+               } while (0);
+       }
+       CHECK_EXCEPTION();
        ZEND_VM_NEXT_OPCODE();
 }
 
@@ -5104,27 +5094,12 @@ ZEND_VM_HANDLER(58, ZEND_END_SILENCE, TMP, ANY)
        USE_OPLINE
 
        SAVE_OPLINE();
-       if (!EG(error_reporting)) {
-               EG(error_reporting) = EX_VAR(opline->op1.var)->u2.error_reporting;
-               if (EXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) == IS_STRING)) {
-                       if (EXPECTED(EG(error_reporting_ini_entry)->modified &&
-                           EG(error_reporting_ini_entry)->value != EG(error_reporting_ini_entry)->orig_value)) {
-                               zend_string_release(EG(error_reporting_ini_entry)->value);
-                       }
-                       EG(error_reporting_ini_entry)->value = Z_STR_P(EX_VAR(opline->op1.var));
-                       if (Z_TYPE(EX(old_error_reporting)) != IS_UNDEF &&
-                           Z_STR(EX(old_error_reporting)) == EG(error_reporting_ini_entry)->value) {
-                               ZVAL_UNDEF(&EX(old_error_reporting));
-                       }
-               }
-       } else {
-               if (EXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) == IS_STRING)) {
-                       zend_string_release(Z_STR_P(EX_VAR(opline->op1.var)));
-                       if (Z_TYPE(EX(old_error_reporting)) != IS_UNDEF &&
-                           Z_STR(EX(old_error_reporting)) == Z_STR_P(EX_VAR(opline->op1.var))) {
-                               ZVAL_UNDEF(&EX(old_error_reporting));
-                       }
-               }
+       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 (Z_TYPE(EX(old_error_reporting)) != IS_UNDEF &&
+               EX(old_error_reporting).u2.silence_num == opline->op2.num) {
+               ZVAL_UNDEF(&EX(old_error_reporting));
        }
        ZEND_VM_NEXT_OPCODE();
 }
@@ -5481,19 +5456,10 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
        }
 
        /* restore previous error_reporting value */
-       if (Z_TYPE(EX(old_error_reporting)) != IS_UNDEF) {
-               if (!EG(error_reporting)) {
-                       zend_string *key;
-
-                       key = zend_string_init("error_reporting", sizeof("error_reporting")-1, 0);
-                       zend_alter_ini_entry_ex(key, Z_STR(EX(old_error_reporting)), ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME, 1 TSRMLS_CC);
-                       zend_string_free(key);
-               }
-               if (Z_STR(EX(old_error_reporting))) {
-                       zend_string_release(Z_STR(EX(old_error_reporting)));
-               }
-               ZVAL_UNDEF(&EX(old_error_reporting));
+       if (!EG(error_reporting) && Z_TYPE(EX(old_error_reporting)) != IS_UNDEF && Z_LVAL(EX(old_error_reporting)) != 0) {
+               EG(error_reporting) = Z_LVAL(EX(old_error_reporting));
        }
+       ZVAL_UNDEF(&EX(old_error_reporting));
 
        if (finally_op_num && (!catch_op_num || catch_op_num >= finally_op_num)) {
                if (EX(delayed_exception)) {
index 211890461614b34dcc792a0d8cb59c22f5631433..fbbc46125a048142b36ee5fcb3ba2a3ad24e3212 100644 (file)
@@ -1108,27 +1108,23 @@ static int ZEND_FASTCALL  ZEND_BEGIN_SILENCE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_AR
        USE_OPLINE
 
        SAVE_OPLINE();
+       ZVAL_LONG(EX_VAR(opline->result.var), EG(error_reporting));
+       if (Z_TYPE(EX(old_error_reporting)) == IS_UNDEF) {
+               ZVAL_LONG(&EX(old_error_reporting), EG(error_reporting));
+               EX(old_error_reporting).u2.silence_num = opline->op2.num;
+       }
 
-       EX_VAR(opline->result.var)->u2.error_reporting = EG(error_reporting);
-       do {
-               if (!EG(error_reporting_ini_entry)) {
-                       zend_ini_entry *p = zend_hash_str_find_ptr(EG(ini_directives), "error_reporting", sizeof("error_reporting")-1);
-                       if (p) {
-                               EG(error_reporting_ini_entry) = p;
-                       } else {
-                               EG(error_reporting) = 0;
-                               break;
-                       }
-               }
-               ZVAL_NEW_STR(EX_VAR(opline->result.var), EG(error_reporting_ini_entry)->value);
-               if (EG(error_reporting_ini_entry)->value) {
-                       zend_string_addref(EG(error_reporting_ini_entry)->value);
-               }
-               if (Z_TYPE(EX(old_error_reporting)) == IS_UNDEF) {
-                       ZVAL_NEW_STR(&EX(old_error_reporting), EG(error_reporting_ini_entry)->value);
-               }
-               if (EG(error_reporting)) {
+       if (EG(error_reporting)) {
+               do {
                        EG(error_reporting) = 0;
+                       if (!EG(error_reporting_ini_entry)) {
+                               zend_ini_entry *p = zend_hash_str_find_ptr(EG(ini_directives), "error_reporting", sizeof("error_reporting")-1);
+                               if (p) {
+                                       EG(error_reporting_ini_entry) = p;
+                               } else {
+                                       break;
+                               }
+                       }
                        if (!EG(error_reporting_ini_entry)->modified) {
                                if (!EG(modified_ini_directives)) {
                                        ALLOC_HASHTABLE(EG(modified_ini_directives));
@@ -1139,16 +1135,10 @@ static int ZEND_FASTCALL  ZEND_BEGIN_SILENCE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_AR
                                        EG(error_reporting_ini_entry)->orig_modifiable = EG(error_reporting_ini_entry)->modifiable;
                                        EG(error_reporting_ini_entry)->modified = 1;
                                }
-                       } else if (EG(error_reporting_ini_entry)->value != EG(error_reporting_ini_entry)->orig_value) {
-                               zend_string_release(EG(error_reporting_ini_entry)->value);
-                       }
-                       if (CG(one_char_string)['0']) {
-                               EG(error_reporting_ini_entry)->value = CG(one_char_string)['0'];
-                       } else {
-                               EG(error_reporting_ini_entry)->value = zend_string_init("0", sizeof("0")-1, 0);
                        }
-               }
-       } while (0);
+               } while (0);
+       }
+       CHECK_EXCEPTION();
        ZEND_VM_NEXT_OPCODE();
 }
 
@@ -1371,19 +1361,10 @@ static int ZEND_FASTCALL  ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER
        }
 
        /* restore previous error_reporting value */
-       if (Z_TYPE(EX(old_error_reporting)) != IS_UNDEF) {
-               if (!EG(error_reporting)) {
-                       zend_string *key;
-
-                       key = zend_string_init("error_reporting", sizeof("error_reporting")-1, 0);
-                       zend_alter_ini_entry_ex(key, Z_STR(EX(old_error_reporting)), ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME, 1 TSRMLS_CC);
-                       zend_string_free(key);
-               }
-               if (Z_STR(EX(old_error_reporting))) {
-                       zend_string_release(Z_STR(EX(old_error_reporting)));
-               }
-               ZVAL_UNDEF(&EX(old_error_reporting));
+       if (!EG(error_reporting) && Z_TYPE(EX(old_error_reporting)) != IS_UNDEF && Z_LVAL(EX(old_error_reporting)) != 0) {
+               EG(error_reporting) = Z_LVAL(EX(old_error_reporting));
        }
+       ZVAL_UNDEF(&EX(old_error_reporting));
 
        if (finally_op_num && (!catch_op_num || catch_op_num >= finally_op_num)) {
                if (EX(delayed_exception)) {
@@ -10039,27 +10020,12 @@ static int ZEND_FASTCALL  ZEND_END_SILENCE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_
        USE_OPLINE
 
        SAVE_OPLINE();
-       if (!EG(error_reporting)) {
-               EG(error_reporting) = EX_VAR(opline->op1.var)->u2.error_reporting;
-               if (EXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) == IS_STRING)) {
-                       if (EXPECTED(EG(error_reporting_ini_entry)->modified &&
-                           EG(error_reporting_ini_entry)->value != EG(error_reporting_ini_entry)->orig_value)) {
-                               zend_string_release(EG(error_reporting_ini_entry)->value);
-                       }
-                       EG(error_reporting_ini_entry)->value = Z_STR_P(EX_VAR(opline->op1.var));
-                       if (Z_TYPE(EX(old_error_reporting)) != IS_UNDEF &&
-                           Z_STR(EX(old_error_reporting)) == EG(error_reporting_ini_entry)->value) {
-                               ZVAL_UNDEF(&EX(old_error_reporting));
-                       }
-               }
-       } else {
-               if (EXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) == IS_STRING)) {
-                       zend_string_release(Z_STR_P(EX_VAR(opline->op1.var)));
-                       if (Z_TYPE(EX(old_error_reporting)) != IS_UNDEF &&
-                           Z_STR(EX(old_error_reporting)) == Z_STR_P(EX_VAR(opline->op1.var))) {
-                               ZVAL_UNDEF(&EX(old_error_reporting));
-                       }
-               }
+       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 (Z_TYPE(EX(old_error_reporting)) != IS_UNDEF &&
+               EX(old_error_reporting).u2.silence_num == opline->op2.num) {
+               ZVAL_UNDEF(&EX(old_error_reporting));
        }
        ZEND_VM_NEXT_OPCODE();
 }