diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 4fbdff3059d..a8ee529a809 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -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; } /* }}} */ diff --git a/Zend/zend_types.h b/Zend/zend_types.h index 368311aedb6..548bd5a2e07 100644 --- a/Zend/zend_types.h +++ b/Zend/zend_types.h @@ -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; }; diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index a1fbba752e4..fc8f28b47ef 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -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)) { diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 21189046161..fbbc46125a0 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -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(); }