Simplify BEGIN_SILENCE/END_SILENCE to not modify ini entry value back and force

This commit is contained in:
Dmitry Stogov 2014-09-03 15:17:50 +04:00
parent d1b0066df7
commit 9a958a086d
4 changed files with 64 additions and 125 deletions

View 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;
}
/* }}} */

View 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;
};

View 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)) {

View 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();
}