13
13
issue = "none"
14
14
) ]
15
15
#![ doc( hidden) ]
16
+ #![ deny( unsafe_op_in_unsafe_fn) ]
17
+ #![ allow( unused_macros) ]
16
18
17
19
// Re-export some of our utilities which are expected by other crates.
18
20
pub use crate :: panicking:: { begin_panic, begin_panic_fmt, panic_count} ;
19
21
22
+ use crate :: sync:: Once ;
23
+ use crate :: sys;
24
+ use crate :: sys_common:: thread_info;
25
+ use crate :: thread:: Thread ;
26
+
27
+ // One-time runtime initialization.
28
+ // Runs before `main`.
29
+ // SAFETY: must be called only once during runtime initialization.
30
+ // NOTE: this is not guaranteed to run, for example when Rust code is called externally.
31
+ #[ cfg_attr( test, allow( dead_code) ) ]
32
+ unsafe fn init ( argc : isize , argv : * const * const u8 ) {
33
+ unsafe {
34
+ sys:: init ( argc, argv) ;
35
+
36
+ let main_guard = sys:: thread:: guard:: init ( ) ;
37
+ // Next, set up the current Thread with the guard information we just
38
+ // created. Note that this isn't necessary in general for new threads,
39
+ // but we just do this to name the main thread and to give it correct
40
+ // info about the stack bounds.
41
+ let thread = Thread :: new ( Some ( "main" . to_owned ( ) ) ) ;
42
+ thread_info:: set ( main_guard, thread) ;
43
+ }
44
+ }
45
+
46
+ // One-time runtime cleanup.
47
+ // Runs after `main` or at program exit.
48
+ // NOTE: this is not guaranteed to run, for example when the program aborts.
49
+ pub ( crate ) fn cleanup ( ) {
50
+ static CLEANUP : Once = Once :: new ( ) ;
51
+ CLEANUP . call_once ( || unsafe {
52
+ // Flush stdout and disable buffering.
53
+ crate :: io:: cleanup ( ) ;
54
+ // SAFETY: Only called once during runtime cleanup.
55
+ sys:: cleanup ( ) ;
56
+ } ) ;
57
+ }
58
+
59
+ // Prints to the "panic output", depending on the platform this may be:
60
+ // - the standard error output
61
+ // - some dedicated platform specific output
62
+ // - nothing (so this macro is a no-op)
63
+ macro_rules! rtprintpanic {
64
+ ( $( $t: tt) * ) => {
65
+ if let Some ( mut out) = crate :: sys:: stdio:: panic_output( ) {
66
+ let _ = crate :: io:: Write :: write_fmt( & mut out, format_args!( $( $t) * ) ) ;
67
+ }
68
+ }
69
+ }
70
+
71
+ macro_rules! rtabort {
72
+ ( $( $t: tt) * ) => {
73
+ {
74
+ rtprintpanic!( "fatal runtime error: {}\n " , format_args!( $( $t) * ) ) ;
75
+ crate :: sys:: abort_internal( ) ;
76
+ }
77
+ }
78
+ }
79
+
80
+ macro_rules! rtassert {
81
+ ( $e: expr) => {
82
+ if !$e {
83
+ rtabort!( concat!( "assertion failed: " , stringify!( $e) ) ) ;
84
+ }
85
+ } ;
86
+ }
87
+
88
+ macro_rules! rtunwrap {
89
+ ( $ok: ident, $e: expr) => {
90
+ match $e {
91
+ $ok( v) => v,
92
+ ref err => {
93
+ let err = err. as_ref( ) . map( drop) ; // map Ok/Some which might not be Debug
94
+ rtabort!( concat!( "unwrap failed: " , stringify!( $e) , " = {:?}" ) , err)
95
+ }
96
+ }
97
+ } ;
98
+ }
99
+
20
100
// To reduce the generated code of the new `lang_start`, this function is doing
21
101
// the real work.
22
102
#[ cfg( not( test) ) ]
@@ -25,7 +105,7 @@ fn lang_start_internal(
25
105
argc : isize ,
26
106
argv : * const * const u8 ,
27
107
) -> Result < isize , !> {
28
- use crate :: { mem, panic, sys , sys_common } ;
108
+ use crate :: { mem, panic} ;
29
109
let rt_abort = move |e| {
30
110
mem:: forget ( e) ;
31
111
rtabort ! ( "initialization or cleanup bug" ) ;
@@ -41,14 +121,14 @@ fn lang_start_internal(
41
121
// prevent libstd from accidentally introducing a panic to these functions. Another is from
42
122
// user code from `main` or, more nefariously, as described in e.g. issue #86030.
43
123
// SAFETY: Only called once during runtime initialization.
44
- panic:: catch_unwind ( move || unsafe { sys_common :: rt :: init ( argc, argv) } ) . map_err ( rt_abort) ?;
124
+ panic:: catch_unwind ( move || unsafe { init ( argc, argv) } ) . map_err ( rt_abort) ?;
45
125
let ret_code = panic:: catch_unwind ( move || panic:: catch_unwind ( main) . unwrap_or ( 101 ) as isize )
46
126
. map_err ( move |e| {
47
127
mem:: forget ( e) ;
48
128
rtprintpanic ! ( "drop of the panic payload panicked" ) ;
49
129
sys:: abort_internal ( )
50
130
} ) ;
51
- panic:: catch_unwind ( sys_common :: rt :: cleanup) . map_err ( rt_abort) ?;
131
+ panic:: catch_unwind ( cleanup) . map_err ( rt_abort) ?;
52
132
ret_code
53
133
}
54
134
0 commit comments