diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 83c6ba0e6ea..6380631cf0d 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -518,8 +518,12 @@ pub mod task { pub use alloc::task::*; } -// Platform-abstraction modules +// The runtime entry point and a few unstable public functions used by the +// compiler #[macro_use] +pub mod rt; + +// Platform-abstraction modules mod sys_common; mod sys; @@ -528,10 +532,6 @@ pub mod alloc; // Private support modules mod panicking; -// The runtime entry point and a few unstable public functions used by the -// compiler -pub mod rt; - #[path = "../../backtrace/src/lib.rs"] #[allow(dead_code, unused_attributes)] mod backtrace_rs; diff --git a/library/std/src/process.rs b/library/std/src/process.rs index c9b21fcf9c6..5c68400114d 100644 --- a/library/std/src/process.rs +++ b/library/std/src/process.rs @@ -1907,7 +1907,7 @@ impl Child { /// [platform-specific behavior]: #platform-specific-behavior #[stable(feature = "rust1", since = "1.0.0")] pub fn exit(code: i32) -> ! { - crate::sys_common::rt::cleanup(); + crate::rt::cleanup(); crate::sys::os::exit(code) } diff --git a/library/std/src/rt.rs b/library/std/src/rt.rs index 72e6c23ee49..8e38f98105b 100644 --- a/library/std/src/rt.rs +++ b/library/std/src/rt.rs @@ -13,10 +13,90 @@ issue = "none" )] #![doc(hidden)] +#![deny(unsafe_op_in_unsafe_fn)] +#![allow(unused_macros)] // Re-export some of our utilities which are expected by other crates. pub use crate::panicking::{begin_panic, begin_panic_fmt, panic_count}; +use crate::sync::Once; +use crate::sys; +use crate::sys_common::thread_info; +use crate::thread::Thread; + +// One-time runtime initialization. +// Runs before `main`. +// SAFETY: must be called only once during runtime initialization. +// NOTE: this is not guaranteed to run, for example when Rust code is called externally. +#[cfg_attr(test, allow(dead_code))] +unsafe fn init(argc: isize, argv: *const *const u8) { + unsafe { + sys::init(argc, argv); + + let main_guard = sys::thread::guard::init(); + // Next, set up the current Thread with the guard information we just + // created. Note that this isn't necessary in general for new threads, + // but we just do this to name the main thread and to give it correct + // info about the stack bounds. + let thread = Thread::new(Some("main".to_owned())); + thread_info::set(main_guard, thread); + } +} + +// One-time runtime cleanup. +// Runs after `main` or at program exit. +// NOTE: this is not guaranteed to run, for example when the program aborts. +pub(crate) fn cleanup() { + static CLEANUP: Once = Once::new(); + CLEANUP.call_once(|| unsafe { + // Flush stdout and disable buffering. + crate::io::cleanup(); + // SAFETY: Only called once during runtime cleanup. + sys::cleanup(); + }); +} + +// Prints to the "panic output", depending on the platform this may be: +// - the standard error output +// - some dedicated platform specific output +// - nothing (so this macro is a no-op) +macro_rules! rtprintpanic { + ($($t:tt)*) => { + if let Some(mut out) = crate::sys::stdio::panic_output() { + let _ = crate::io::Write::write_fmt(&mut out, format_args!($($t)*)); + } + } +} + +macro_rules! rtabort { + ($($t:tt)*) => { + { + rtprintpanic!("fatal runtime error: {}\n", format_args!($($t)*)); + crate::sys::abort_internal(); + } + } +} + +macro_rules! rtassert { + ($e:expr) => { + if !$e { + rtabort!(concat!("assertion failed: ", stringify!($e))); + } + }; +} + +macro_rules! rtunwrap { + ($ok:ident, $e:expr) => { + match $e { + $ok(v) => v, + ref err => { + let err = err.as_ref().map(drop); // map Ok/Some which might not be Debug + rtabort!(concat!("unwrap failed: ", stringify!($e), " = {:?}"), err) + } + } + }; +} + // To reduce the generated code of the new `lang_start`, this function is doing // the real work. #[cfg(not(test))] @@ -25,7 +105,7 @@ fn lang_start_internal( argc: isize, argv: *const *const u8, ) -> Result { - use crate::{mem, panic, sys, sys_common}; + use crate::{mem, panic}; let rt_abort = move |e| { mem::forget(e); rtabort!("initialization or cleanup bug"); @@ -41,14 +121,14 @@ fn lang_start_internal( // prevent libstd from accidentally introducing a panic to these functions. Another is from // user code from `main` or, more nefariously, as described in e.g. issue #86030. // SAFETY: Only called once during runtime initialization. - panic::catch_unwind(move || unsafe { sys_common::rt::init(argc, argv) }).map_err(rt_abort)?; + panic::catch_unwind(move || unsafe { init(argc, argv) }).map_err(rt_abort)?; let ret_code = panic::catch_unwind(move || panic::catch_unwind(main).unwrap_or(101) as isize) .map_err(move |e| { mem::forget(e); rtprintpanic!("drop of the panic payload panicked"); sys::abort_internal() }); - panic::catch_unwind(sys_common::rt::cleanup).map_err(rt_abort)?; + panic::catch_unwind(cleanup).map_err(rt_abort)?; ret_code } diff --git a/library/std/src/sys_common/mod.rs b/library/std/src/sys_common/mod.rs index 894440564b7..5a5913ebd79 100644 --- a/library/std/src/sys_common/mod.rs +++ b/library/std/src/sys_common/mod.rs @@ -28,8 +28,6 @@ pub mod memchr; pub mod mutex; pub mod process; pub mod remutex; -#[macro_use] -pub mod rt; pub mod rwlock; pub mod thread; pub mod thread_info; diff --git a/library/std/src/sys_common/rt.rs b/library/std/src/sys_common/rt.rs deleted file mode 100644 index 02013ecc4ce..00000000000 --- a/library/std/src/sys_common/rt.rs +++ /dev/null @@ -1,81 +0,0 @@ -#![deny(unsafe_op_in_unsafe_fn)] -#![allow(unused_macros)] - -use crate::sync::Once; -use crate::sys; -use crate::sys_common::thread_info; -use crate::thread::Thread; - -// One-time runtime initialization. -// Runs before `main`. -// SAFETY: must be called only once during runtime initialization. -// NOTE: this is not guaranteed to run, for example when Rust code is called externally. -#[cfg_attr(test, allow(dead_code))] -pub unsafe fn init(argc: isize, argv: *const *const u8) { - unsafe { - sys::init(argc, argv); - - let main_guard = sys::thread::guard::init(); - // Next, set up the current Thread with the guard information we just - // created. Note that this isn't necessary in general for new threads, - // but we just do this to name the main thread and to give it correct - // info about the stack bounds. - let thread = Thread::new(Some("main".to_owned())); - thread_info::set(main_guard, thread); - } -} - -// One-time runtime cleanup. -// Runs after `main` or at program exit. -// NOTE: this is not guaranteed to run, for example when the program aborts. -#[cfg_attr(test, allow(dead_code))] -pub fn cleanup() { - static CLEANUP: Once = Once::new(); - CLEANUP.call_once(|| unsafe { - // Flush stdout and disable buffering. - crate::io::cleanup(); - // SAFETY: Only called once during runtime cleanup. - sys::cleanup(); - }); -} - -// Prints to the "panic output", depending on the platform this may be: -// - the standard error output -// - some dedicated platform specific output -// - nothing (so this macro is a no-op) -macro_rules! rtprintpanic { - ($($t:tt)*) => { - if let Some(mut out) = crate::sys::stdio::panic_output() { - let _ = crate::io::Write::write_fmt(&mut out, format_args!($($t)*)); - } - } -} - -macro_rules! rtabort { - ($($t:tt)*) => { - { - rtprintpanic!("fatal runtime error: {}\n", format_args!($($t)*)); - crate::sys::abort_internal(); - } - } -} - -macro_rules! rtassert { - ($e:expr) => { - if !$e { - rtabort!(concat!("assertion failed: ", stringify!($e))); - } - }; -} - -macro_rules! rtunwrap { - ($ok:ident, $e:expr) => { - match $e { - $ok(v) => v, - ref err => { - let err = err.as_ref().map(drop); // map Ok/Some which might not be Debug - rtabort!(concat!("unwrap failed: ", stringify!($e), " = {:?}"), err) - } - } - }; -}