Skip to content

Commit

Permalink
std: Internalize almost all of std::rt
Browse files Browse the repository at this point in the history
This commit does some refactoring to make almost all of the `std::rt` private.
Specifically, the following items are no longer part of its API:

* DEFAULT_ERROR_CODE
* backtrace
* unwind
* args
* at_exit
* cleanup
* heap (this is just alloc::heap)
* min_stack
* util

The module is now tagged as `#[doc(hidden)]` as the only purpose it's serve is
an entry point for the `panic!` macro via the `begin_unwind` and
`begin_unwind_fmt` reexports.
  • Loading branch information
alexcrichton committed Sep 11, 2015
1 parent 192c375 commit f4be202
Show file tree
Hide file tree
Showing 33 changed files with 272 additions and 431 deletions.
24 changes: 18 additions & 6 deletions src/doc/nomicon/destructors.md
Expand Up @@ -26,13 +26,16 @@ this is totally fine.
For instance, a custom implementation of `Box` might write `Drop` like this:

```rust
#![feature(heap_api, core_intrinsics, unique)]
#![feature(alloc, heap_api, core_intrinsics, unique)]

extern crate alloc;

use std::rt::heap;
use std::ptr::Unique;
use std::intrinsics::drop_in_place;
use std::mem;

use alloc::heap;

struct Box<T>{ ptr: Unique<T> }

impl<T> Drop for Box<T> {
Expand All @@ -45,6 +48,7 @@ impl<T> Drop for Box<T> {
}
}
}
# fn main() {}
```

and this works fine because when Rust goes to drop the `ptr` field it just sees
Expand All @@ -54,13 +58,16 @@ use-after-free the `ptr` because when drop exits, it becomes inacessible.
However this wouldn't work:

```rust
#![feature(heap_api, core_intrinsics, unique)]
#![feature(alloc, heap_api, core_intrinsics, unique)]

extern crate alloc;

use std::rt::heap;
use std::ptr::Unique;
use std::intrinsics::drop_in_place;
use std::mem;

use alloc::heap;

struct Box<T>{ ptr: Unique<T> }

impl<T> Drop for Box<T> {
Expand All @@ -87,6 +94,7 @@ impl<T> Drop for SuperBox<T> {
}
}
}
# fn main() {}
```

After we deallocate the `box`'s ptr in SuperBox's destructor, Rust will
Expand Down Expand Up @@ -129,13 +137,16 @@ The classic safe solution to overriding recursive drop and allowing moving out
of Self during `drop` is to use an Option:

```rust
#![feature(heap_api, core_intrinsics, unique)]
#![feature(alloc, heap_api, core_intrinsics, unique)]

extern crate alloc;

use std::rt::heap;
use std::ptr::Unique;
use std::intrinsics::drop_in_place;
use std::mem;

use alloc::heap;

struct Box<T>{ ptr: Unique<T> }

impl<T> Drop for Box<T> {
Expand Down Expand Up @@ -165,6 +176,7 @@ impl<T> Drop for SuperBox<T> {
}
}
}
# fn main() {}
```

However this has fairly odd semantics: you're saying that a field that *should*
Expand Down
7 changes: 4 additions & 3 deletions src/doc/nomicon/vec-alloc.md
Expand Up @@ -9,7 +9,7 @@ This is perfectly fine because we already have `cap == 0` as our sentinel for no
allocation. We don't even need to handle it specially in almost any code because
we usually need to check if `cap > len` or `len > 0` anyway. The traditional
Rust value to put here is `0x01`. The standard library actually exposes this
as `std::rt::heap::EMPTY`. There are quite a few places where we'll
as `alloc::heap::EMPTY`. There are quite a few places where we'll
want to use `heap::EMPTY` because there's no real allocation to talk about but
`null` would make the compiler do bad things.

Expand All @@ -20,11 +20,12 @@ the `heap` API anyway, so let's just get that dependency over with.
So:

```rust,ignore
#![feature(heap_api)]
#![feature(alloc, heap_api)]
use std::rt::heap::EMPTY;
use std::mem;
use alloc::heap::EMPTY;
impl<T> Vec<T> {
fn new() -> Self {
assert!(mem::size_of::<T>() != 0, "We're not ready to handle ZSTs");
Expand Down
9 changes: 4 additions & 5 deletions src/doc/nomicon/vec-final.md
Expand Up @@ -2,17 +2,16 @@

```rust
#![feature(unique)]
#![feature(heap_api)]
#![feature(alloc, heap_api)]

extern crate alloc;

use std::ptr::{Unique, self};
use std::rt::heap;
use std::mem;
use std::ops::{Deref, DerefMut};
use std::marker::PhantomData;




use alloc::heap;

