about summary refs log tree commit diff
path: root/src/libstd/rt
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-05-07 11:06:45 -0700
committerbors <bors@rust-lang.org>2014-05-07 11:06:45 -0700
commit87115fd001440652291c509a77bda74fa511dab0 (patch)
tree06de178943c0e48728df22b090dcdc1b9ba9a9d2 /src/libstd/rt
parent445988b47811679144d0fa9b3a2ccf2348752850 (diff)
parent07caa224501817c93be3f5c57a013ed5db6c04e1 (diff)
downloadrust-87115fd001440652291c509a77bda74fa511dab0.tar.gz
rust-87115fd001440652291c509a77bda74fa511dab0.zip
auto merge of #13901 : alexcrichton/rust/facade, r=brson
This is the second step in implementing #13851. This PR cannot currently land until a snapshot exists with #13892, but I imagine that this review will take longer.

This PR refactors a large amount of functionality outside of the standard library into a new library, libcore. This new library has 0 dependencies (in theory). In practice, this library currently depends on these symbols being available:

* `rust_begin_unwind` and `rust_fail_bounds_check` - These are the two entry points of failure in libcore. The symbols are provided by libstd currently. In the future (see the bullets on #13851) this will be officially supported with nice error mesages. Additionally, there will only be one failure entry point once `std::fmt` migrates to libcore.
* `memcpy` - This is often generated by LLVM. This is also quite trivial to implement for any platform, so I'm not too worried about this.
* `memcmp` - This is required for comparing strings. This function is quite common *everywhere*, so I don't feel to bad about relying on a consumer of libcore to define it.
* `malloc` and `free` - This is quite unfortunate, and is a temporary stopgap until we deal with the `~` situation. More details can be found in the module `core::should_not_exist`
* `fmod` and `fmodf` - These exist because the `Rem` trait is defined in libcore, so the `Rem` implementation for floats must also be defined in libcore. I imagine that any platform using floating-point modulus will have these symbols anyway, and otherwise they will be optimized out.
* `fdim` and `fdimf` - Like `fmod`, these are from the `Signed` trait being defined in libcore. I don't expect this to be much of a problem

These dependencies all "Just Work" for now because libcore only exists as an rlib, not as a dylib.

The commits themselves are organized to show that the overall diff of this extraction is not all that large. Most modules were able to be moved with very few modifications. The primary module left out of this iteration is `std::fmt`. I plan on migrating the `fmt` module to libcore, but I chose to not do so at this time because it had implications on the `Writer` trait that I wanted to deal with in isolation. There are a few breaking changes in these commits, but they are fairly minor, and are all labeled with `[breaking-change]`.

The nastiest parts of this movement come up with `~[T]` and `~str` being language-defined types today. I believe that much of this nastiness will get better over time as we migrate towards `Vec<T>` and `Str` (or whatever the types will be named). There will likely always be some extension traits, but the situation won't be as bad as it is today.

Known deficiencies:

* rustdoc will get worse in terms of readability. This is the next issue I will tackle as part of #13851. If others think that the rustdoc change should happen first, I can also table this to fix rustdoc first.
* The compiler reveals that all these types are reexports via error messages like `core::option::Option`. This is filed as #13065, and I believe that issue would have a higher priority now. I do not currently plan on fixing that as part of #13851. If others believe that this issue should be fixed, I can also place it on the roadmap for #13851.

I recommend viewing these changes on a commit-by-commit basis. The overall change is likely too overwhelming to take in.
Diffstat (limited to 'src/libstd/rt')
-rw-r--r--src/libstd/rt/args.rs1
-rw-r--r--src/libstd/rt/env.rs2
-rw-r--r--src/libstd/rt/mod.rs2
-rw-r--r--src/libstd/rt/task.rs2
-rw-r--r--src/libstd/rt/unwind.rs42
5 files changed, 14 insertions, 35 deletions
diff --git a/src/libstd/rt/args.rs b/src/libstd/rt/args.rs
index 17e6f6b7698..ac1692e6bb3 100644
--- a/src/libstd/rt/args.rs
+++ b/src/libstd/rt/args.rs
@@ -70,7 +70,6 @@ mod imp {
     use owned::Box;
     use unstable::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
     use mem;
-    #[cfg(not(test))] use str::StrSlice;
     #[cfg(not(test))] use ptr::RawPtr;
 
     static mut global_args_ptr: uint = 0;
diff --git a/src/libstd/rt/env.rs b/src/libstd/rt/env.rs
index 94f56d42613..708c42030ab 100644
--- a/src/libstd/rt/env.rs
+++ b/src/libstd/rt/env.rs
@@ -11,7 +11,7 @@
 //! Runtime environment settings
 
 use from_str::from_str;
-use option::{Some, None};
+use option::{Some, None, Expect};
 use os;
 
 // Note that these are all accessed without any synchronization.
diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs
index e79e3056838..5b9c314d42b 100644
--- a/src/libstd/rt/mod.rs
+++ b/src/libstd/rt/mod.rs
@@ -70,7 +70,7 @@ use self::task::{Task, BlockedTask};
 pub use self::util::default_sched_threads;
 
 // Export unwinding facilities used by the failure macros
-pub use self::unwind::{begin_unwind, begin_unwind_raw, begin_unwind_fmt};
+pub use self::unwind::{begin_unwind, begin_unwind_fmt};
 
 pub use self::util::{Stdio, Stdout, Stderr};
 
diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs
index 5b29de5a8c1..909df5618aa 100644
--- a/src/libstd/rt/task.rs
+++ b/src/libstd/rt/task.rs
@@ -436,7 +436,7 @@ mod test {
     #[test]
     fn rng() {
         use rand::{StdRng, Rng};
-        let mut r = StdRng::new().unwrap();
+        let mut r = StdRng::new().ok().unwrap();
         let _ = r.next_u32();
     }
 
diff --git a/src/libstd/rt/unwind.rs b/src/libstd/rt/unwind.rs
index 3ba97f381ab..5f3731eb819 100644
--- a/src/libstd/rt/unwind.rs
+++ b/src/libstd/rt/unwind.rs
@@ -58,7 +58,6 @@
 // Currently Rust uses unwind runtime provided by libgcc.
 
 use any::{Any, AnyRefExt};
-use c_str::CString;
 use cast;
 use fmt;
 use kinds::Send;
@@ -298,42 +297,23 @@ pub mod eabi {
 }
 
 #[cold]
-#[lang="fail_"]
+#[no_mangle]
 #[cfg(not(test))]
-pub fn fail_(expr: *u8, file: *u8, line: uint) -> ! {
-    begin_unwind_raw(expr, file, line);
-}
-
-#[cold]
-#[lang="fail_bounds_check"]
-#[cfg(not(test))]
-pub fn fail_bounds_check(file: *u8, line: uint, index: uint, len: uint) -> ! {
-    use c_str::ToCStr;
+pub extern fn rust_fail_bounds_check(file: *u8, line: uint,
+                                     index: uint, len: uint) -> ! {
+    use str::raw::c_str_to_static_slice;
 
     let msg = format!("index out of bounds: the len is {} but the index is {}",
                       len as uint, index as uint);
-    msg.with_c_str(|buf| fail_(buf as *u8, file, line))
+    begin_unwind(msg, unsafe { c_str_to_static_slice(file as *i8) }, line)
 }
 
-/// This is the entry point of unwinding for things like lang items and such.
-/// The arguments are normally generated by the compiler, and need to
-/// have static lifetimes.
-#[inline(never)] #[cold] // this is the slow path, please never inline this
-pub fn begin_unwind_raw(msg: *u8, file: *u8, line: uint) -> ! {
-    use libc::c_char;
-    #[inline]
-    fn static_char_ptr(p: *u8) -> &'static str {
-        let s = unsafe { CString::new(p as *c_char, false) };
-        match s.as_str() {
-            Some(s) => unsafe { cast::transmute::<&str, &'static str>(s) },
-            None => rtabort!("message wasn't utf8?")
-        }
-    }
-
-    let msg = static_char_ptr(msg);
-    let file = static_char_ptr(file);
-
-    begin_unwind(msg, file, line as uint)
+// Entry point of failure from the libcore crate
+#[no_mangle]
+#[cfg(not(test))]
+pub extern fn rust_begin_unwind(msg: &str, file: &'static str, line: uint) -> ! {
+    use str::StrAllocating;
+    begin_unwind(msg.to_owned(), file, line)
 }
 
 /// The entry point for unwinding with a formatted message.