about summary refs log tree commit diff
path: root/src/libstd/rt
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2013-12-18 09:57:58 -0800
committerAlex Crichton <alex@alexcrichton.com>2013-12-25 23:10:46 -0800
commit6cad8f4f14da1dd529100779db74b03d6db20faf (patch)
treef3610bdf15fbe38e248a1d92b37919ed8d5a6219 /src/libstd/rt
parentb47ff23673559ee9a5b91221e0212fd6a57d9802 (diff)
downloadrust-6cad8f4f14da1dd529100779db74b03d6db20faf.tar.gz
rust-6cad8f4f14da1dd529100779db74b03d6db20faf.zip
Test fixes and rebase conflicts
* vec::raw::to_ptr is gone
* Pausible => Pausable
* Removing @
* Calling the main task "<main>"
* Removing unused imports
* Removing unused mut
* Bringing some libextra tests up to date
* Allowing compiletest to work at stage0
* Fixing the bootstrap-from-c rmake tests
* assert => rtassert in a few cases
* printing to stderr instead of stdout in fail!()
Diffstat (limited to 'src/libstd/rt')
-rw-r--r--src/libstd/rt/local_ptr.rs6
-rw-r--r--src/libstd/rt/mod.rs1
-rw-r--r--src/libstd/rt/rtio.rs18
-rw-r--r--src/libstd/rt/task.rs8
-rw-r--r--src/libstd/rt/thread.rs4
-rw-r--r--src/libstd/rt/unwind.rs202
-rw-r--r--src/libstd/rt/util.rs3
7 files changed, 137 insertions, 105 deletions
diff --git a/src/libstd/rt/local_ptr.rs b/src/libstd/rt/local_ptr.rs
index b75f2927003..42cce272e44 100644
--- a/src/libstd/rt/local_ptr.rs
+++ b/src/libstd/rt/local_ptr.rs
@@ -42,7 +42,7 @@ impl<T> Drop for Borrowed<T> {
             }
             let val: ~T = cast::transmute(self.val);
             put::<T>(val);
-            assert!(exists());
+            rtassert!(exists());
         }
     }
 }