struct RawVec<T> {
ptr: Unique<T>,
Expand Down
3 changes: 2 additions & 1 deletion src/libarena/lib.rs
Expand Up @@ -49,7 +49,8 @@ use std::marker;
use std::mem;
use std::ptr;
use std::rc::Rc;
use std::rt::heap::{allocate, deallocate};

use alloc::heap::{allocate, deallocate};

// The way arena uses arrays is really deeply awful. The arrays are
// allocated, and have capacities reserved, but the fill for the array
Expand Down
19 changes: 0 additions & 19 deletions src/liblog/lib.rs
Expand Up @@ -174,7 +174,6 @@
#![feature(box_syntax)]
#![feature(const_fn)]
#![feature(iter_cmp)]
#![feature(rt)]
#![feature(staged_api)]
#![feature(static_mutex)]

Expand All @@ -185,7 +184,6 @@ use std::io::prelude::*;
use std::mem;
use std::env;
use std::ptr;
use std::rt;
use std::slice;
use std::sync::{Once, StaticMutex};

Expand Down Expand Up @@ -292,7 +290,6 @@ pub fn log(level: u32, loc: &'static LogLocation, args: fmt::Arguments) {
let _g = LOCK.lock();
match FILTER as usize {
0 => {}
1 => panic!("cannot log after main thread has exited"),
n => {
let filter = mem::transmute::<_, &String>(n);
if !args.to_string().contains(filter) {
Expand Down Expand Up @@ -385,9 +382,6 @@ pub fn mod_enabled(level: u32, module: &str) -> bool {
let _g = LOCK.lock();
unsafe {
assert!(DIRECTIVES as usize != 0);
assert!(DIRECTIVES as usize != 1,
"cannot log after the main thread has exited");

enabled(level, module, (*DIRECTIVES).iter())
}
}
Expand Down Expand Up @@ -442,19 +436,6 @@ fn init() {

assert!(DIRECTIVES.is_null());
DIRECTIVES = Box::into_raw(box directives);

// Schedule the cleanup for the globals for when the runtime exits.
let _ = rt::at_exit(move || {
let _g = LOCK.lock();
assert!(!DIRECTIVES.is_null());
let _directives = Box::from_raw(DIRECTIVES);
DIRECTIVES = 1 as *mut _;

if !FILTER.is_null() {
let _filter = Box::from_raw(FILTER);
FILTER = 1 as *mut _;
}
});
}
}

Expand Down
13 changes: 5 additions & 8 deletions src/libstd/collections/hash/table.rs
Expand Up @@ -8,23 +8,20 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use self::BucketState::*;
use alloc::heap::{allocate, deallocate, EMPTY};

use clone::Clone;
use cmp;
use hash::{Hash, Hasher};
use iter::{Iterator, ExactSizeIterator};
use marker::{Copy, Send, Sync, Sized, self};
use marker;
use mem::{align_of, size_of};
use mem;
use num::wrapping::OverflowingOps;
use ops::{Deref, DerefMut, Drop};
use option::Option;
use option::Option::{Some, None};
use ops::{Deref, DerefMut};
use ptr::{self, Unique};
use rt::heap::{allocate, deallocate, EMPTY};
use collections::hash_state::HashState;

use self::BucketState::*;

const EMPTY_BUCKET: u64 = 0;

/// The raw hashtable, providing safe-ish access to the unzipped and highly
Expand Down
4 changes: 2 additions & 2 deletions src/libstd/io/lazy.rs
Expand Up @@ -12,8 +12,8 @@ use prelude::v1::*;

use cell::Cell;
use ptr;
use rt;
use sync::{StaticMutex, Arc};
use sys_common;

pub struct Lazy<T> {
lock: StaticMutex,
Expand Down Expand Up @@ -51,7 +51,7 @@ impl<T: Send + Sync + 'static> Lazy<T> {
// `Arc` allocation in our own internal box (it will get deallocated by
// the at exit handler). Otherwise we just return the freshly allocated
// `Arc`.
let registered = rt::at_exit(move || {
let registered = sys_common::at_exit(move || {
let g = self.lock.lock();
let ptr = self.ptr.get();
self.ptr.set(1 as *mut _);
Expand Down
3 changes: 2 additions & 1 deletion src/libstd/panicking.rs
Expand Up @@ -13,9 +13,10 @@ use io::prelude::*;

use any::Any;
use cell::RefCell;
use rt::{backtrace, unwind};
use sys::stdio::Stderr;
use sys_common::backtrace;
use sys_common::thread_info;
use sys_common::unwind;

thread_local! {
pub static LOCAL_STDERR: RefCell<Option<Box<Write + Send>>> = {
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/process.rs
Expand Up @@ -582,7 +582,7 @@ impl Child {
/// to run.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn exit(code: i32) -> ! {
::rt::cleanup();
::sys_common::cleanup();
::sys::os::exit(code)
}

Expand Down
65 changes: 65 additions & 0 deletions src/libstd/rt.rs
@@ -0,0 +1,65 @@
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Runtime services
//!
//! The `rt` module provides a narrow set of runtime services,
//! including the global heap (exported in `heap`) and unwinding and
//! backtrace support. The APIs in this module are highly unstable,
//! and should be considered as private implementation details for the
//! time being.

#![unstable(feature = "rt",
reason = "this public module should not exist and is highly likely \
to disappear",
issue = "0")]
#![doc(hidden)]

use borrow::ToOwned;
use mem;
use sys;
use sys_common::thread_info::{self, NewThread};
use sys_common;
use thread::{self, Thread};

// Reexport some of our utilities which are expected by other crates.
pub use sys_common::unwind::{begin_unwind, begin_unwind_fmt};

#[cfg(not(test))]
#[lang = "start"]
fn lang_start(main: *const u8, argc: isize, argv: *const *const u8) -> isize {
sys::init();

let failed = unsafe {
let main_guard = sys::thread::guard::init();
sys::stack_overflow::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 = NewThread::new(Some("<main>".to_owned()));
thread_info::set(main_guard, thread);

// Store our args if necessary in a squirreled away location
sys_common::args::init(argc, argv);

// Let's run some code!
let res = thread::catch_panic(mem::transmute::<_, fn()>(main));
sys_common::cleanup();
res.is_err()
};

if failed {
101
} else {
0
}
}

0 comments on commit f4be202

Please sign in to comment.