libs: Fix miscellaneous fallout of librustrt

This commit is contained in:
Alex Crichton 2014-06-04 00:01:40 -07:00
parent d743b8831e
commit 75014f7b17
34 changed files with 263 additions and 288 deletions

View file

@ -238,9 +238,15 @@ impl Container for CString {
#[inline]
fn len(&self) -> uint {
if self.buf.is_null() { fail!("CString is null!"); }
let mut cur = self.buf;
let mut len = 0;
unsafe {
ptr::position(self.buf, |c| *c == 0)
while *cur != 0 {
len += 1;
cur = cur.offset(1);
}
}
return len;
}
}

View file

@ -113,6 +113,7 @@ pub fn init(argc: int, argv: **u8) {
// FIXME(#14344) this shouldn't be necessary
collections::fixme_14344_be_sure_to_link_to_collections();
alloc::fixme_14344_be_sure_to_link_to_collections();
libc::issue_14344_workaround();
}
/// Enqueues a procedure to run when the runtime is cleaned up

View file

@ -95,8 +95,6 @@ type TLSValue = Box<LocalData:Send>;
// Gets the map from the runtime. Lazily initialises if not done so already.
unsafe fn get_local_map() -> Option<&mut Map> {
use rt::local::Local;
if !Local::exists(None::<Task>) { return None }
let task: *mut Task = Local::unsafe_borrow();

View file

@ -18,10 +18,11 @@ use core::prelude::*;
use alloc::arc::Arc;
use alloc::owned::{AnyOwnExt, Box};
use core::any::Any;
use core::atomics::{AtomicUint, SeqCst};
use core::finally::Finally;
use core::iter::Take;
use core::mem;
use core::finally::Finally;
use core::atomics::{AtomicUint, SeqCst};
use core::raw;
use local_data;
use Runtime;
@ -142,18 +143,17 @@ impl Task {
// TLS, or possibly some destructors for those objects being
// annihilated invoke TLS. Sadly these two operations seemed to
// be intertwined, and miraculously work for now...
let mut task = Local::borrow(None::<Task>);
let storage_map = {
drop({
let mut task = Local::borrow(None::<Task>);
let &LocalStorage(ref mut optmap) = &mut task.storage;
optmap.take()
};
drop(task);
drop(storage_map);
});
// Destroy remaining boxes. Also may run user dtors.
let mut task = Local::borrow(None::<Task>);
let mut heap = mem::replace(&mut task.heap, LocalHeap::new());
drop(task);
let mut heap = {
let mut task = Local::borrow(None::<Task>);
mem::replace(&mut task.heap, LocalHeap::new())
};
unsafe { heap.annihilate() }
drop(heap);
})
@ -202,13 +202,16 @@ impl Task {
// crops up.
unsafe {
let imp = self.imp.take_unwrap();
let &(vtable, _): &(uint, uint) = mem::transmute(&imp);
let vtable = mem::transmute::<_, &raw::TraitObject>(&imp).vtable;
match imp.wrap().move::<T>() {
Ok(t) => Some(t),
Err(t) => {
let (_, obj): (uint, uint) = mem::transmute(t);
let data = mem::transmute::<_, raw::TraitObject>(t).data;
let obj: Box<Runtime:Send> =
mem::transmute((vtable, obj));
mem::transmute(raw::TraitObject {
vtable: vtable,
data: data,
});
self.put_runtime(obj);
None
}

View file

@ -121,7 +121,7 @@ impl Unwinder {
self.cause = unsafe { try(f) }.err();
}
pub fn result(&mut self) -> TaskResult {
pub fn result(&mut self) -> Result {
if self.unwinding {
Err(self.cause.take().unwrap())
} else {
@ -150,10 +150,7 @@ impl Unwinder {
/// guaranteed that a rust task is in place when invoking this function.
/// Unwinding twice can lead to resource leaks where some destructors are not
/// run.
pub unsafe fn try(f: ||) -> Result<(), Box<Any:Send>> {
use raw::Closure;
use libc::{c_void};
pub unsafe fn try(f: ||) -> ::core::result::Result<(), Box<Any:Send>> {
let closure: Closure = mem::transmute(f);
let ep = rust_try(try_fn, closure.code as *c_void,
closure.env as *c_void);
@ -300,7 +297,7 @@ pub mod eabi {
#[cfg(target_arch = "arm", not(test))]
#[allow(visible_private_types)]
pub mod eabi {
use uw = rt::libunwind;
use uw = libunwind;
use libc::c_int;
extern "C" {
@ -432,9 +429,9 @@ fn begin_unwind_inner(msg: Box<Any:Send>,
// Now that we've run all the necessary unwind callbacks, we actually
// perform the unwinding. If we don't have a task, then it's time to die
// (hopefully someone printed something about this).
let task: Box<Task> = match Local::try_take() {
let mut task: Box<Task> = match Local::try_take() {
Some(task) => task,
None => unsafe { intrinsics::abort() }
None => rust_fail(msg),
};
if task.unwinder.unwinding {
@ -445,17 +442,13 @@ fn begin_unwind_inner(msg: Box<Any:Send>,
rterrln!("task failed during unwinding. aborting.");
unsafe { intrinsics::abort() }
}
task.unwinder.unwinding = true;
// Put the task back in TLS because the unwinding process may run code which
// requires the task. We need a handle to its unwinder, however, so after
// this we unsafely extract it and continue along.
Local::put(task);
unsafe {
let task: *mut Task = Local::unsafe_borrow();
(*task).unwinder.begin_unwind(msg);
}
task.name = name;
Local::put(task);
rust_fail(msg);
}
/// Register a callback to be invoked when a task unwinds.

View file

@ -73,9 +73,7 @@ pub fn abort(args: &fmt::Arguments) -> ! {
let mut w = BufWriter { buf: msg, pos: 0 };
let _ = write!(&mut w, "{}", args);
let msg = str::from_utf8(w.buf.slice_to(w.pos)).unwrap_or("aborted");
let msg = if msg.is_empty() {
"aborted"
} else { "aborted" };
let msg = if msg.is_empty() {"aborted"} else {msg};
// Give some context to the message
let hash = msg.bytes().fold(0, |accum, val| accum + (val as uint) );