@@ -110,7 +110,7 @@ pub mod compiled {
     #[inline]
     pub unsafe fn take<T>() -> ~T {
         let ptr = RT_TLS_PTR;
-        assert!(!ptr.is_null());
+        rtassert!(!ptr.is_null());
         let ptr: ~T = cast::transmute(ptr);
         // can't use `as`, due to type not matching with `cfg(test)`
         RT_TLS_PTR = cast::transmute(0);
@@ -180,7 +180,7 @@ pub mod native {
     }
 
     pub unsafe fn cleanup() {
-        assert!(INITIALIZED);
+        rtassert!(INITIALIZED);
         tls::destroy(RT_TLS_KEY);
         LOCK.destroy();
         INITIALIZED = false;
diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs
index d0c062c1274..0dd6c883d5b 100644
--- a/src/libstd/rt/mod.rs
+++ b/src/libstd/rt/mod.rs
@@ -176,6 +176,7 @@ pub fn init(argc: int, argv: **u8) {
         args::init(argc, argv);
         env::init();
         logging::init();
+        local_ptr::init();
     }
 }
 
diff --git a/src/libstd/rt/rtio.rs b/src/libstd/rt/rtio.rs
index 97b08cc18ca..6b3d50a76ac 100644
--- a/src/libstd/rt/rtio.rs
+++ b/src/libstd/rt/rtio.rs
@@ -95,14 +95,16 @@ impl<'a> LocalIo<'a> {
     /// Returns the local I/O: either the local scheduler's I/O services or
     /// the native I/O services.
     pub fn borrow() -> Option<LocalIo> {
-        // XXX: This is currently very unsafely implemented. We don't actually
-        //      *take* the local I/O so there's a very real possibility that we
-        //      can have two borrows at once. Currently there is not a clear way
-        //      to actually borrow the local I/O factory safely because even if
-        //      ownership were transferred down to the functions that the I/O
-        //      factory implements it's just too much of a pain to know when to
-        //      relinquish ownership back into the local task (but that would be
-        //      the safe way of implementing this function).
+        // FIXME(#11053): bad
+        //
+        // This is currently very unsafely implemented. We don't actually
+        // *take* the local I/O so there's a very real possibility that we
+        // can have two borrows at once. Currently there is not a clear way
+        // to actually borrow the local I/O factory safely because even if
+        // ownership were transferred down to the functions that the I/O
+        // factory implements it's just too much of a pain to know when to
+        // relinquish ownership back into the local task (but that would be
+        // the safe way of implementing this function).
         //
         // In order to get around this, we just transmute a copy out of the task
         // in order to have what is likely a static lifetime (bad).
diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs
index 765f0b427cd..e6ab159a769 100644
--- a/src/libstd/rt/task.rs
+++ b/src/libstd/rt/task.rs
@@ -15,9 +15,10 @@
 
 use any::AnyOwnExt;
 use borrow;
+use cast;
 use cleanup;
 use io::Writer;
-use libc::{c_char, size_t};
+use iter::{Iterator, Take};
 use local_data;
 use ops::Drop;
 use option::{Option, Some, None};
@@ -488,7 +489,10 @@ mod test {
 
     #[test]
     #[should_fail]
-    fn test_begin_unwind() { begin_unwind("cause", file!(), line!()) }
+    fn test_begin_unwind() {
+        use rt::unwind::begin_unwind;
+        begin_unwind("cause", file!(), line!())
+    }
 
     // Task blocking tests
 
diff --git a/src/libstd/rt/thread.rs b/src/libstd/rt/thread.rs
index 11189282f68..f4f4aaa2765 100644
--- a/src/libstd/rt/thread.rs
+++ b/src/libstd/rt/thread.rs
@@ -144,15 +144,11 @@ impl<T: Send> Drop for Thread<T> {
 
 #[cfg(windows)]
 mod imp {
-    use super::DEFAULT_STACK_SIZE;
-
     use cast;
     use libc;
     use libc::types::os::arch::extra::{LPSECURITY_ATTRIBUTES, SIZE_T, BOOL,
                                        LPVOID, DWORD, LPDWORD, HANDLE};
     use ptr;
-    use libc;
-    use cast;
 
     pub type rust_thread = HANDLE;
     pub type rust_thread_return = DWORD;
diff --git a/src/libstd/rt/unwind.rs b/src/libstd/rt/unwind.rs
index 8248c6274ca..9706dbae4c6 100644
--- a/src/libstd/rt/unwind.rs
+++ b/src/libstd/rt/unwind.rs
@@ -10,8 +10,9 @@
 
 // Implementation of Rust stack unwinding
 //
-// For background on exception handling and stack unwinding please see "Exception Handling in LLVM"
-// (llvm.org/docs/ExceptionHandling.html) and documents linked from it.
+// For background on exception handling and stack unwinding please see
+// "Exception Handling in LLVM" (llvm.org/docs/ExceptionHandling.html) and
+// documents linked from it.
 // These are also good reads:
 //     http://theofilos.cs.columbia.edu/blog/2013/09/22/base_abi/
 //     http://monoinfinito.wordpress.com/series/exception-handling-in-c/
@@ -20,41 +21,55 @@
 // ~~~ A brief summary ~~~
 // Exception handling happens in two phases: a search phase and a cleanup phase.
 //
-// In both phases the unwinder walks stack frames from top to bottom using information from
-// the stack frame unwind sections of the current process's modules ("module" here refers to
-// an OS module, i.e. an executable or a dynamic library).
+// In both phases the unwinder walks stack frames from top to bottom using
+// information from the stack frame unwind sections of the current process's
+// modules ("module" here refers to an OS module, i.e. an executable or a
+// dynamic library).
 //
-// For each stack frame, it invokes the associated "personality routine", whose address is also
-// stored in the unwind info section.
+// For each stack frame, it invokes the associated "personality routine", whose
+// address is also stored in the unwind info section.
 //
-// In the search phase, the job of a personality routine is to examine exception object being
-// thrown, and to decide whether it should be caught at that stack frame.  Once the handler frame
-// has been identified, cleanup phase begins.
+// In the search phase, the job of a personality routine is to examine exception
+// object being thrown, and to decide whether it should be caught at that stack
+// frame.  Once the handler frame has been identified, cleanup phase begins.
 //
-// In the cleanup phase, personality routines invoke cleanup code associated with their
-// stack frames (i.e. destructors).  Once stack has been unwound down to the handler frame level,
-// unwinding stops and the last personality routine transfers control to its' catch block.
+// In the cleanup phase, personality routines invoke cleanup code associated
+// with their stack frames (i.e. destructors).  Once stack has been unwound down
+// to the handler frame level, unwinding stops and the last personality routine
+// transfers control to its' catch block.
 //
 // ~~~ Frame unwind info registration ~~~
-// Each module has its' own frame unwind info section (usually ".eh_frame"), and unwinder needs
-// to know about all of them in order for unwinding to be able to cross module boundaries.
+// Each module has its' own frame unwind info section (usually ".eh_frame"), and
+// unwinder needs to know about all of them in order for unwinding to be able to
+// cross module boundaries.
 //
-// On some platforms, like Linux, this is achieved by dynamically enumerating currently loaded
-// modules via the dl_iterate_phdr() API and finding all .eh_frame sections.
+// On some platforms, like Linux, this is achieved by dynamically enumerating
+// currently loaded modules via the dl_iterate_phdr() API and finding all
+// .eh_frame sections.
 //
-// Others, like Windows, require modules to actively register their unwind info sections by calling
-// __register_frame_info() API at startup.
-// In the latter case it is essential that there is only one copy of the unwinder runtime
-// in the process.  This is usually achieved by linking to the dynamic version of the unwind
-// runtime.
+// Others, like Windows, require modules to actively register their unwind info
+// sections by calling __register_frame_info() API at startup.  In the latter
+// case it is essential that there is only one copy of the unwinder runtime in
+// the process.  This is usually achieved by linking to the dynamic version of
+// the unwind runtime.
 //
 // Currently Rust uses unwind runtime provided by libgcc.
 
-use prelude::*;
-use cast::transmute;
-use task::TaskResult;
+use any::{Any, AnyRefExt};
+use c_str::CString;
+use cast;
+use kinds::Send;
+use libc::{c_char, size_t};
 use libc::{c_void, c_int};
-use self::libunwind::*;
+use option::{Some, None, Option};
+use result::{Err, Ok};
+use rt::local::Local;
+use rt::task::Task;
+use str::Str;
+use task::TaskResult;
+use unstable::intrinsics;
+
+use uw = self::libunwind;
 
 mod libunwind {
     //! Unwind library interface
@@ -109,34 +124,41 @@ mod libunwind {
 }
 
 pub struct Unwinder {
-    unwinding: bool,
-    cause: Option<~Any>
+    priv unwinding: bool,
+    priv cause: Option<~Any>
 }
 
 impl Unwinder {
+    pub fn new() -> Unwinder {
+        Unwinder {
+            unwinding: false,
+            cause: None,
+        }
+    }
+
+    pub fn unwinding(&self) -> bool {
+        self.unwinding
+    }
 
     pub fn try(&mut self, f: ||) {
         use unstable::raw::Closure;
 
         unsafe {
-            let closure: Closure = transmute(f);
-            let code = transmute(closure.code);
-            let env = transmute(closure.env);
-
-            let ep = rust_try(try_fn, code, env);
+            let closure: Closure = cast::transmute(f);
+            let ep = rust_try(try_fn, closure.code as *c_void,
+                              closure.env as *c_void);
             if !ep.is_null() {
                 rtdebug!("Caught {}", (*ep).exception_class);
-                _Unwind_DeleteException(ep);
+                uw::_Unwind_DeleteException(ep);
             }
         }
 
         extern fn try_fn(code: *c_void, env: *c_void) {
             unsafe {
-                let closure: Closure = Closure {
-                    code: transmute(code),
-                    env: transmute(env),
-                };
-                let closure: || = transmute(closure);
+                let closure: || = cast::transmute(Closure {
+                    code: code as *(),
+                    env: env as *(),
+                });
                 closure();
             }
         }
@@ -144,10 +166,11 @@ impl Unwinder {
         extern {
             // Rust's try-catch
             // When f(...) returns normally, the return value is null.
-            // When f(...) throws, the return value is a pointer to the caught exception object.
+            // When f(...) throws, the return value is a pointer to the caught
+            // exception object.
             fn rust_try(f: extern "C" fn(*c_void, *c_void),
                         code: *c_void,
-                        data: *c_void) -> *_Unwind_Exception;
+                        data: *c_void) -> *uw::_Unwind_Exception;
         }
     }
 
@@ -158,21 +181,21 @@ impl Unwinder {
         self.cause = Some(cause);
 
         unsafe {
-            let exception = ~_Unwind_Exception {
+            let exception = ~uw::_Unwind_Exception {
                 exception_class: rust_exception_class(),
                 exception_cleanup: exception_cleanup,
                 private_1: 0,
                 private_2: 0
             };
-            let error = _Unwind_RaiseException(transmute(exception));
+            let error = uw::_Unwind_RaiseException(cast::transmute(exception));
             rtabort!("Could not unwind stack, error = {}", error as int)
         }
 
-        extern "C" fn exception_cleanup(_unwind_code: _Unwind_Reason_Code,
-                                        exception: *_Unwind_Exception) {
+        extern "C" fn exception_cleanup(_unwind_code: uw::_Unwind_Reason_Code,
+                                        exception: *uw::_Unwind_Exception) {
             rtdebug!("exception_cleanup()");
             unsafe {
-                let _: ~_Unwind_Exception = transmute(exception);
+                let _: ~uw::_Unwind_Exception = cast::transmute(exception);
             }
         }
     }
@@ -188,68 +211,75 @@ impl Unwinder {
 
 // Rust's exception class identifier.  This is used by personality routines to
 // determine whether the exception was thrown by their own runtime.
-fn rust_exception_class() -> _Unwind_Exception_Class {
-    let bytes = bytes!("MOZ\0RUST"); // vendor, language
-    unsafe {
-        let ptr: *_Unwind_Exception_Class = transmute(bytes.as_ptr());
-        *ptr
-    }
+fn rust_exception_class() -> uw::_Unwind_Exception_Class {
+    // M O Z \0  R U S T -- vendor, language
+    0x4d4f5a_00_52555354
 }
 
-
-// We could implement our personality routine in pure Rust, however exception info decoding
-// is tedious.  More importantly, personality routines have to handle various platform
-// quirks, which are not fun to maintain.  For this reason, we attempt to reuse personality
-// routine of the C language: __gcc_personality_v0.
+// We could implement our personality routine in pure Rust, however exception
+// info decoding is tedious.  More importantly, personality routines have to
+// handle various platform quirks, which are not fun to maintain.  For this
+// reason, we attempt to reuse personality routine of the C language:
+// __gcc_personality_v0.
 //
-// Since C does not support exception catching, __gcc_personality_v0 simply always
-// returns _URC_CONTINUE_UNWIND in search phase, and always returns _URC_INSTALL_CONTEXT
-// (i.e. "invoke cleanup code") in cleanup phase.
+// Since C does not support exception catching, __gcc_personality_v0 simply
+// always returns _URC_CONTINUE_UNWIND in search phase, and always returns
+// _URC_INSTALL_CONTEXT (i.e. "invoke cleanup code") in cleanup phase.
 //
-// This is pretty close to Rust's exception handling approach, except that Rust does have
-// a single "catch-all" handler at the bottom of each task's stack.
+// This is pretty close to Rust's exception handling approach, except that Rust
+// does have a single "catch-all" handler at the bottom of each task's stack.
 // So we have two versions:
-// - rust_eh_personality, used by all cleanup landing pads, which never catches, so
-//   the behavior of __gcc_personality_v0 is perfectly adequate there, and
-// - rust_eh_personality_catch, used only by rust_try(), which always catches.  This is
-//   achieved by overriding the return value in search phase to always say "catch!".
+// - rust_eh_personality, used by all cleanup landing pads, which never catches,
+//   so the behavior of __gcc_personality_v0 is perfectly adequate there, and
+// - rust_eh_personality_catch, used only by rust_try(), which always catches.
+//   This is achieved by overriding the return value in search phase to always
+//   say "catch!".
 
 extern "C" {
     fn __gcc_personality_v0(version: c_int,
-                            actions: _Unwind_Action,
-                            exception_class: _Unwind_Exception_Class,
-                            ue_header: *_Unwind_Exception,
-                            context: *_Unwind_Context) -> _Unwind_Reason_Code;
+                            actions: uw::_Unwind_Action,
+                            exception_class: uw::_Unwind_Exception_Class,
+                            ue_header: *uw::_Unwind_Exception,
+                            context: *uw::_Unwind_Context)
+        -> uw::_Unwind_Reason_Code;
 }
 
 #[lang="eh_personality"]
 #[no_mangle] // so we can reference it by name from middle/trans/base.rs
 #[doc(hidden)]
 #[cfg(not(test))]
-pub extern "C" fn rust_eh_personality(version: c_int,
-                                      actions: _Unwind_Action,
-                                      exception_class: _Unwind_Exception_Class,
-                                      ue_header: *_Unwind_Exception,
-                                      context: *_Unwind_Context) -> _Unwind_Reason_Code {
+pub extern "C" fn rust_eh_personality(
+    version: c_int,
+    actions: uw::_Unwind_Action,
+    exception_class: uw::_Unwind_Exception_Class,
+    ue_header: *uw::_Unwind_Exception,
+    context: *uw::_Unwind_Context
+) -> uw::_Unwind_Reason_Code
+{
     unsafe {
-        __gcc_personality_v0(version, actions, exception_class, ue_header, context)
+        __gcc_personality_v0(version, actions, exception_class, ue_header,
+                             context)
     }
 }
 
 #[no_mangle] // referenced from rust_try.ll
 #[doc(hidden)]
 #[cfg(not(test))]
-pub extern "C" fn rust_eh_personality_catch(version: c_int,
-                                            actions: _Unwind_Action,
-                                            exception_class: _Unwind_Exception_Class,
-                                            ue_header: *_Unwind_Exception,
-                                            context: *_Unwind_Context) -> _Unwind_Reason_Code {
-    if (actions as c_int & _UA_SEARCH_PHASE as c_int) != 0 { // search phase
-        _URC_HANDLER_FOUND // catch!
+pub extern "C" fn rust_eh_personality_catch(
+    version: c_int,
+    actions: uw::_Unwind_Action,
+    exception_class: uw::_Unwind_Exception_Class,
+    ue_header: *uw::_Unwind_Exception,
+    context: *uw::_Unwind_Context
+) -> uw::_Unwind_Reason_Code
+{
+    if (actions as c_int & uw::_UA_SEARCH_PHASE as c_int) != 0 { // search phase
+        uw::_URC_HANDLER_FOUND // catch!
     }
     else { // cleanup phase
         unsafe {
-             __gcc_personality_v0(version, actions, exception_class, ue_header, context)
+             __gcc_personality_v0(version, actions, exception_class, ue_header,
+                                  context)
         }
     }
 }
@@ -307,11 +337,11 @@ pub fn begin_unwind<M: Any + Send>(msg: M, file: &'static str, line: uint) -> !
                     let n = (*task).name.as_ref()
                                    .map(|n| n.as_slice()).unwrap_or("<unnamed>");
 
-                    println!("task '{}' failed at '{}', {}:{}", n, msg_s,
+                    rterrln!("task '{}' failed at '{}', {}:{}", n, msg_s,
                              file, line);
                 }
                 None => {
-                    println!("failed at '{}', {}:{}", msg_s, file, line);
+                    rterrln!("failed at '{}', {}:{}", msg_s, file, line);
                     intrinsics::abort();
                 }
             }
diff --git a/src/libstd/rt/util.rs b/src/libstd/rt/util.rs
index 69c1da39abc..730a38ce886 100644
--- a/src/libstd/rt/util.rs
+++ b/src/libstd/rt/util.rs
@@ -69,14 +69,13 @@ pub fn default_sched_threads() -> uint {
 pub fn dumb_println(args: &fmt::Arguments) {
     use io;
     use libc;
-    use vec;
 
     struct Stderr;
     impl io::Writer for Stderr {
         fn write(&mut self, data: &[u8]) {
             unsafe {
                 libc::write(libc::STDERR_FILENO,
-                            vec::raw::to_ptr(data) as *libc::c_void,
+                            data.as_ptr() as *libc::c_void,
                             data.len() as libc::size_t);
             }
         }