From e8ddef93da5f112795eff66ff7dc7ccccc1baa86 Mon Sep 17 00:00:00 2001
From: Brian Anderson <banderson@mozilla.com>
Date: Tue, 12 Mar 2013 00:48:41 -0700
Subject: [PATCH 01/12] core: Cleanup rt::context

---
 src/libcore/rt/context.rs | 41 ++++++++++++++++++++++++++++++---------
 src/libcore/rt/sched.rs   | 10 ++--------
 src/libcore/rt/stack.rs   |  1 +
 3 files changed, 35 insertions(+), 17 deletions(-)

diff --git a/src/libcore/rt/context.rs b/src/libcore/rt/context.rs
index dfb7bdf04c3..11512c3fe7a 100644
--- a/src/libcore/rt/context.rs
+++ b/src/libcore/rt/context.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use option::*;
 use super::stack::StackSegment;
 use libc::c_void;
 use cast::{transmute, transmute_mut_unsafe,
@@ -16,17 +17,30 @@ use cast::{transmute, transmute_mut_unsafe,
 // XXX: Registers is boxed so that it is 16-byte aligned, for storing
 // SSE regs.  It would be marginally better not to do this. In C++ we
 // use an attribute on a struct.
-pub struct Context(~Registers);
+// XXX: It would be nice to define regs as `~Option<Registers>` since
+// the registers are sometimes empty, but the discriminant would
+// then misalign the regs again.
+pub struct Context {
+    /// The context entry point, saved here for later destruction
+    start: Option<~~fn()>,
+    /// Hold the registers while the task or scheduler is suspended
+    regs: ~Registers
+}
 
 pub impl Context {
     static fn empty() -> Context {
-        Context(new_regs())
+        Context {
+            start: None,
+            regs: new_regs()
+        }
     }
 
     /// Create a new context that will resume execution by running ~fn()
-    /// # Safety Note
-    /// The `start` closure must remain valid for the life of the Task
-    static fn new(start: &~fn(), stack: &mut StackSegment) -> Context {
+    static fn new(start: ~fn(), stack: &mut StackSegment) -> Context {
+        // XXX: Putting main into a ~ so it's a thin pointer and can
+        // be passed to the spawn function.  Another unfortunate
+        // allocation
+        let start = ~start;
 
         // The C-ABI function that is the task entry point
         extern fn task_start_wrapper(f: &~fn()) { (*f)() }
@@ -46,15 +60,24 @@ pub impl Context {
 
         initialize_call_frame(&mut *regs, fp, argp, sp);
 
-        return Context(regs);
+        return Context {
+            start: Some(start),
+            regs: regs
+        }
     }
 
+    /* Switch contexts
+
+    Suspend the current execution context and resume another by
+    saving the registers values of the executing thread to a Context
+    then loading the registers from a previously saved Context.
+    */
     static fn swap(out_context: &mut Context, in_context: &Context) {
         let out_regs: &mut Registers = match out_context {
-            &Context(~ref mut r) => r
+            &Context { regs: ~ref mut r, _ } => r
         };
         let in_regs: &Registers = match in_context {
-            &Context(~ref r) => r
+            &Context { regs: ~ref r, _ } => r
         };
 
         unsafe { swap_registers(out_regs, in_regs) };
@@ -88,7 +111,7 @@ fn initialize_call_frame(regs: &mut Registers,
                          fptr: *c_void, arg: *c_void, sp: *mut uint) {
 
     let sp = align_down(sp);
-    let sp = mut_offset(sp, -4); // XXX: -4 words? Needs this be done at all?
+    let sp = mut_offset(sp, -4);
 
     unsafe { *sp = arg as uint; }
     let sp = mut_offset(sp, -1);
diff --git a/src/libcore/rt/sched.rs b/src/libcore/rt/sched.rs
index 8f315452e5e..ff0b3d28e8d 100644
--- a/src/libcore/rt/sched.rs
+++ b/src/libcore/rt/sched.rs
@@ -285,8 +285,6 @@ pub impl Scheduler {
 const TASK_MIN_STACK_SIZE: uint = 10000000; // XXX: Too much stack
 
 pub struct Task {
-    /// The task entry point, saved here for later destruction
-    priv start: ~~fn(),
     /// The segment of stack on which the task is currently running or,
     /// if the task is blocked, on which the task will resume execution
     priv current_stack_segment: StackSegment,
@@ -297,15 +295,11 @@ pub struct Task {
 
 impl Task {
     static fn new(stack_pool: &mut StackPool, start: ~fn()) -> Task {
-        // XXX: Putting main into a ~ so it's a thin pointer and can
-        // be passed to the spawn function.  Another unfortunate
-        // allocation
-        let start = ~Task::build_start_wrapper(start);
+        let start = Task::build_start_wrapper(start);
         let mut stack = stack_pool.take_segment(TASK_MIN_STACK_SIZE);
         // NB: Context holds a pointer to that ~fn
-        let initial_context = Context::new(&*start, &mut stack);
+        let initial_context = Context::new(start, &mut stack);
         return Task {
-            start: start,
             current_stack_segment: stack,
             saved_context: initial_context,
         };
diff --git a/src/libcore/rt/stack.rs b/src/libcore/rt/stack.rs
index 02c47218ed8..ef48025ffe6 100644
--- a/src/libcore/rt/stack.rs
+++ b/src/libcore/rt/stack.rs
@@ -27,6 +27,7 @@ pub impl StackSegment {
         }
     }
 
+    /// Point one word beyond the high end of the allocated stack
     fn end(&self) -> *uint {
         unsafe {
             vec::raw::to_ptr(self.buf).offset(self.buf.len()) as *uint

From d30c75897416621092023063b885494f2a64e406 Mon Sep 17 00:00:00 2001
From: Brian Anderson <banderson@mozilla.com>
Date: Tue, 12 Mar 2013 14:06:19 -0700
Subject: [PATCH 02/12] Give core::rt and std::net their own uvll bindings

I intend to do some big refactoring and don't want to deal w/ std just now
---
 src/libcore/rt/mod.rs                |    1 +
 src/libcore/rt/uv.rs                 |    2 +-
 src/libcore/{unstable => rt}/uvll.rs |    0
 src/libcore/unstable.rs              |    2 -
 src/libstd/net_ip.rs                 |   28 +-
 src/libstd/std.rc                    |    2 +-
 src/libstd/uv.rs                     |    2 +-
 src/libstd/uv_ll.rs                  | 1939 ++++++++++++++++++++++++++
 8 files changed, 1957 insertions(+), 19 deletions(-)
 rename src/libcore/{unstable => rt}/uvll.rs (100%)
 create mode 100644 src/libstd/uv_ll.rs

diff --git a/src/libcore/rt/mod.rs b/src/libcore/rt/mod.rs
index a1a9884aeca..e48367d7202 100644
--- a/src/libcore/rt/mod.rs
+++ b/src/libcore/rt/mod.rs
@@ -37,6 +37,7 @@ macro_rules! rtdebug (
 
 mod sched;
 mod io;
+pub mod uvll;
 mod uvio;
 mod uv;
 // FIXME #5248: The import in `sched` doesn't resolve unless this is pub!
diff --git a/src/libcore/rt/uv.rs b/src/libcore/rt/uv.rs
index c947e4dde4c..c450a631955 100644
--- a/src/libcore/rt/uv.rs
+++ b/src/libcore/rt/uv.rs
@@ -43,7 +43,7 @@ use libc::{c_void, c_int, size_t, malloc, free, ssize_t};
 use cast::{transmute, transmute_mut_region};
 use ptr::null;
 use sys::size_of;
-use unstable::uvll;
+use super::uvll;
 use super::io::{IpAddr, Ipv4, Ipv6};
 
 #[cfg(test)] use unstable::run_in_bare_thread;
diff --git a/src/libcore/unstable/uvll.rs b/src/libcore/rt/uvll.rs
similarity index 100%
rename from src/libcore/unstable/uvll.rs
rename to src/libcore/rt/uvll.rs
diff --git a/src/libcore/unstable.rs b/src/libcore/unstable.rs
index 9b6dcc31234..ac5e7e90ea6 100644
--- a/src/libcore/unstable.rs
+++ b/src/libcore/unstable.rs
@@ -35,8 +35,6 @@ pub mod extfmt;
 #[path = "unstable/lang.rs"]
 #[cfg(notest)]
 pub mod lang;
-#[path = "unstable/uvll.rs"]
-pub mod uvll;
 
 mod rustrt {
     use unstable::{raw_thread, rust_little_lock};
diff --git a/src/libstd/net_ip.rs b/src/libstd/net_ip.rs
index 04283674d88..15593571b43 100644
--- a/src/libstd/net_ip.rs
+++ b/src/libstd/net_ip.rs
@@ -21,20 +21,20 @@ use core::vec;
 use iotask = uv::iotask::IoTask;
 use interact = uv::iotask::interact;
 
-use sockaddr_in = core::unstable::uvll::sockaddr_in;
-use sockaddr_in6 = core::unstable::uvll::sockaddr_in6;
-use addrinfo = core::unstable::uvll::addrinfo;
-use uv_getaddrinfo_t = core::unstable::uvll::uv_getaddrinfo_t;
-use uv_ip4_name = core::unstable::uvll::ip4_name;
-use uv_ip4_port = core::unstable::uvll::ip4_port;
-use uv_ip6_name = core::unstable::uvll::ip6_name;
-use uv_ip6_port = core::unstable::uvll::ip6_port;
-use uv_getaddrinfo = core::unstable::uvll::getaddrinfo;
-use uv_freeaddrinfo = core::unstable::uvll::freeaddrinfo;
-use create_uv_getaddrinfo_t = core::unstable::uvll::getaddrinfo_t;
-use set_data_for_req = core::unstable::uvll::set_data_for_req;
-use get_data_for_req = core::unstable::uvll::get_data_for_req;
-use ll = core::unstable::uvll;
+use sockaddr_in = super::uv_ll::sockaddr_in;
+use sockaddr_in6 = super::uv_ll::sockaddr_in6;
+use addrinfo = super::uv_ll::addrinfo;
+use uv_getaddrinfo_t = super::uv_ll::uv_getaddrinfo_t;
+use uv_ip4_name = super::uv_ll::ip4_name;
+use uv_ip4_port = super::uv_ll::ip4_port;
+use uv_ip6_name = super::uv_ll::ip6_name;
+use uv_ip6_port = super::uv_ll::ip6_port;
+use uv_getaddrinfo = super::uv_ll::getaddrinfo;
+use uv_freeaddrinfo = super::uv_ll::freeaddrinfo;
+use create_uv_getaddrinfo_t = super::uv_ll::getaddrinfo_t;
+use set_data_for_req = super::uv_ll::set_data_for_req;
+use get_data_for_req = super::uv_ll::get_data_for_req;
+use ll = super::uv_ll;
 
 /// An IP address
 pub enum IpAddr {
diff --git a/src/libstd/std.rc b/src/libstd/std.rc
index 85e914a60a1..6a7576645b8 100644
--- a/src/libstd/std.rc
+++ b/src/libstd/std.rc
@@ -36,7 +36,7 @@ not required in or otherwise suitable for the core library.
 extern mod core(vers = "0.6");
 use core::*;
 
-pub use uv_ll = core::unstable::uvll;
+pub mod uv_ll;
 
 // General io and system-services modules
 
diff --git a/src/libstd/uv.rs b/src/libstd/uv.rs
index aaddc9b6836..e055b407057 100644
--- a/src/libstd/uv.rs
+++ b/src/libstd/uv.rs
@@ -33,6 +33,6 @@
  * facilities.
  */
 
-pub use ll = core::unstable::uvll;
+pub use ll = super::uv_ll;
 pub use iotask = uv_iotask;
 pub use global_loop = uv_global_loop;
diff --git a/src/libstd/uv_ll.rs b/src/libstd/uv_ll.rs
new file mode 100644
index 00000000000..682939975ef
--- /dev/null
+++ b/src/libstd/uv_ll.rs
@@ -0,0 +1,1939 @@
+// Copyright 2012 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.
+
+/*!
+ * Low-level bindings to the libuv library.
+ *
+ * This module contains a set of direct, 'bare-metal' wrappers around
+ * the libuv C-API.
+ *
+ * Also contained herein are a set of rust records that map, in
+ * approximate memory-size, to the libuv data structures. The record
+ * implementations are adjusted, per-platform, to match their respective
+ * representations.
+ *
+ * There are also a collection of helper functions to ease interacting
+ * with the low-level API (such as a function to return the latest
+ * libuv error as a rust-formatted string).
+ *
+ * As new functionality, existant in uv.h, is added to the rust stdlib,
+ * the mappings should be added in this module.
+ *
+ * This module's implementation will hopefully be, eventually, replaced
+ * with per-platform, generated source files from rust-bindgen.
+ */
+
+#[allow(non_camel_case_types)]; // C types
+
+use core::libc::size_t;
+use core::libc::c_void;
+use core::prelude::*;
+use core::ptr::to_unsafe_ptr;
+
+pub type uv_handle_t = c_void;
+pub type uv_loop_t = c_void;
+pub type uv_idle_t = c_void;
+pub type uv_idle_cb = *u8;
+
+// libuv struct mappings
+pub struct uv_ip4_addr {
+    ip: ~[u8],
+    port: int,
+}
+pub type uv_ip6_addr = uv_ip4_addr;
+
+pub enum uv_handle_type {
+    UNKNOWN_HANDLE = 0,
+    UV_TCP,
+    UV_UDP,
+    UV_NAMED_PIPE,
+    UV_TTY,
+    UV_FILE,
+    UV_TIMER,
+    UV_PREPARE,
+    UV_CHECK,
+    UV_IDLE,
+    UV_ASYNC,
+    UV_ARES_TASK,
+    UV_ARES_EVENT,
+    UV_PROCESS,
+    UV_FS_EVENT
+}
+
+pub type handle_type = libc::c_uint;
+
+pub struct uv_handle_fields {
+   loop_handle: *libc::c_void,
+   type_: handle_type,
+   close_cb: *u8,
+   data: *libc::c_void,
+}
+
+// unix size: 8
+pub struct uv_err_t {
+    code: libc::c_int,
+    sys_errno_: libc::c_int
+}
+
+// don't create one of these directly. instead,
+// count on it appearing in libuv callbacks or embedded
+// in other types as a pointer to be used in other
+// operations (so mostly treat it as opaque, once you
+// have it in this form..)
+pub struct uv_stream_t {
+    fields: uv_handle_fields,
+}
+
+// 64bit unix size: 216
+#[cfg(target_os="macos")]
+pub struct uv_tcp_t {
+    fields: uv_handle_fields,
+    a00: *u8, a01: *u8, a02: *u8, a03: *u8,
+    a04: *u8, a05: *u8, a06: *u8, a07: *u8,
+    a08: *u8, a09: *u8, a10: *u8, a11: *u8,
+    a12: *u8, a13: *u8, a14: *u8, a15: *u8,
+    a16: *u8, a17: *u8, a18: *u8, a19: *u8,
+    a20: *u8, a21: *u8, a22: *u8,
+    a23: uv_tcp_t_osx_riders
+}
+#[cfg(target_arch="x86_64")]
+pub struct uv_tcp_t_osx_riders {
+    a23: *u8,
+}
+#[cfg(target_arch="x86")]
+#[cfg(target_arch="arm")]
+pub struct uv_tcp_t_osx_riders {
+    a23: *u8,
+    a24: *u8, a25: *u8,
+}
+#[cfg(target_os="linux")]
+#[cfg(target_os="freebsd")]
+#[cfg(target_os="android")]
+pub struct uv_tcp_t {
+    fields: uv_handle_fields,
+    a00: *u8, a01: *u8, a02: *u8, a03: *u8,
+    a04: *u8, a05: *u8, a06: *u8, a07: *u8,
+    a08: *u8, a09: *u8, a10: *u8, a11: *u8,
+    a12: *u8, a13: *u8, a14: *u8, a15: *u8,
+    a16: *u8, a17: *u8, a18: *u8, a19: *u8,
+    a20: *u8, a21: *u8,
+    a22: uv_tcp_t_32bit_unix_riders,
+}
+// 32bit unix size: 328 (164)
+#[cfg(target_arch="x86_64")]
+pub struct uv_tcp_t_32bit_unix_riders {
+    a29: *u8,
+}
+#[cfg(target_arch="x86")]
+#[cfg(target_arch="arm")]
+#[cfg(target_arch="mips")]
+pub struct uv_tcp_t_32bit_unix_riders {
+    a29: *u8, a30: *u8, a31: *u8,
+}
+
+// 32bit win32 size: 240 (120)
+#[cfg(windows)]
+pub struct uv_tcp_t {
+    fields: uv_handle_fields,
+    a00: *u8, a01: *u8, a02: *u8, a03: *u8,
+    a04: *u8, a05: *u8, a06: *u8, a07: *u8,
+    a08: *u8, a09: *u8, a10: *u8, a11: *u8,
+    a12: *u8, a13: *u8, a14: *u8, a15: *u8,
+    a16: *u8, a17: *u8, a18: *u8, a19: *u8,
+    a20: *u8, a21: *u8, a22: *u8, a23: *u8,
+    a24: *u8, a25: *u8,
+}
+
+// unix size: 64
+#[cfg(unix)]
+pub struct uv_connect_t {
+    a00: *u8, a01: *u8, a02: *u8, a03: *u8,
+    a04: *u8, a05: *u8, a06: *u8, a07: *u8
+}
+// win32 size: 88 (44)
+#[cfg(windows)]
+pub struct uv_connect_t {
+    a00: *u8, a01: *u8, a02: *u8, a03: *u8,
+    a04: *u8, a05: *u8, a06: *u8, a07: *u8,
+    a08: *u8, a09: *u8, a10: *u8,
+}
+
+// unix size: 16
+pub struct uv_buf_t {
+    base: *u8,
+    len: libc::size_t,
+}
+// no gen stub method.. should create
+// it via uv::direct::buf_init()
+
+// unix size: 160
+#[cfg(unix)]
+pub struct uv_write_t {
+    fields: uv_handle_fields,
+    a00: *u8, a01: *u8, a02: *u8, a03: *u8,
+    a04: *u8, a05: *u8, a06: *u8, a07: *u8,
+    a08: *u8, a09: *u8, a10: *u8, a11: *u8,
+    a12: *u8,
+    a14: uv_write_t_32bit_unix_riders,
+}
+#[cfg(target_arch="x86_64")]
+pub struct uv_write_t_32bit_unix_riders {
+    a13: *u8, a14: *u8, a15: *u8
+}
+#[cfg(target_arch="x86")]
+#[cfg(target_arch="arm")]
+#[cfg(target_arch="mips")]
+pub struct uv_write_t_32bit_unix_riders {
+    a13: *u8, a14: *u8, a15: *u8,
+    a16: *u8,
+}
+// win32 size: 136 (68)
+#[cfg(windows)]
+pub struct uv_write_t {
+    fields: uv_handle_fields,
+    a00: *u8, a01: *u8, a02: *u8, a03: *u8,
+    a04: *u8, a05: *u8, a06: *u8, a07: *u8,
+    a08: *u8, a09: *u8, a10: *u8, a11: *u8,
+    a12: *u8,
+}
+// 64bit unix size: 96
+// 32bit unix size: 152 (76)
+#[cfg(unix)]
+pub struct uv_async_t {
+    fields: uv_handle_fields,
+    a00: *u8, a01: *u8, a02: *u8, a03: *u8,
+    a04: *u8, a05: *u8, a06: *u8,
+    a07: uv_async_t_32bit_unix_riders,
+}
+#[cfg(target_arch="x86_64")]
+pub struct uv_async_t_32bit_unix_riders {
+    a10: *u8,
+}
+#[cfg(target_arch="x86")]
+#[cfg(target_arch="arm")]
+#[cfg(target_arch="mips")]
+pub struct uv_async_t_32bit_unix_riders {
+    a10: *u8,
+}
+// win32 size 132 (68)
+#[cfg(windows)]
+pub struct uv_async_t {
+    fields: uv_handle_fields,
+    a00: *u8, a01: *u8, a02: *u8, a03: *u8,
+    a04: *u8, a05: *u8, a06: *u8, a07: *u8,
+    a08: *u8, a09: *u8, a10: *u8, a11: *u8,
+    a12: *u8,
+}
+
+// 64bit unix size: 120
+// 32bit unix size: 84
+#[cfg(unix)]
+pub struct uv_timer_t {
+    fields: uv_handle_fields,
+    a00: *u8, a01: *u8, a02: *u8, a03: *u8,
+    a04: *u8, a05: *u8, a06: *u8, a07: *u8,
+    a08: *u8, a09: *u8,
+    a11: uv_timer_t_32bit_unix_riders,
+}
+#[cfg(target_arch="x86_64")]
+pub struct uv_timer_t_32bit_unix_riders {
+    a10: *u8,
+}
+#[cfg(target_arch="x86")]
+#[cfg(target_arch="arm")]
+#[cfg(target_arch="mips")]
+pub struct uv_timer_t_32bit_unix_riders {
+    a10: *u8, a11: *u8, a12: *u8
+}
+// win32 size: 64
+#[cfg(windows)]
+pub struct uv_timer_t {
+    fields: uv_handle_fields,
+    a00: *u8, a01: *u8, a02: *u8, a03: *u8,
+    a04: *u8, a05: *u8, a06: *u8, a07: *u8,
+    a08: *u8, a09: *u8, a10: *u8, a11: *u8,
+}
+
+// unix size: 16
+pub struct sockaddr_in {
+    sin_family: u16,
+    sin_port: u16,
+    sin_addr: u32, // in_addr: this is an opaque, per-platform struct
+    sin_zero: (u8, u8, u8, u8, u8, u8, u8, u8),
+}
+
+// unix size: 28 .. FIXME #1645
+// stuck with 32 becuse of rust padding structs?
+#[cfg(target_arch="x86_64")]
+pub struct sockaddr_in6 {
+    a0: *u8, a1: *u8,
+    a2: *u8, a3: *u8,
+}
+#[cfg(target_arch="x86")]
+#[cfg(target_arch="arm")]
+#[cfg(target_arch="mips")]
+pub struct sockaddr_in6 {
+    a0: *u8, a1: *u8,
+    a2: *u8, a3: *u8,
+    a4: *u8, a5: *u8,
+    a6: *u8, a7: *u8,
+}
+
+// unix size: 28 .. FIXME #1645
+// stuck with 32 becuse of rust padding structs?
+pub type addr_in = addr_in_impl::addr_in;
+#[cfg(unix)]
+pub mod addr_in_impl {
+    #[cfg(target_arch="x86_64")]
+    pub struct addr_in {
+        a0: *u8, a1: *u8,
+        a2: *u8, a3: *u8,
+    }
+    #[cfg(target_arch="x86")]
+    #[cfg(target_arch="arm")]
+    #[cfg(target_arch="mips")]
+    pub struct addr_in {
+        a0: *u8, a1: *u8,
+        a2: *u8, a3: *u8,
+        a4: *u8, a5: *u8,
+        a6: *u8, a7: *u8,
+    }
+}
+#[cfg(windows)]
+pub mod addr_in_impl {
+    pub struct addr_in {
+        a0: *u8, a1: *u8,
+        a2: *u8, a3: *u8,
+    }
+}
+
+// unix size: 48, 32bit: 32
+pub type addrinfo = addrinfo_impl::addrinfo;
+#[cfg(target_os="linux")]
+#[cfg(target_os="android")]
+pub mod addrinfo_impl {
+    #[cfg(target_arch="x86_64")]
+    pub struct addrinfo {
+        a00: *u8, a01: *u8, a02: *u8, a03: *u8,
+        a04: *u8, a05: *u8,
+    }
+    #[cfg(target_arch="x86")]
+    #[cfg(target_arch="arm")]
+    #[cfg(target_arch="mips")]
+    pub struct addrinfo {
+        a00: *u8, a01: *u8, a02: *u8, a03: *u8,
+        a04: *u8, a05: *u8, a06: *u8, a07: *u8,
+    }
+}
+#[cfg(target_os="macos")]
+#[cfg(target_os="freebsd")]
+pub mod addrinfo_impl {
+    pub struct addrinfo {
+        a00: *u8, a01: *u8, a02: *u8, a03: *u8,
+        a04: *u8, a05: *u8,
+    }
+}
+#[cfg(windows)]
+pub mod addrinfo_impl {
+    pub struct addrinfo {
+        a00: *u8, a01: *u8, a02: *u8, a03: *u8,
+        a04: *u8, a05: *u8,
+    }
+}
+
+// unix size: 72
+pub struct uv_getaddrinfo_t {
+    a00: *u8, a01: *u8, a02: *u8, a03: *u8, a04: *u8, a05: *u8,
+    a06: *u8, a07: *u8, a08: *u8, a09: *u8,
+    a10: *u8, a11: *u8, a12: *u8, a13: *u8, a14: *u8, a15: *u8
+}
+
+pub mod uv_ll_struct_stubgen {
+
+    use core::ptr;
+
+    use super::{
+        uv_async_t,
+        uv_connect_t,
+        uv_getaddrinfo_t,
+        uv_handle_fields,
+        uv_tcp_t,
+        uv_timer_t,
+        uv_write_t,
+    };
+
+    #[cfg(target_os = "linux")]
+    #[cfg(target_os = "android")]
+    #[cfg(target_os = "macos")]
+    #[cfg(target_os = "freebsd")]
+    use super::{
+        uv_async_t_32bit_unix_riders,
+        uv_tcp_t_32bit_unix_riders,
+        uv_timer_t_32bit_unix_riders,
+        uv_write_t_32bit_unix_riders,
+    };
+
+    pub fn gen_stub_uv_tcp_t() -> uv_tcp_t {
+        return gen_stub_os();
+        #[cfg(target_os = "linux")]
+        #[cfg(target_os = "android")]
+        #[cfg(target_os = "freebsd")]
+        pub fn gen_stub_os() -> uv_tcp_t {
+            return gen_stub_arch();
+            #[cfg(target_arch="x86_64")]
+            pub fn gen_stub_arch() -> uv_tcp_t {
+                uv_tcp_t {
+                    fields: uv_handle_fields {
+                        loop_handle: ptr::null(), type_: 0u32,
+                        close_cb: ptr::null(),
+                        data: ptr::null(),
+                    },
+                    a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
+                    a03: 0 as *u8,
+                    a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
+                    a07: 0 as *u8,
+                    a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
+                    a11: 0 as *u8,
+                    a12: 0 as *u8, a13: 0 as *u8, a14: 0 as *u8,
+                    a15: 0 as *u8,
+                    a16: 0 as *u8, a17: 0 as *u8, a18: 0 as *u8,
+                    a19: 0 as *u8,
+                    a20: 0 as *u8, a21: 0 as *u8,
+                    a22: uv_tcp_t_32bit_unix_riders { a29: 0 as *u8 },
+                }
+            }
+            #[cfg(target_arch="x86")]
+            #[cfg(target_arch="arm")]
+            #[cfg(target_arch="mips")]
+            pub fn gen_stub_arch() -> uv_tcp_t {
+                uv_tcp_t {
+                    fields: uv_handle_fields {
+                        loop_handle: ptr::null(), type_: 0u32,
+                        close_cb: ptr::null(),
+                        data: ptr::null(),
+                    },
+                    a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
+                    a03: 0 as *u8,
+                    a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
+                    a07: 0 as *u8,
+                    a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
+                    a11: 0 as *u8,
+                    a12: 0 as *u8, a13: 0 as *u8, a14: 0 as *u8,
+                    a15: 0 as *u8,
+                    a16: 0 as *u8, a17: 0 as *u8, a18: 0 as *u8,
+                    a19: 0 as *u8,
+                    a20: 0 as *u8, a21: 0 as *u8,
+                    a22: uv_tcp_t_32bit_unix_riders {
+                        a29: 0 as *u8, a30: 0 as *u8, a31: 0 as *u8,
+                    },
+                }
+            }
+        }
+        #[cfg(windows)]
+        pub fn gen_stub_os() -> uv_tcp_t {
+            uv_tcp_t {
+                fields: uv_handle_fields {
+                    loop_handle: ptr::null(), type_: 0u32,
+                    close_cb: ptr::null(),
+                    data: ptr::null(),
+                },
+                a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
+                a03: 0 as *u8,
+                a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
+                a07: 0 as *u8,
+                a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
+                a11: 0 as *u8,
+                a12: 0 as *u8, a13: 0 as *u8, a14: 0 as *u8,
+                a15: 0 as *u8,
+                a16: 0 as *u8, a17: 0 as *u8, a18: 0 as *u8,
+                a19: 0 as *u8,
+                a20: 0 as *u8, a21: 0 as *u8, a22: 0 as *u8,
+                a23: 0 as *u8,
+                a24: 0 as *u8, a25: 0 as *u8,
+            }
+        }
+        #[cfg(target_os = "macos")]
+        pub fn gen_stub_os() -> uv_tcp_t {
+            use super::uv_tcp_t_osx_riders;
+
+            return gen_stub_arch();
+
+            #[cfg(target_arch = "x86_64")]
+            fn gen_stub_arch() -> uv_tcp_t {
+                uv_tcp_t {
+                    fields: uv_handle_fields {
+                        loop_handle: ptr::null(), type_: 0u32,
+                        close_cb: ptr::null(),
+                        data: ptr::null(),
+                    },
+                    a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
+                    a03: 0 as *u8,
+                    a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
+                    a07: 0 as *u8,
+                    a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
+                    a11: 0 as *u8,
+                    a12: 0 as *u8, a13: 0 as *u8, a14: 0 as *u8,
+                    a15: 0 as *u8,
+                    a16: 0 as *u8, a17: 0 as *u8, a18: 0 as *u8,
+                    a19: 0 as *u8,
+                    a20: 0 as *u8, a21: 0 as *u8, a22: 0 as *u8,
+                    a23: uv_tcp_t_osx_riders {
+                        a23: 0 as *u8,
+                    }
+                }
+            }
+
+            #[cfg(target_arch = "x86")]
+            #[cfg(target_arch = "arm")]
+            fn gen_stub_arch() -> uv_tcp_t {
+                uv_tcp_t {
+                    fields: uv_handle_fields {
+                        loop_handle: ptr::null(), type_: 0u32,
+                        close_cb: ptr::null(),
+                        data: ptr::null(),
+                    },
+                    a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
+                    a03: 0 as *u8,
+                    a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
+                    a07: 0 as *u8,
+                    a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
+                    a11: 0 as *u8,
+                    a12: 0 as *u8, a13: 0 as *u8, a14: 0 as *u8,
+                    a15: 0 as *u8,
+                    a16: 0 as *u8, a17: 0 as *u8, a18: 0 as *u8,
+                    a19: 0 as *u8,
+                    a20: 0 as *u8, a21: 0 as *u8, a22: 0 as *u8,
+                    a23: uv_tcp_t_osx_riders {
+                        a23: 0 as *u8,
+                        a24: 0 as *u8, a25: 0 as *u8,
+                    }
+                }
+            }
+        }
+    }
+    #[cfg(unix)]
+    pub fn gen_stub_uv_connect_t() -> uv_connect_t {
+        uv_connect_t {
+            a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
+            a03: 0 as *u8,
+            a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
+            a07: 0 as *u8
+        }
+    }
+    #[cfg(windows)]
+    pub fn gen_stub_uv_connect_t() -> uv_connect_t {
+        uv_connect_t {
+            a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
+            a03: 0 as *u8,
+            a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
+            a07: 0 as *u8,
+            a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
+        }
+    }
+    #[cfg(unix)]
+    pub fn gen_stub_uv_async_t() -> uv_async_t {
+        return gen_stub_arch();
+        #[cfg(target_arch = "x86_64")]
+        pub fn gen_stub_arch() -> uv_async_t {
+            uv_async_t {
+                fields: uv_handle_fields {
+                    loop_handle: ptr::null(), type_: 0u32,
+                    close_cb: ptr::null(),
+                    data: ptr::null(),
+                },
+                a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
+                a03: 0 as *u8,
+                a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
+                a07: uv_async_t_32bit_unix_riders { a10: 0 as *u8 },
+            }
+        }
+        #[cfg(target_arch = "x86")]
+        #[cfg(target_arch="arm")]
+        #[cfg(target_arch="mips")]
+        pub fn gen_stub_arch() -> uv_async_t {
+            uv_async_t {
+                fields: uv_handle_fields {
+                    loop_handle: ptr::null(), type_: 0u32,
+                    close_cb: ptr::null(),
+                    data: ptr::null(),
+                },
+                a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
+                a03: 0 as *u8,
+                a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
+                a07: uv_async_t_32bit_unix_riders {
+                    a10: 0 as *u8,
+                }
+            }
+        }
+    }
+    #[cfg(windows)]
+    pub fn gen_stub_uv_async_t() -> uv_async_t {
+        uv_async_t {
+            fields: uv_handle_fields {
+                loop_handle: ptr::null(), type_: 0u32,
+                close_cb: ptr::null(),
+                data: ptr::null(),
+            },
+            a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
+            a03: 0 as *u8,
+            a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
+            a07: 0 as *u8,
+            a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
+            a11: 0 as *u8,
+            a12: 0 as *u8,
+        }
+    }
+    #[cfg(unix)]
+    pub fn gen_stub_uv_timer_t() -> uv_timer_t {
+        return gen_stub_arch();
+        #[cfg(target_arch = "x86_64")]
+        pub fn gen_stub_arch() -> uv_timer_t {
+            uv_timer_t {
+                fields: uv_handle_fields {
+                    loop_handle: ptr::null(), type_: 0u32,
+                    close_cb: ptr::null(),
+                    data: ptr::null(),
+                },
+                a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
+                a03: 0 as *u8,
+                a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
+                a07: 0 as *u8,
+                a08: 0 as *u8, a09: 0 as *u8,
+                a11: uv_timer_t_32bit_unix_riders {
+                    a10: 0 as *u8
+                },
+            }
+        }
+        #[cfg(target_arch = "x86")]
+        #[cfg(target_arch="arm")]
+        #[cfg(target_arch="mips")]
+        pub fn gen_stub_arch() -> uv_timer_t {
+            uv_timer_t {
+                fields: uv_handle_fields {
+                    loop_handle: ptr::null(), type_: 0u32,
+                    close_cb: ptr::null(),
+                    data: ptr::null(),
+                },
+                a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
+                a03: 0 as *u8,
+                a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
+                a07: 0 as *u8,
+                a08: 0 as *u8, a09: 0 as *u8,
+                a11: uv_timer_t_32bit_unix_riders {
+                    a10: 0 as *u8, a11: 0 as *u8,
+                    a12: 0 as *u8,
+                },
+            }
+        }
+    }
+    #[cfg(windows)]
+    pub fn gen_stub_uv_timer_t() -> uv_timer_t {
+        uv_timer_t {
+            fields: uv_handle_fields {
+                loop_handle: ptr::null(), type_: 0u32,
+                close_cb: ptr::null(),
+                data: ptr::null(),
+            },
+            a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
+            a03: 0 as *u8,
+            a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
+            a07: 0 as *u8,
+            a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
+            a11: 0 as *u8,
+        }
+    }
+    #[cfg(unix)]
+    pub fn gen_stub_uv_write_t() -> uv_write_t {
+        return gen_stub_arch();
+        #[cfg(target_arch="x86_64")]
+        pub fn gen_stub_arch() -> uv_write_t {
+            uv_write_t {
+                fields: uv_handle_fields {
+                    loop_handle: ptr::null(), type_: 0u32,
+                    close_cb: ptr::null(),
+                    data: ptr::null(),
+                },
+                a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
+                a03: 0 as *u8,
+                a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
+                a07: 0 as *u8,
+                a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
+                a11: 0 as *u8,
+                a12: 0 as *u8,
+                a14: uv_write_t_32bit_unix_riders { a13: 0 as *u8,
+                                                   a14: 0 as *u8,
+                                                   a15: 0 as *u8},
+            }
+        }
+        #[cfg(target_arch="x86")]
+        #[cfg(target_arch="arm")]
+        #[cfg(target_arch="mips")]
+        pub fn gen_stub_arch() -> uv_write_t {
+            uv_write_t {
+                fields: uv_handle_fields {
+                    loop_handle: ptr::null(), type_: 0u32,
+                    close_cb: ptr::null(),
+                    data: ptr::null(),
+                },
+                a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
+                a03: 0 as *u8,
+                a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
+                a07: 0 as *u8,
+                a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
+                a11: 0 as *u8,
+                a12: 0 as *u8,
+                a14: uv_write_t_32bit_unix_riders {
+                    a13: 0 as *u8,
+                    a14: 0 as *u8,
+                    a15: 0 as *u8,
+                    a16: 0 as *u8,
+                }
+            }
+        }
+    }
+    #[cfg(windows)]
+    pub fn gen_stub_uv_write_t() -> uv_write_t {
+        uv_write_t {
+            fields: uv_handle_fields {
+                loop_handle: ptr::null(), type_: 0u32,
+                close_cb: ptr::null(),
+                data: ptr::null(),
+            },
+            a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
+            a03: 0 as *u8,
+            a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
+            a07: 0 as *u8,
+            a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
+            a11: 0 as *u8,
+            a12: 0 as *u8
+        }
+    }
+    pub fn gen_stub_uv_getaddrinfo_t() -> uv_getaddrinfo_t {
+        uv_getaddrinfo_t {
+            a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8, a03: 0 as *u8,
+            a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8, a07: 0 as *u8,
+            a08: 0 as *u8, a09: 0 as *u8,
+            a10: 1 as *u8, a11: 1 as *u8, a12: 1 as *u8, a13: 1 as *u8,
+            a14: 1 as *u8, a15: 1 as *u8
+        }
+    }
+}
+
+#[nolink]
+extern mod rustrt {
+
+    // libuv public API
+    unsafe fn rust_uv_loop_new() -> *libc::c_void;
+    unsafe fn rust_uv_loop_delete(lp: *libc::c_void);
+    unsafe fn rust_uv_run(loop_handle: *libc::c_void);
+    unsafe fn rust_uv_close(handle: *libc::c_void, cb: *u8);
+    unsafe fn rust_uv_walk(loop_handle: *libc::c_void, cb: *u8,
+                           arg: *libc::c_void);
+
+    unsafe fn rust_uv_idle_new() -> *uv_idle_t;
+    unsafe fn rust_uv_idle_delete(handle: *uv_idle_t);
+    unsafe fn rust_uv_idle_init(loop_handle: *uv_loop_t,
+                                handle: *uv_idle_t) -> libc::c_int;
+    unsafe fn rust_uv_idle_start(handle: *uv_idle_t,
+                                 cb: uv_idle_cb) -> libc::c_int;
+    unsafe fn rust_uv_idle_stop(handle: *uv_idle_t) -> libc::c_int;
+
+    unsafe fn rust_uv_async_send(handle: *uv_async_t);
+    unsafe fn rust_uv_async_init(loop_handle: *libc::c_void,
+                          async_handle: *uv_async_t,
+                          cb: *u8) -> libc::c_int;
+    unsafe fn rust_uv_tcp_init(
+        loop_handle: *libc::c_void,
+        handle_ptr: *uv_tcp_t) -> libc::c_int;
+    // FIXME ref #2604 .. ?
+    unsafe fn rust_uv_buf_init(out_buf: *uv_buf_t, base: *u8,
+                        len: libc::size_t);
+    unsafe fn rust_uv_last_error(loop_handle: *libc::c_void) -> uv_err_t;
+    // FIXME ref #2064
+    unsafe fn rust_uv_strerror(err: *uv_err_t) -> *libc::c_char;
+    // FIXME ref #2064
+    unsafe fn rust_uv_err_name(err: *uv_err_t) -> *libc::c_char;
+    unsafe fn rust_uv_ip4_addr(ip: *u8, port: libc::c_int)
+        -> sockaddr_in;
+    unsafe fn rust_uv_ip6_addr(ip: *u8, port: libc::c_int)
+        -> sockaddr_in6;
+    unsafe fn rust_uv_ip4_name(src: *sockaddr_in,
+                               dst: *u8,
+                               size: libc::size_t)
+                            -> libc::c_int;
+    unsafe fn rust_uv_ip6_name(src: *sockaddr_in6,
+                               dst: *u8,
+                               size: libc::size_t)
+                            -> libc::c_int;
+    unsafe fn rust_uv_ip4_port(src: *sockaddr_in) -> libc::c_uint;
+    unsafe fn rust_uv_ip6_port(src: *sockaddr_in6) -> libc::c_uint;
+    // FIXME ref #2064
+    unsafe fn rust_uv_tcp_connect(connect_ptr: *uv_connect_t,
+                                  tcp_handle_ptr: *uv_tcp_t,
+                                  ++after_cb: *u8,
+                                  ++addr: *sockaddr_in) -> libc::c_int;
+    // FIXME ref #2064
+    unsafe fn rust_uv_tcp_bind(tcp_server: *uv_tcp_t,
+                               ++addr: *sockaddr_in) -> libc::c_int;
+    // FIXME ref #2064
+    unsafe fn rust_uv_tcp_connect6(connect_ptr: *uv_connect_t,
+                                   tcp_handle_ptr: *uv_tcp_t,
+                                   ++after_cb: *u8,
+                                   ++addr: *sockaddr_in6) -> libc::c_int;
+    // FIXME ref #2064
+    unsafe fn rust_uv_tcp_bind6(tcp_server: *uv_tcp_t,
+                                ++addr: *sockaddr_in6) -> libc::c_int;
+    unsafe fn rust_uv_tcp_getpeername(tcp_handle_ptr: *uv_tcp_t,
+                                      ++name: *sockaddr_in) -> libc::c_int;
+    unsafe fn rust_uv_tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t,
+                                       ++name: *sockaddr_in6) ->libc::c_int;
+    unsafe fn rust_uv_listen(stream: *libc::c_void,
+                             backlog: libc::c_int,
+                             cb: *u8) -> libc::c_int;
+    unsafe fn rust_uv_accept(server: *libc::c_void, client: *libc::c_void)
+                          -> libc::c_int;
+    unsafe fn rust_uv_write(req: *libc::c_void,
+                            stream: *libc::c_void,
+                            ++buf_in: *uv_buf_t,
+                            buf_cnt: libc::c_int,
+                            cb: *u8)
+        -> libc::c_int;
+    unsafe fn rust_uv_read_start(stream: *libc::c_void,
+                                 on_alloc: *u8,
+                                 on_read: *u8)
+        -> libc::c_int;
+    unsafe fn rust_uv_read_stop(stream: *libc::c_void) -> libc::c_int;
+    unsafe fn rust_uv_timer_init(loop_handle: *libc::c_void,
+                                 timer_handle: *uv_timer_t)
+        -> libc::c_int;
+    unsafe fn rust_uv_timer_start(
+        timer_handle: *uv_timer_t,
+        cb: *u8,
+        timeout: libc::c_uint,
+        repeat: libc::c_uint) -> libc::c_int;
+    unsafe fn rust_uv_timer_stop(handle: *uv_timer_t) -> libc::c_int;
+
+    unsafe fn rust_uv_getaddrinfo(loop_ptr: *libc::c_void,
+                                  handle: *uv_getaddrinfo_t,
+                                  cb: *u8,
+                                  node_name_ptr: *u8,
+                                  service_name_ptr: *u8,
+                                  // should probably only pass ptr::null()
+                                  hints: *addrinfo)
+        -> libc::c_int;
+    unsafe fn rust_uv_freeaddrinfo(res: *addrinfo);
+
+    // data accessors/helpers for rust-mapped uv structs
+    unsafe fn rust_uv_helper_get_INADDR_NONE() -> u32;
+    unsafe fn rust_uv_is_ipv4_addrinfo(input: *addrinfo) -> bool;
+    unsafe fn rust_uv_is_ipv6_addrinfo(input: *addrinfo) -> bool;
+    unsafe fn rust_uv_get_next_addrinfo(input: *addrinfo) -> *addrinfo;
+    unsafe fn rust_uv_addrinfo_as_sockaddr_in(input: *addrinfo)
+        -> *sockaddr_in;
+    unsafe fn rust_uv_addrinfo_as_sockaddr_in6(input: *addrinfo)
+        -> *sockaddr_in6;
+    unsafe fn rust_uv_malloc_buf_base_of(sug_size: libc::size_t) -> *u8;
+    unsafe fn rust_uv_free_base_of_buf(++buf: uv_buf_t);
+    unsafe fn rust_uv_get_stream_handle_from_connect_req(
+        connect_req: *uv_connect_t)
+        -> *uv_stream_t;
+    unsafe fn rust_uv_get_stream_handle_from_write_req(
+        write_req: *uv_write_t)
+        -> *uv_stream_t;
+    unsafe fn rust_uv_get_loop_for_uv_handle(handle: *libc::c_void)
+        -> *libc::c_void;
+    unsafe fn rust_uv_get_data_for_uv_loop(loop_ptr: *libc::c_void)
+        -> *libc::c_void;
+    unsafe fn rust_uv_set_data_for_uv_loop(loop_ptr: *libc::c_void,
+                                           data: *libc::c_void);
+    unsafe fn rust_uv_get_data_for_uv_handle(handle: *libc::c_void)
+        -> *libc::c_void;
+    unsafe fn rust_uv_set_data_for_uv_handle(handle: *libc::c_void,
+                                             data: *libc::c_void);
+    unsafe fn rust_uv_get_data_for_req(req: *libc::c_void)
+        -> *libc::c_void;
+    unsafe fn rust_uv_set_data_for_req(req: *libc::c_void,
+                                       data: *libc::c_void);
+    unsafe fn rust_uv_get_base_from_buf(++buf: uv_buf_t) -> *u8;
+    unsafe fn rust_uv_get_len_from_buf(++buf: uv_buf_t) -> libc::size_t;
+
+    // sizeof testing helpers
+    unsafe fn rust_uv_helper_uv_tcp_t_size() -> libc::c_uint;
+    unsafe fn rust_uv_helper_uv_connect_t_size() -> libc::c_uint;
+    unsafe fn rust_uv_helper_uv_buf_t_size() -> libc::c_uint;
+    unsafe fn rust_uv_helper_uv_write_t_size() -> libc::c_uint;
+    unsafe fn rust_uv_helper_uv_err_t_size() -> libc::c_uint;
+    unsafe fn rust_uv_helper_sockaddr_in_size() -> libc::c_uint;
+    unsafe fn rust_uv_helper_sockaddr_in6_size() -> libc::c_uint;
+    unsafe fn rust_uv_helper_uv_async_t_size() -> libc::c_uint;
+    unsafe fn rust_uv_helper_uv_timer_t_size() -> libc::c_uint;
+    unsafe fn rust_uv_helper_uv_getaddrinfo_t_size() -> libc::c_uint;
+    unsafe fn rust_uv_helper_addrinfo_size() -> libc::c_uint;
+    unsafe fn rust_uv_helper_addr_in_size() -> libc::c_uint;
+}
+
+pub unsafe fn loop_new() -> *libc::c_void {
+    return rustrt::rust_uv_loop_new();
+}
+
+pub unsafe fn loop_delete(loop_handle: *libc::c_void) {
+    rustrt::rust_uv_loop_delete(loop_handle);
+}
+
+pub unsafe fn run(loop_handle: *libc::c_void) {
+    rustrt::rust_uv_run(loop_handle);
+}
+
+pub unsafe fn close<T>(handle: *T, cb: *u8) {
+    rustrt::rust_uv_close(handle as *libc::c_void, cb);
+}
+
+pub unsafe fn walk(loop_handle: *libc::c_void, cb: *u8, arg: *libc::c_void) {
+    rustrt::rust_uv_walk(loop_handle, cb, arg);
+}
+
+pub unsafe fn idle_new() -> *uv_idle_t {
+    rustrt::rust_uv_idle_new()
+}
+
+pub unsafe fn idle_delete(handle: *uv_idle_t) {
+    rustrt::rust_uv_idle_delete(handle)
+}
+
+pub unsafe fn idle_init(loop_handle: *uv_loop_t,
+                        handle: *uv_idle_t) -> libc::c_int {
+    rustrt::rust_uv_idle_init(loop_handle, handle)
+}
+
+pub unsafe fn idle_start(handle: *uv_idle_t, cb: uv_idle_cb) -> libc::c_int {
+    rustrt::rust_uv_idle_start(handle, cb)
+}
+
+pub unsafe fn idle_stop(handle: *uv_idle_t) -> libc::c_int {
+    rustrt::rust_uv_idle_stop(handle)
+}
+
+pub unsafe fn tcp_init(loop_handle: *libc::c_void, handle: *uv_tcp_t)
+    -> libc::c_int {
+    return rustrt::rust_uv_tcp_init(loop_handle, handle);
+}
+// FIXME ref #2064
+pub unsafe fn tcp_connect(connect_ptr: *uv_connect_t,
+                      tcp_handle_ptr: *uv_tcp_t,
+                      addr_ptr: *sockaddr_in,
+                      after_connect_cb: *u8)
+-> libc::c_int {
+    log(debug, fmt!("b4 foreign tcp_connect--addr port: %u cb: %u",
+                    (*addr_ptr).sin_port as uint, after_connect_cb as uint));
+    return rustrt::rust_uv_tcp_connect(connect_ptr, tcp_handle_ptr,
+                                    after_connect_cb, addr_ptr);
+}
+// FIXME ref #2064
+pub unsafe fn tcp_connect6(connect_ptr: *uv_connect_t,
+                      tcp_handle_ptr: *uv_tcp_t,
+                      addr_ptr: *sockaddr_in6,
+                      after_connect_cb: *u8)
+-> libc::c_int {
+    return rustrt::rust_uv_tcp_connect6(connect_ptr, tcp_handle_ptr,
+                                    after_connect_cb, addr_ptr);
+}
+// FIXME ref #2064
+pub unsafe fn tcp_bind(tcp_server_ptr: *uv_tcp_t,
+                   addr_ptr: *sockaddr_in) -> libc::c_int {
+    return rustrt::rust_uv_tcp_bind(tcp_server_ptr,
+                                 addr_ptr);
+}
+// FIXME ref #2064
+pub unsafe fn tcp_bind6(tcp_server_ptr: *uv_tcp_t,
+                   addr_ptr: *sockaddr_in6) -> libc::c_int {
+    return rustrt::rust_uv_tcp_bind6(tcp_server_ptr,
+                                 addr_ptr);
+}
+
+pub unsafe fn tcp_getpeername(tcp_handle_ptr: *uv_tcp_t,
+                              name: *sockaddr_in) -> libc::c_int {
+    return rustrt::rust_uv_tcp_getpeername(tcp_handle_ptr, name);
+}
+
+pub unsafe fn tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t,
+                               name: *sockaddr_in6) ->libc::c_int {
+    return rustrt::rust_uv_tcp_getpeername6(tcp_handle_ptr, name);
+}
+
+pub unsafe fn listen<T>(stream: *T, backlog: libc::c_int,
+                 cb: *u8) -> libc::c_int {
+    return rustrt::rust_uv_listen(stream as *libc::c_void, backlog, cb);
+}
+
+pub unsafe fn accept(server: *libc::c_void, client: *libc::c_void)
+    -> libc::c_int {
+    return rustrt::rust_uv_accept(server as *libc::c_void,
+                               client as *libc::c_void);
+}
+
+pub unsafe fn write<T>(req: *uv_write_t, stream: *T,
+         buf_in: *~[uv_buf_t], cb: *u8) -> libc::c_int {
+    let buf_ptr = vec::raw::to_ptr(*buf_in);
+    let buf_cnt = vec::len(*buf_in) as i32;
+    return rustrt::rust_uv_write(req as *libc::c_void,
+                              stream as *libc::c_void,
+                              buf_ptr, buf_cnt, cb);
+}
+pub unsafe fn read_start(stream: *uv_stream_t, on_alloc: *u8,
+                     on_read: *u8) -> libc::c_int {
+    return rustrt::rust_uv_read_start(stream as *libc::c_void,
+                                   on_alloc, on_read);
+}
+
+pub unsafe fn read_stop(stream: *uv_stream_t) -> libc::c_int {
+    return rustrt::rust_uv_read_stop(stream as *libc::c_void);
+}
+
+pub unsafe fn last_error(loop_handle: *libc::c_void) -> uv_err_t {
+    return rustrt::rust_uv_last_error(loop_handle);
+}
+
+pub unsafe fn strerror(err: *uv_err_t) -> *libc::c_char {
+    return rustrt::rust_uv_strerror(err);
+}
+pub unsafe fn err_name(err: *uv_err_t) -> *libc::c_char {
+    return rustrt::rust_uv_err_name(err);
+}
+
+pub unsafe fn async_init(loop_handle: *libc::c_void,
+                     async_handle: *uv_async_t,
+                     cb: *u8) -> libc::c_int {
+    return rustrt::rust_uv_async_init(loop_handle,
+                                   async_handle,
+                                   cb);
+}
+
+pub unsafe fn async_send(async_handle: *uv_async_t) {
+    return rustrt::rust_uv_async_send(async_handle);
+}
+pub unsafe fn buf_init(input: *u8, len: uint) -> uv_buf_t {
+    let out_buf = uv_buf_t { base: ptr::null(), len: 0 as libc::size_t };
+    let out_buf_ptr = ptr::addr_of(&out_buf);
+    log(debug, fmt!("buf_init - input %u len %u out_buf: %u",
+                     input as uint,
+                     len as uint,
+                     out_buf_ptr as uint));
+    // yuck :/
+    rustrt::rust_uv_buf_init(out_buf_ptr, input, len as size_t);
+    //let result = rustrt::rust_uv_buf_init_2(input, len as size_t);
+    log(debug, ~"after rust_uv_buf_init");
+    let res_base = get_base_from_buf(out_buf);
+    let res_len = get_len_from_buf(out_buf);
+    //let res_base = get_base_from_buf(result);
+    log(debug, fmt!("buf_init - result %u len %u",
+                     res_base as uint,
+                     res_len as uint));
+    return out_buf;
+    //return result;
+}
+pub unsafe fn ip4_addr(ip: &str, port: int)
+-> sockaddr_in {
+    do str::as_c_str(ip) |ip_buf| {
+        rustrt::rust_uv_ip4_addr(ip_buf as *u8,
+                                 port as libc::c_int)
+    }
+}
+pub unsafe fn ip6_addr(ip: &str, port: int)
+-> sockaddr_in6 {
+    do str::as_c_str(ip) |ip_buf| {
+        rustrt::rust_uv_ip6_addr(ip_buf as *u8,
+                                 port as libc::c_int)
+    }
+}
+pub unsafe fn ip4_name(src: &sockaddr_in) -> ~str {
+    // ipv4 addr max size: 15 + 1 trailing null byte
+    let dst: ~[u8] = ~[0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8,
+                     0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8];
+    do vec::as_imm_buf(dst) |dst_buf, size| {
+        rustrt::rust_uv_ip4_name(to_unsafe_ptr(src),
+                                 dst_buf, size as libc::size_t);
+        // seems that checking the result of uv_ip4_name
+        // doesn't work too well..
+        // you're stuck looking at the value of dst_buf
+        // to see if it is the string representation of
+        // INADDR_NONE (0xffffffff or 255.255.255.255 on
+        // many platforms)
+        str::raw::from_buf(dst_buf)
+    }
+}
+pub unsafe fn ip6_name(src: &sockaddr_in6) -> ~str {
+    // ipv6 addr max size: 45 + 1 trailing null byte
+    let dst: ~[u8] = ~[0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8,
+                       0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8,
+                       0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8,
+                       0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8,
+                       0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8,
+                       0u8,0u8,0u8,0u8,0u8,0u8];
+    do vec::as_imm_buf(dst) |dst_buf, size| {
+        let src_unsafe_ptr = to_unsafe_ptr(src);
+        log(debug, fmt!("val of src *sockaddr_in6: %? sockaddr_in6: %?",
+                        src_unsafe_ptr, src));
+        let result = rustrt::rust_uv_ip6_name(src_unsafe_ptr,
+                                              dst_buf, size as libc::size_t);
+        match result {
+          0i32 => str::raw::from_buf(dst_buf),
+          _ => ~""
+        }
+    }
+}
+pub unsafe fn ip4_port(src: &sockaddr_in) -> uint {
+    rustrt::rust_uv_ip4_port(to_unsafe_ptr(src)) as uint
+}
+pub unsafe fn ip6_port(src: &sockaddr_in6) -> uint {
+    rustrt::rust_uv_ip6_port(to_unsafe_ptr(src)) as uint
+}
+
+pub unsafe fn timer_init(loop_ptr: *libc::c_void,
+                     timer_ptr: *uv_timer_t) -> libc::c_int {
+    return rustrt::rust_uv_timer_init(loop_ptr, timer_ptr);
+}
+pub unsafe fn timer_start(timer_ptr: *uv_timer_t, cb: *u8, timeout: uint,
+                      repeat: uint) -> libc::c_int {
+    return rustrt::rust_uv_timer_start(timer_ptr, cb, timeout as libc::c_uint,
+                                    repeat as libc::c_uint);
+}
+pub unsafe fn timer_stop(timer_ptr: *uv_timer_t) -> libc::c_int {
+    return rustrt::rust_uv_timer_stop(timer_ptr);
+}
+pub unsafe fn getaddrinfo(loop_ptr: *libc::c_void,
+                           handle: *uv_getaddrinfo_t,
+                           cb: *u8,
+                           node_name_ptr: *u8,
+                           service_name_ptr: *u8,
+                           hints: *addrinfo) -> libc::c_int {
+    rustrt::rust_uv_getaddrinfo(loop_ptr,
+                           handle,
+                           cb,
+                           node_name_ptr,
+                           service_name_ptr,
+                           hints)
+}
+pub unsafe fn freeaddrinfo(res: *addrinfo) {
+    rustrt::rust_uv_freeaddrinfo(res);
+}
+
+// libuv struct initializers
+pub unsafe fn tcp_t() -> uv_tcp_t {
+    return uv_ll_struct_stubgen::gen_stub_uv_tcp_t();
+}
+pub unsafe fn connect_t() -> uv_connect_t {
+    return uv_ll_struct_stubgen::gen_stub_uv_connect_t();
+}
+pub unsafe fn write_t() -> uv_write_t {
+    return uv_ll_struct_stubgen::gen_stub_uv_write_t();
+}
+pub unsafe fn async_t() -> uv_async_t {
+    return uv_ll_struct_stubgen::gen_stub_uv_async_t();
+}
+pub unsafe fn timer_t() -> uv_timer_t {
+    return uv_ll_struct_stubgen::gen_stub_uv_timer_t();
+}
+pub unsafe fn getaddrinfo_t() -> uv_getaddrinfo_t {
+    return uv_ll_struct_stubgen::gen_stub_uv_getaddrinfo_t();
+}
+
+// data access helpers
+pub unsafe fn get_loop_for_uv_handle<T>(handle: *T)
+    -> *libc::c_void {
+    return rustrt::rust_uv_get_loop_for_uv_handle(handle as *libc::c_void);
+}
+pub unsafe fn get_stream_handle_from_connect_req(connect: *uv_connect_t)
+    -> *uv_stream_t {
+    return rustrt::rust_uv_get_stream_handle_from_connect_req(
+        connect);
+}
+pub unsafe fn get_stream_handle_from_write_req(
+    write_req: *uv_write_t)
+    -> *uv_stream_t {
+    return rustrt::rust_uv_get_stream_handle_from_write_req(
+        write_req);
+}
+pub unsafe fn get_data_for_uv_loop(loop_ptr: *libc::c_void) -> *libc::c_void {
+    rustrt::rust_uv_get_data_for_uv_loop(loop_ptr)
+}
+pub unsafe fn set_data_for_uv_loop(loop_ptr: *libc::c_void,
+                                   data: *libc::c_void) {
+    rustrt::rust_uv_set_data_for_uv_loop(loop_ptr, data);
+}
+pub unsafe fn get_data_for_uv_handle<T>(handle: *T) -> *libc::c_void {
+    return rustrt::rust_uv_get_data_for_uv_handle(handle as *libc::c_void);
+}
+pub unsafe fn set_data_for_uv_handle<T, U>(handle: *T,
+                    data: *U) {
+    rustrt::rust_uv_set_data_for_uv_handle(handle as *libc::c_void,
+                                           data as *libc::c_void);
+}
+pub unsafe fn get_data_for_req<T>(req: *T) -> *libc::c_void {
+    return rustrt::rust_uv_get_data_for_req(req as *libc::c_void);
+}
+pub unsafe fn set_data_for_req<T, U>(req: *T,
+                    data: *U) {
+    rustrt::rust_uv_set_data_for_req(req as *libc::c_void,
+                                     data as *libc::c_void);
+}
+pub unsafe fn get_base_from_buf(buf: uv_buf_t) -> *u8 {
+    return rustrt::rust_uv_get_base_from_buf(buf);
+}
+pub unsafe fn get_len_from_buf(buf: uv_buf_t) -> libc::size_t {
+    return rustrt::rust_uv_get_len_from_buf(buf);
+}
+pub unsafe fn malloc_buf_base_of(suggested_size: libc::size_t)
+    -> *u8 {
+    return rustrt::rust_uv_malloc_buf_base_of(suggested_size);
+}
+pub unsafe fn free_base_of_buf(buf: uv_buf_t) {
+    rustrt::rust_uv_free_base_of_buf(buf);
+}
+
+pub unsafe fn get_last_err_info(uv_loop: *libc::c_void) -> ~str {
+    let err = last_error(uv_loop);
+    let err_ptr = ptr::addr_of(&err);
+    let err_name = str::raw::from_c_str(err_name(err_ptr));
+    let err_msg = str::raw::from_c_str(strerror(err_ptr));
+    return fmt!("LIBUV ERROR: name: %s msg: %s",
+                    err_name, err_msg);
+}
+
+pub unsafe fn get_last_err_data(uv_loop: *libc::c_void) -> uv_err_data {
+    let err = last_error(uv_loop);
+    let err_ptr = ptr::addr_of(&err);
+    let err_name = str::raw::from_c_str(err_name(err_ptr));
+    let err_msg = str::raw::from_c_str(strerror(err_ptr));
+    uv_err_data { err_name: err_name, err_msg: err_msg }
+}
+
+pub struct uv_err_data {
+    err_name: ~str,
+    err_msg: ~str,
+}
+
+pub unsafe fn is_ipv4_addrinfo(input: *addrinfo) -> bool {
+    rustrt::rust_uv_is_ipv4_addrinfo(input)
+}
+pub unsafe fn is_ipv6_addrinfo(input: *addrinfo) -> bool {
+    rustrt::rust_uv_is_ipv6_addrinfo(input)
+}
+pub unsafe fn get_INADDR_NONE() -> u32 {
+    rustrt::rust_uv_helper_get_INADDR_NONE()
+}
+pub unsafe fn get_next_addrinfo(input: *addrinfo) -> *addrinfo {
+    rustrt::rust_uv_get_next_addrinfo(input)
+}
+pub unsafe fn addrinfo_as_sockaddr_in(input: *addrinfo) -> *sockaddr_in {
+    rustrt::rust_uv_addrinfo_as_sockaddr_in(input)
+}
+pub unsafe fn addrinfo_as_sockaddr_in6(input: *addrinfo) -> *sockaddr_in6 {
+    rustrt::rust_uv_addrinfo_as_sockaddr_in6(input)
+}
+
+#[cfg(test)]
+pub mod test {
+    use prelude::*;
+    use super::*;
+    use comm::{SharedChan, stream, GenericChan, GenericPort};
+
+    enum tcp_read_data {
+        tcp_read_eof,
+        tcp_read_more(~[u8]),
+        tcp_read_error
+    }
+
+    struct request_wrapper {
+        write_req: *uv_write_t,
+        req_buf: *~[uv_buf_t],
+        read_chan: SharedChan<~str>,
+    }
+
+    extern fn after_close_cb(handle: *libc::c_void) {
+        log(debug, fmt!("after uv_close! handle ptr: %?",
+                        handle));
+    }
+
+    extern fn on_alloc_cb(handle: *libc::c_void,
+                         suggested_size: libc::size_t)
+        -> uv_buf_t {
+        unsafe {
+            log(debug, ~"on_alloc_cb!");
+            let char_ptr = malloc_buf_base_of(suggested_size);
+            log(debug, fmt!("on_alloc_cb h: %? char_ptr: %u sugsize: %u",
+                             handle,
+                             char_ptr as uint,
+                             suggested_size as uint));
+            return buf_init(char_ptr, suggested_size as uint);
+        }
+    }
+
+    extern fn on_read_cb(stream: *uv_stream_t,
+                        nread: libc::ssize_t,
+                        ++buf: uv_buf_t) {
+        unsafe {
+            let nread = nread as int;
+            log(debug, fmt!("CLIENT entering on_read_cb nred: %d",
+                            nread));
+            if (nread > 0) {
+                // we have data
+                log(debug, fmt!("CLIENT read: data! nread: %d", nread));
+                read_stop(stream);
+                let client_data =
+                    get_data_for_uv_handle(stream as *libc::c_void)
+                      as *request_wrapper;
+                let buf_base = get_base_from_buf(buf);
+                let bytes = vec::from_buf(buf_base, nread as uint);
+                let read_chan = (*client_data).read_chan.clone();
+                let msg_from_server = str::from_bytes(bytes);
+                read_chan.send(msg_from_server);
+                close(stream as *libc::c_void, after_close_cb)
+            }
+            else if (nread == -1) {
+                // err .. possibly EOF
+                log(debug, ~"read: eof!");
+            }
+            else {
+                // nread == 0 .. do nothing, just free buf as below
+                log(debug, ~"read: do nothing!");
+            }
+            // when we're done
+            free_base_of_buf(buf);
+            log(debug, ~"CLIENT exiting on_read_cb");
+        }
+    }
+
+    extern fn on_write_complete_cb(write_req: *uv_write_t,
+                                  status: libc::c_int) {
+        unsafe {
+            log(debug,
+                fmt!("CLIENT beginning on_write_complete_cb status: %d",
+                     status as int));
+            let stream = get_stream_handle_from_write_req(write_req);
+            log(debug,
+                fmt!("CLIENT on_write_complete_cb: tcp:%d write_handle:%d",
+                stream as int, write_req as int));
+            let result = read_start(stream, on_alloc_cb, on_read_cb);
+            log(debug,
+                fmt!("CLIENT ending on_write_complete_cb .. status: %d",
+                     result as int));
+        }
+    }
+
+    extern fn on_connect_cb(connect_req_ptr: *uv_connect_t,
+                                 status: libc::c_int) {
+        unsafe {
+            log(debug, fmt!("beginning on_connect_cb .. status: %d",
+                             status as int));
+            let stream =
+                get_stream_handle_from_connect_req(connect_req_ptr);
+            if (status == 0i32) {
+                log(debug, ~"on_connect_cb: in status=0 if..");
+                let client_data = get_data_for_req(
+                    connect_req_ptr as *libc::c_void)
+                    as *request_wrapper;
+                let write_handle = (*client_data).write_req;
+                log(debug, fmt!("on_connect_cb: tcp: %d write_hdl: %d",
+                                stream as int, write_handle as int));
+                let write_result = write(write_handle,
+                                  stream as *libc::c_void,
+                                  (*client_data).req_buf,
+                                  on_write_complete_cb);
+                log(debug, fmt!("on_connect_cb: write() status: %d",
+                                 write_result as int));
+            }
+            else {
+                let test_loop = get_loop_for_uv_handle(
+                    stream as *libc::c_void);
+                let err_msg = get_last_err_info(test_loop);
+                log(debug, err_msg);
+                fail_unless!(false);
+            }
+            log(debug, ~"finishing on_connect_cb");
+        }
+    }
+
+    fn impl_uv_tcp_request(ip: &str, port: int, req_str: &str,
+                          client_chan: SharedChan<~str>) {
+        unsafe {
+            let test_loop = loop_new();
+            let tcp_handle = tcp_t();
+            let tcp_handle_ptr = ptr::addr_of(&tcp_handle);
+            let connect_handle = connect_t();
+            let connect_req_ptr = ptr::addr_of(&connect_handle);
+
+            // this is the persistent payload of data that we
+            // need to pass around to get this example to work.
+            // In C, this would be a malloc'd or stack-allocated
+            // struct that we'd cast to a void* and store as the
+            // data field in our uv_connect_t struct
+            let req_str_bytes = str::to_bytes(req_str);
+            let req_msg_ptr: *u8 = vec::raw::to_ptr(req_str_bytes);
+            log(debug, fmt!("req_msg ptr: %u", req_msg_ptr as uint));
+            let req_msg = ~[
+                buf_init(req_msg_ptr, vec::len(req_str_bytes))
+            ];
+            // this is the enclosing record, we'll pass a ptr to
+            // this to C..
+            let write_handle = write_t();
+            let write_handle_ptr = ptr::addr_of(&write_handle);
+            log(debug, fmt!("tcp req: tcp stream: %d write_handle: %d",
+                             tcp_handle_ptr as int,
+                             write_handle_ptr as int));
+            let client_data = request_wrapper {
+                write_req: write_handle_ptr,
+                req_buf: ptr::addr_of(&req_msg),
+                read_chan: client_chan
+            };
+
+            let tcp_init_result = tcp_init(
+                test_loop as *libc::c_void, tcp_handle_ptr);
+            if (tcp_init_result == 0i32) {
+                log(debug, ~"sucessful tcp_init_result");
+
+                log(debug, ~"building addr...");
+                let addr = ip4_addr(ip, port);
+                // FIXME ref #2064
+                let addr_ptr = ptr::addr_of(&addr);
+                log(debug, fmt!("after build addr in rust. port: %u",
+                                 addr.sin_port as uint));
+
+                // this should set up the connection request..
+                log(debug, fmt!("b4 call tcp_connect connect cb: %u ",
+                                on_connect_cb as uint));
+                let tcp_connect_result = tcp_connect(
+                    connect_req_ptr, tcp_handle_ptr,
+                    addr_ptr, on_connect_cb);
+                if (tcp_connect_result == 0i32) {
+                    // not set the data on the connect_req
+                    // until its initialized
+                    set_data_for_req(
+                        connect_req_ptr as *libc::c_void,
+                        ptr::addr_of(&client_data) as *libc::c_void);
+                    set_data_for_uv_handle(
+                        tcp_handle_ptr as *libc::c_void,
+                        ptr::addr_of(&client_data) as *libc::c_void);
+                    log(debug, ~"before run tcp req loop");
+                    run(test_loop);
+                    log(debug, ~"after run tcp req loop");
+                }
+                else {
+                   log(debug, ~"tcp_connect() failure");
+                   fail_unless!(false);
+                }
+            }
+            else {
+                log(debug, ~"tcp_init() failure");
+                fail_unless!(false);
+            }
+            loop_delete(test_loop);
+        }
+    }
+
+    extern fn server_after_close_cb(handle: *libc::c_void) {
+        unsafe {
+            log(debug, fmt!("SERVER server stream closed, should exit. h: %?",
+                       handle));
+        }
+    }
+
+    extern fn client_stream_after_close_cb(handle: *libc::c_void) {
+        unsafe {
+            log(debug,
+                ~"SERVER: closed client stream, now closing server stream");
+            let client_data = get_data_for_uv_handle(
+                handle) as
+                *tcp_server_data;
+            close((*client_data).server as *libc::c_void,
+                          server_after_close_cb);
+        }
+    }
+
+    extern fn after_server_resp_write(req: *uv_write_t) {
+        unsafe {
+            let client_stream_ptr =
+                get_stream_handle_from_write_req(req);
+            log(debug, ~"SERVER: resp sent... closing client stream");
+            close(client_stream_ptr as *libc::c_void,
+                          client_stream_after_close_cb)
+        }
+    }
+
+    extern fn on_server_read_cb(client_stream_ptr: *uv_stream_t,
+                               nread: libc::ssize_t,
+                               ++buf: uv_buf_t) {
+        unsafe {
+            let nread = nread as int;
+            if (nread > 0) {
+                // we have data
+                log(debug, fmt!("SERVER read: data! nread: %d", nread));
+
+                // pull out the contents of the write from the client
+                let buf_base = get_base_from_buf(buf);
+                let buf_len = get_len_from_buf(buf) as uint;
+                log(debug, fmt!("SERVER buf base: %u, len: %u, nread: %d",
+                                buf_base as uint,
+                                buf_len as uint,
+                                nread));
+                let bytes = vec::from_buf(buf_base, nread as uint);
+                let request_str = str::from_bytes(bytes);
+
+                let client_data = get_data_for_uv_handle(
+                    client_stream_ptr as *libc::c_void) as *tcp_server_data;
+
+                let server_kill_msg = copy (*client_data).server_kill_msg;
+                let write_req = (*client_data).server_write_req;
+                if str::contains(request_str, server_kill_msg) {
+                    log(debug, ~"SERVER: client req contains kill_msg!");
+                    log(debug, ~"SERVER: sending response to client");
+                    read_stop(client_stream_ptr);
+                    let server_chan = (*client_data).server_chan.clone();
+                    server_chan.send(request_str);
+                    let write_result = write(
+                        write_req,
+                        client_stream_ptr as *libc::c_void,
+                        (*client_data).server_resp_buf,
+                        after_server_resp_write);
+                    log(debug, fmt!("SERVER: resp write result: %d",
+                                write_result as int));
+                    if (write_result != 0i32) {
+                        log(debug, ~"bad result for server resp write()");
+                        log(debug, get_last_err_info(
+                            get_loop_for_uv_handle(client_stream_ptr
+                                as *libc::c_void)));
+                        fail_unless!(false);
+                    }
+                }
+                else {
+                    log(debug, ~"SERVER: client req !contain kill_msg!");
+                }
+            }
+            else if (nread == -1) {
+                // err .. possibly EOF
+                log(debug, ~"read: eof!");
+            }
+            else {
+                // nread == 0 .. do nothing, just free buf as below
+                log(debug, ~"read: do nothing!");
+            }
+            // when we're done
+            free_base_of_buf(buf);
+            log(debug, ~"SERVER exiting on_read_cb");
+        }
+    }
+
+    extern fn server_connection_cb(server_stream_ptr:
+                                    *uv_stream_t,
+                                  status: libc::c_int) {
+        unsafe {
+            log(debug, ~"client connecting!");
+            let test_loop = get_loop_for_uv_handle(
+                                   server_stream_ptr as *libc::c_void);
+            if status != 0i32 {
+                let err_msg = get_last_err_info(test_loop);
+                log(debug, fmt!("server_connect_cb: non-zero status: %?",
+                             err_msg));
+                return;
+            }
+            let server_data = get_data_for_uv_handle(
+                server_stream_ptr as *libc::c_void) as *tcp_server_data;
+            let client_stream_ptr = (*server_data).client;
+            let client_init_result = tcp_init(test_loop,
+                                                      client_stream_ptr);
+            set_data_for_uv_handle(
+                client_stream_ptr as *libc::c_void,
+                server_data as *libc::c_void);
+            if (client_init_result == 0i32) {
+                log(debug, ~"successfully initialized client stream");
+                let accept_result = accept(server_stream_ptr as
+                                                     *libc::c_void,
+                                                   client_stream_ptr as
+                                                     *libc::c_void);
+                if (accept_result == 0i32) {
+                    // start reading
+                    let read_result = read_start(
+                        client_stream_ptr as *uv_stream_t,
+                                                         on_alloc_cb,
+                                                         on_server_read_cb);
+                    if (read_result == 0i32) {
+                        log(debug, ~"successful server read start");
+                    }
+                    else {
+                        log(debug, fmt!("server_connection_cb: bad read:%d",
+                                        read_result as int));
+                        fail_unless!(false);
+                    }
+                }
+                else {
+                    log(debug, fmt!("server_connection_cb: bad accept: %d",
+                                accept_result as int));
+                    fail_unless!(false);
+                }
+            }
+            else {
+                log(debug, fmt!("server_connection_cb: bad client init: %d",
+                            client_init_result as int));
+                fail_unless!(false);
+            }
+        }
+    }
+
+    struct tcp_server_data {
+        client: *uv_tcp_t,
+        server: *uv_tcp_t,
+        server_kill_msg: ~str,
+        server_resp_buf: *~[uv_buf_t],
+        server_chan: SharedChan<~str>,
+        server_write_req: *uv_write_t,
+    }
+
+    struct async_handle_data {
+        continue_chan: SharedChan<bool>,
+    }
+
+    extern fn async_close_cb(handle: *libc::c_void) {
+        log(debug, fmt!("SERVER: closing async cb... h: %?",
+                   handle));
+    }
+
+    extern fn continue_async_cb(async_handle: *uv_async_t,
+                               status: libc::c_int) {
+        unsafe {
+            // once we're in the body of this callback,
+            // the tcp server's loop is set up, so we
+            // can continue on to let the tcp client
+            // do its thang
+            let data = get_data_for_uv_handle(
+                async_handle as *libc::c_void) as *async_handle_data;
+            let continue_chan = (*data).continue_chan.clone();
+            let should_continue = status == 0i32;
+            continue_chan.send(should_continue);
+            close(async_handle as *libc::c_void, async_close_cb);
+        }
+    }
+
+    fn impl_uv_tcp_server(server_ip: &str,
+                          server_port: int,
+                          kill_server_msg: ~str,
+                          server_resp_msg: ~str,
+                          server_chan: SharedChan<~str>,
+                          continue_chan: SharedChan<bool>) {
+        unsafe {
+            let test_loop = loop_new();
+            let tcp_server = tcp_t();
+            let tcp_server_ptr = ptr::addr_of(&tcp_server);
+
+            let tcp_client = tcp_t();
+            let tcp_client_ptr = ptr::addr_of(&tcp_client);
+
+            let server_write_req = write_t();
+            let server_write_req_ptr = ptr::addr_of(&server_write_req);
+
+            let resp_str_bytes = str::to_bytes(server_resp_msg);
+            let resp_msg_ptr: *u8 = vec::raw::to_ptr(resp_str_bytes);
+            log(debug, fmt!("resp_msg ptr: %u", resp_msg_ptr as uint));
+            let resp_msg = ~[
+                buf_init(resp_msg_ptr, vec::len(resp_str_bytes))
+            ];
+
+            let continue_async_handle = async_t();
+            let continue_async_handle_ptr =
+                ptr::addr_of(&continue_async_handle);
+            let async_data =
+                async_handle_data { continue_chan: continue_chan };
+            let async_data_ptr = ptr::addr_of(&async_data);
+
+            let server_data = tcp_server_data {
+                client: tcp_client_ptr,
+                server: tcp_server_ptr,
+                server_kill_msg: kill_server_msg,
+                server_resp_buf: ptr::addr_of(&resp_msg),
+                server_chan: server_chan,
+                server_write_req: server_write_req_ptr
+            };
+            let server_data_ptr = ptr::addr_of(&server_data);
+            set_data_for_uv_handle(tcp_server_ptr as *libc::c_void,
+                                           server_data_ptr as *libc::c_void);
+
+            // uv_tcp_init()
+            let tcp_init_result = tcp_init(
+                test_loop as *libc::c_void, tcp_server_ptr);
+            if (tcp_init_result == 0i32) {
+                let server_addr = ip4_addr(server_ip, server_port);
+                // FIXME ref #2064
+                let server_addr_ptr = ptr::addr_of(&server_addr);
+
+                // uv_tcp_bind()
+                let bind_result = tcp_bind(tcp_server_ptr,
+                                                   server_addr_ptr);
+                if (bind_result == 0i32) {
+                    log(debug, ~"successful uv_tcp_bind, listening");
+
+                    // uv_listen()
+                    let listen_result = listen(tcp_server_ptr as
+                                                         *libc::c_void,
+                                                       128i32,
+                                                       server_connection_cb);
+                    if (listen_result == 0i32) {
+                        // let the test know it can set up the tcp server,
+                        // now.. this may still present a race, not sure..
+                        let async_result = async_init(test_loop,
+                                           continue_async_handle_ptr,
+                                           continue_async_cb);
+                        if (async_result == 0i32) {
+                            set_data_for_uv_handle(
+                                continue_async_handle_ptr as *libc::c_void,
+                                async_data_ptr as *libc::c_void);
+                            async_send(continue_async_handle_ptr);
+                            // uv_run()
+                            run(test_loop);
+                            log(debug, ~"server uv::run() has returned");
+                        }
+                        else {
+                            log(debug, fmt!("uv_async_init failure: %d",
+                                    async_result as int));
+                            fail_unless!(false);
+                        }
+                    }
+                    else {
+                        log(debug, fmt!("non-zero result on uv_listen: %d",
+                                    listen_result as int));
+                        fail_unless!(false);
+                    }
+                }
+                else {
+                    log(debug, fmt!("non-zero result on uv_tcp_bind: %d",
+                                bind_result as int));
+                    fail_unless!(false);
+                }
+            }
+            else {
+                log(debug, fmt!("non-zero result on uv_tcp_init: %d",
+                            tcp_init_result as int));
+                fail_unless!(false);
+            }
+            loop_delete(test_loop);
+        }
+    }
+
+    // this is the impl for a test that is (maybe) ran on a
+    // per-platform/arch basis below
+    pub fn impl_uv_tcp_server_and_request() {
+        unsafe {
+            let bind_ip = ~"0.0.0.0";
+            let request_ip = ~"127.0.0.1";
+            let port = 8886;
+            let kill_server_msg = ~"does a dog have buddha nature?";
+            let server_resp_msg = ~"mu!";
+            let (client_port, client_chan) = stream::<~str>();
+            let client_chan = SharedChan(client_chan);
+            let (server_port, server_chan) = stream::<~str>();
+            let server_chan = SharedChan(server_chan);
+
+            let (continue_port, continue_chan) = stream::<bool>();
+            let continue_chan = SharedChan(continue_chan);
+
+            let kill_server_msg_copy = copy kill_server_msg;
+            let server_resp_msg_copy = copy server_resp_msg;
+            do task::spawn_sched(task::ManualThreads(1)) {
+                impl_uv_tcp_server(bind_ip, port,
+                                   copy kill_server_msg_copy,
+                                   copy server_resp_msg_copy,
+                                   server_chan.clone(),
+                                   continue_chan.clone());
+            };
+
+            // block until the server up is.. possibly a race?
+            log(debug, ~"before receiving on server continue_port");
+            continue_port.recv();
+            log(debug, ~"received on continue port, set up tcp client");
+
+            let kill_server_msg_copy = copy kill_server_msg;
+            do task::spawn_sched(task::ManualThreads(1u)) {
+                impl_uv_tcp_request(request_ip, port,
+                                   kill_server_msg_copy,
+                                   client_chan.clone());
+            };
+
+            let msg_from_client = server_port.recv();
+            let msg_from_server = client_port.recv();
+
+            fail_unless!(str::contains(msg_from_client, kill_server_msg));
+            fail_unless!(str::contains(msg_from_server, server_resp_msg));
+        }
+    }
+
+    // FIXME don't run on fbsd or linux 32 bit(#2064)
+    #[cfg(target_os="win32")]
+    #[cfg(target_os="darwin")]
+    #[cfg(target_os="linux")]
+    #[cfg(target_os="android")]
+    pub mod tcp_and_server_client_test {
+        #[cfg(target_arch="x86_64")]
+        pub mod impl64 {
+            #[test]
+            pub fn test_uv_ll_tcp_server_and_request() {
+                unsafe {
+                    super::super::impl_uv_tcp_server_and_request();
+                }
+            }
+        }
+        #[cfg(target_arch="x86")]
+        #[cfg(target_arch="arm")]
+        #[cfg(target_arch="mips")]
+        pub mod impl32 {
+            #[test]
+            #[ignore(cfg(target_os = "linux"))]
+            pub fn test_uv_ll_tcp_server_and_request() {
+                unsafe {
+                    super::super::impl_uv_tcp_server_and_request();
+                }
+            }
+        }
+    }
+
+    fn struct_size_check_common<TStruct>(t_name: ~str,
+                                         foreign_size: libc::c_uint) {
+        unsafe {
+            let rust_size = sys::size_of::<TStruct>();
+            let sizes_match = foreign_size as uint == rust_size;
+            if !sizes_match {
+                let output = fmt!(
+                    "STRUCT_SIZE FAILURE: %s -- actual: %u expected: %u",
+                    t_name, rust_size, foreign_size as uint);
+                log(debug, output);
+            }
+            fail_unless!(sizes_match);
+        }
+    }
+
+    // struct size tests
+    #[test]
+    fn test_uv_ll_struct_size_uv_tcp_t() {
+        unsafe {
+            struct_size_check_common::<uv_tcp_t>(
+                ~"uv_tcp_t",
+                super::rustrt::rust_uv_helper_uv_tcp_t_size()
+            );
+        }
+    }
+    #[test]
+    fn test_uv_ll_struct_size_uv_connect_t() {
+        unsafe {
+            struct_size_check_common::<uv_connect_t>(
+                ~"uv_connect_t",
+                super::rustrt::rust_uv_helper_uv_connect_t_size()
+            );
+        }
+    }
+    #[test]
+    fn test_uv_ll_struct_size_uv_buf_t() {
+        unsafe {
+            struct_size_check_common::<uv_buf_t>(
+                ~"uv_buf_t",
+                super::rustrt::rust_uv_helper_uv_buf_t_size()
+            );
+        }
+    }
+    #[test]
+    fn test_uv_ll_struct_size_uv_write_t() {
+        unsafe {
+            struct_size_check_common::<uv_write_t>(
+                ~"uv_write_t",
+                super::rustrt::rust_uv_helper_uv_write_t_size()
+            );
+        }
+    }
+
+    #[test]
+    fn test_uv_ll_struct_size_sockaddr_in() {
+        unsafe {
+            struct_size_check_common::<sockaddr_in>(
+                ~"sockaddr_in",
+                super::rustrt::rust_uv_helper_sockaddr_in_size()
+            );
+        }
+    }
+    #[test]
+    fn test_uv_ll_struct_size_sockaddr_in6() {
+        unsafe {
+            let foreign_handle_size =
+                super::rustrt::rust_uv_helper_sockaddr_in6_size();
+            let rust_handle_size = sys::size_of::<sockaddr_in6>();
+            let output = fmt!("sockaddr_in6 -- foreign: %u rust: %u",
+                              foreign_handle_size as uint, rust_handle_size);
+            log(debug, output);
+            // FIXME #1645 .. rust appears to pad structs to the nearest
+            // byte..?
+            // .. can't get the uv::ll::sockaddr_in6 to == 28 :/
+            // .. so the type always appears to be 32 in size.. which is
+            // good, i guess.. better too big than too little
+            fail_unless!((4u+foreign_handle_size as uint) ==
+                rust_handle_size);
+        }
+    }
+    #[test]
+    #[ignore(reason = "questionable size calculations")]
+    fn test_uv_ll_struct_size_addr_in() {
+        unsafe {
+            let foreign_handle_size =
+                super::rustrt::rust_uv_helper_addr_in_size();
+            let rust_handle_size = sys::size_of::<addr_in>();
+            let output = fmt!("addr_in -- foreign: %u rust: %u",
+                              foreign_handle_size as uint, rust_handle_size);
+            log(debug, output);
+            // FIXME #1645 .. see note above about struct padding
+            fail_unless!((4u+foreign_handle_size as uint) ==
+                rust_handle_size);
+        }
+    }
+
+    #[test]
+    fn test_uv_ll_struct_size_uv_async_t() {
+        unsafe {
+            struct_size_check_common::<uv_async_t>(
+                ~"uv_async_t",
+                super::rustrt::rust_uv_helper_uv_async_t_size()
+            );
+        }
+    }
+
+    #[test]
+    fn test_uv_ll_struct_size_uv_timer_t() {
+        unsafe {
+            struct_size_check_common::<uv_timer_t>(
+                ~"uv_timer_t",
+                super::rustrt::rust_uv_helper_uv_timer_t_size()
+            );
+        }
+    }
+
+    #[test]
+    #[ignore(cfg(target_os = "win32"))]
+    fn test_uv_ll_struct_size_uv_getaddrinfo_t() {
+        unsafe {
+            struct_size_check_common::<uv_getaddrinfo_t>(
+                ~"uv_getaddrinfo_t",
+                super::rustrt::rust_uv_helper_uv_getaddrinfo_t_size()
+            );
+        }
+    }
+    #[test]
+    #[ignore(cfg(target_os = "macos"))]
+    #[ignore(cfg(target_os = "win32"))]
+    fn test_uv_ll_struct_size_addrinfo() {
+        unsafe {
+            struct_size_check_common::<uv_timer_t>(
+                ~"addrinfo",
+                super::rustrt::rust_uv_helper_uv_timer_t_size()
+            );
+        }
+    }
+}

From 723d2247c1e310a49dd49afc80e7c8a153bd1432 Mon Sep 17 00:00:00 2001
From: Brian Anderson <banderson@mozilla.com>
Date: Tue, 12 Mar 2013 15:40:32 -0700
Subject: [PATCH 03/12] core: Don't use printf in rtdebug!

The bots were showing a segfault that I can't reproduce. Assuming it's
varargs related so let's not use printf
---
 src/libcore/rt/mod.rs | 14 ++++----------
 1 file changed, 4 insertions(+), 10 deletions(-)

diff --git a/src/libcore/rt/mod.rs b/src/libcore/rt/mod.rs
index e48367d7202..556431e9315 100644
--- a/src/libcore/rt/mod.rs
+++ b/src/libcore/rt/mod.rs
@@ -15,16 +15,10 @@ macro_rules! rtdebug_ (
         dumb_println(fmt!( $($arg),+ ));
 
         fn dumb_println(s: &str) {
-            use str::as_c_str;
-            use libc::c_char;
-
-            extern {
-                fn printf(s: *c_char);
-            }
-
-            do as_c_str(s.to_str() + "\n") |s| {
-                unsafe { printf(s); }
-            }
+            use io::WriterUtil;
+            let dbg = ::libc::STDERR_FILENO as ::io::fd_t;
+            dbg.write_str(s);
+            dbg.write_str("\n");
         }
 
     } )

From 54bb7226e16090b471d791af5615016d01000504 Mon Sep 17 00:00:00 2001
From: Brian Anderson <banderson@mozilla.com>
Date: Tue, 12 Mar 2013 20:04:25 -0700
Subject: [PATCH 04/12] core: Simplify uvll bindings and strip out
 currently-unused bits

No more mapping uv structs to Rust structs
---
 src/libcore/rt/uv.rs   |   56 +-
 src/libcore/rt/uvll.rs | 2043 ++++++----------------------------------
 src/libstd/uv_ll.rs    |   18 -
 src/rt/rust_uv.cpp     |   48 +
 src/rt/rustrt.def.in   |    9 +
 5 files changed, 379 insertions(+), 1795 deletions(-)

diff --git a/src/libcore/rt/uv.rs b/src/libcore/rt/uv.rs
index c450a631955..8280359eb2b 100644
--- a/src/libcore/rt/uv.rs
+++ b/src/libcore/rt/uv.rs
@@ -44,21 +44,28 @@ use cast::{transmute, transmute_mut_region};
 use ptr::null;
 use sys::size_of;
 use super::uvll;
+use super::uvll::*;
 use super::io::{IpAddr, Ipv4, Ipv6};
+use unstable::finally::Finally;
 
 #[cfg(test)] use unstable::run_in_bare_thread;
 #[cfg(test)] use super::thread::Thread;
 #[cfg(test)] use cell::Cell;
 
-fn ip4_to_uv_ip4(addr: IpAddr) -> uvll::sockaddr_in {
+fn ip4_as_uv_ip4(addr: IpAddr, f: &fn(*sockaddr_in)) {
     match addr {
         Ipv4(a, b, c, d, p) => {
             unsafe {
-                uvll::ip4_addr(fmt!("%u.%u.%u.%u",
-                                    a as uint,
-                                    b as uint,
-                                    c as uint,
-                                    d as uint), p as int)
+                let addr = malloc_ip4_addr(fmt!("%u.%u.%u.%u",
+                                                a as uint,
+                                                b as uint,
+                                                c as uint,
+                                                d as uint), p as int);
+                do (|| {
+                    f(addr);
+                }).finally {
+                    free_ip4_addr(addr);
+                }
             }
         }
         Ipv6 => fail!()
@@ -301,7 +308,7 @@ pub impl StreamWatcher {
                 data.close_cb.swap_unwrap()();
             }
             drop_watcher_data(&mut stream_watcher);
-            unsafe { free(handle as *c_void) }
+            unsafe { free_handle(handle as *c_void) }
         }
     }
 }
@@ -330,8 +337,7 @@ impl Callback for ConnectionCallback { }
 pub impl TcpWatcher {
     static fn new(loop_: &mut Loop) -> TcpWatcher {
         unsafe {
-            let size = size_of::<uvll::uv_tcp_t>() as size_t;
-            let handle = malloc(size) as *uvll::uv_tcp_t;
+            let handle = malloc_handle(UV_TCP);
             fail_unless!(handle.is_not_null());
             fail_unless!(0 == uvll::tcp_init(loop_.native_handle(), handle));
             let mut watcher = NativeHandle::from_native_handle(handle);
@@ -343,12 +349,13 @@ pub impl TcpWatcher {
     fn bind(&mut self, address: IpAddr) {
         match address {
             Ipv4(*) => {
-                let addr = ip4_to_uv_ip4(address);
-                let result = unsafe {
-                    uvll::tcp_bind(self.native_handle(), &addr)
-                };
-                // XXX: bind is likely to fail. need real error handling
-                fail_unless!(result == 0);
+                do ip4_as_uv_ip4(address) |addr| {
+                    let result = unsafe {
+                        uvll::tcp_bind(self.native_handle(), addr)
+                    };
+                    // XXX: bind is likely to fail. need real error handling
+                    fail_unless!(result == 0);
+                }
             }
             _ => fail!()
         }
@@ -363,11 +370,12 @@ pub impl TcpWatcher {
             let connect_handle = connect_watcher.native_handle();
             match address {
                 Ipv4(*) => {
-                    let addr = ip4_to_uv_ip4(address);
-                    rtdebug!("connect_t: %x", connect_handle as uint);
-                    fail_unless!(0 == uvll::tcp_connect(connect_handle,
-                                                        self.native_handle(),
-                                                        &addr, connect_cb));
+                    do ip4_as_uv_ip4(address) |addr| {
+                        rtdebug!("connect_t: %x", connect_handle as uint);
+                        fail_unless!(0 == uvll::tcp_connect(connect_handle,
+                                                            self.native_handle(),
+                                                            addr, connect_cb));
+                    }
                 }
                 _ => fail!()
             }
@@ -443,7 +451,7 @@ impl ConnectRequest {
 
     static fn new() -> ConnectRequest {
         let connect_handle = unsafe {
-            malloc(size_of::<uvll::uv_connect_t>() as size_t)
+            malloc_req(UV_CONNECT)
         };
         fail_unless!(connect_handle.is_not_null());
         let connect_handle = connect_handle as *uvll::uv_connect_t;
@@ -460,7 +468,7 @@ impl ConnectRequest {
     }
 
     fn delete(self) {
-        unsafe { free(self.native_handle() as *c_void) }
+        unsafe { free_req(self.native_handle() as *c_void) }
     }
 }
 
@@ -482,7 +490,7 @@ impl WriteRequest {
 
     static fn new() -> WriteRequest {
         let write_handle = unsafe {
-            malloc(size_of::<uvll::uv_write_t>() as size_t)
+            malloc_req(UV_WRITE)
         };
         fail_unless!(write_handle.is_not_null());
         let write_handle = write_handle as *uvll::uv_write_t;
@@ -498,7 +506,7 @@ impl WriteRequest {
     }
 
     fn delete(self) {
-        unsafe { free(self.native_handle() as *c_void) }
+        unsafe { free_req(self.native_handle() as *c_void) }
     }
 }
 
diff --git a/src/libcore/rt/uvll.rs b/src/libcore/rt/uvll.rs
index 80f04cf4ac0..1332ddf1127 100644
--- a/src/libcore/rt/uvll.rs
+++ b/src/libcore/rt/uvll.rs
@@ -14,1190 +14,356 @@
  * This module contains a set of direct, 'bare-metal' wrappers around
  * the libuv C-API.
  *
- * Also contained herein are a set of rust records that map, in
- * approximate memory-size, to the libuv data structures. The record
- * implementations are adjusted, per-platform, to match their respective
- * representations.
+ * We're not bothering yet to redefine uv's structs as Rust structs
+ * because they are quite large and change often between versions.
+ * The maintenance burden is just too high. Instead we use the uv's
+ * `uv_handle_size` and `uv_req_size` to find the correct size of the
+ * structs and allocate them on the heap. This can be revisited later.
  *
  * There are also a collection of helper functions to ease interacting
- * with the low-level API (such as a function to return the latest
- * libuv error as a rust-formatted string).
+ * with the low-level API.
  *
  * As new functionality, existant in uv.h, is added to the rust stdlib,
  * the mappings should be added in this module.
- *
- * This module's implementation will hopefully be, eventually, replaced
- * with per-platform, generated source files from rust-bindgen.
  */
 
 #[allow(non_camel_case_types)]; // C types
 
-use libc::size_t;
-use libc::c_void;
+use libc::{size_t, c_int, c_uint, c_void, c_char, uintptr_t};
+use libc::{malloc, free};
 use prelude::*;
 use ptr::to_unsafe_ptr;
 
-pub type uv_handle_t = c_void;
-pub type uv_loop_t = c_void;
-pub type uv_idle_t = c_void;
-pub type uv_idle_cb = *u8;
-
-// libuv struct mappings
-pub struct uv_ip4_addr {
-    ip: ~[u8],
-    port: int,
-}
-pub type uv_ip6_addr = uv_ip4_addr;
-
-pub enum uv_handle_type {
-    UNKNOWN_HANDLE = 0,
-    UV_TCP,
-    UV_UDP,
-    UV_NAMED_PIPE,
-    UV_TTY,
-    UV_FILE,
-    UV_TIMER,
-    UV_PREPARE,
-    UV_CHECK,
-    UV_IDLE,
-    UV_ASYNC,
-    UV_ARES_TASK,
-    UV_ARES_EVENT,
-    UV_PROCESS,
-    UV_FS_EVENT
-}
-
-pub type handle_type = libc::c_uint;
-
-pub struct uv_handle_fields {
-   loop_handle: *libc::c_void,
-   type_: handle_type,
-   close_cb: *u8,
-   data: *libc::c_void,
-}
-
-// unix size: 8
 pub struct uv_err_t {
-    code: libc::c_int,
-    sys_errno_: libc::c_int
+    code: c_int,
+    sys_errno_: c_int
 }
 
-// don't create one of these directly. instead,
-// count on it appearing in libuv callbacks or embedded
-// in other types as a pointer to be used in other
-// operations (so mostly treat it as opaque, once you
-// have it in this form..)
-pub struct uv_stream_t {
-    fields: uv_handle_fields,
-}
-
-// 64bit unix size: 216
-#[cfg(target_os="macos")]
-pub struct uv_tcp_t {
-    fields: uv_handle_fields,
-    a00: *u8, a01: *u8, a02: *u8, a03: *u8,
-    a04: *u8, a05: *u8, a06: *u8, a07: *u8,
-    a08: *u8, a09: *u8, a10: *u8, a11: *u8,
-    a12: *u8, a13: *u8, a14: *u8, a15: *u8,
-    a16: *u8, a17: *u8, a18: *u8, a19: *u8,
-    a20: *u8, a21: *u8, a22: *u8,
-    a23: uv_tcp_t_osx_riders
-}
-#[cfg(target_arch="x86_64")]
-pub struct uv_tcp_t_osx_riders {
-    a23: *u8,
-}
-#[cfg(target_arch="x86")]
-#[cfg(target_arch="arm")]
-pub struct uv_tcp_t_osx_riders {
-    a23: *u8,
-    a24: *u8, a25: *u8,
-}
-#[cfg(target_os="linux")]
-#[cfg(target_os="freebsd")]
-#[cfg(target_os="android")]
-pub struct uv_tcp_t {
-    fields: uv_handle_fields,
-    a00: *u8, a01: *u8, a02: *u8, a03: *u8,
-    a04: *u8, a05: *u8, a06: *u8, a07: *u8,
-    a08: *u8, a09: *u8, a10: *u8, a11: *u8,
-    a12: *u8, a13: *u8, a14: *u8, a15: *u8,
-    a16: *u8, a17: *u8, a18: *u8, a19: *u8,
-    a20: *u8, a21: *u8,
-    a22: uv_tcp_t_32bit_unix_riders,
-}
-// 32bit unix size: 328 (164)
-#[cfg(target_arch="x86_64")]
-pub struct uv_tcp_t_32bit_unix_riders {
-    a29: *u8,
-}
-#[cfg(target_arch="x86")]
-#[cfg(target_arch="arm")]
-#[cfg(target_arch="mips")]
-pub struct uv_tcp_t_32bit_unix_riders {
-    a29: *u8, a30: *u8, a31: *u8,
-}
-
-// 32bit win32 size: 240 (120)
-#[cfg(windows)]
-pub struct uv_tcp_t {
-    fields: uv_handle_fields,
-    a00: *u8, a01: *u8, a02: *u8, a03: *u8,
-    a04: *u8, a05: *u8, a06: *u8, a07: *u8,
-    a08: *u8, a09: *u8, a10: *u8, a11: *u8,
-    a12: *u8, a13: *u8, a14: *u8, a15: *u8,
-    a16: *u8, a17: *u8, a18: *u8, a19: *u8,
-    a20: *u8, a21: *u8, a22: *u8, a23: *u8,
-    a24: *u8, a25: *u8,
-}
-
-// unix size: 64
-#[cfg(unix)]
-pub struct uv_connect_t {
-    a00: *u8, a01: *u8, a02: *u8, a03: *u8,
-    a04: *u8, a05: *u8, a06: *u8, a07: *u8
-}
-// win32 size: 88 (44)
-#[cfg(windows)]
-pub struct uv_connect_t {
-    a00: *u8, a01: *u8, a02: *u8, a03: *u8,
-    a04: *u8, a05: *u8, a06: *u8, a07: *u8,
-    a08: *u8, a09: *u8, a10: *u8,
-}
-
-// unix size: 16
 pub struct uv_buf_t {
     base: *u8,
     len: libc::size_t,
 }
-// no gen stub method.. should create
-// it via uv::direct::buf_init()
 
-// unix size: 160
-#[cfg(unix)]
-pub struct uv_write_t {
-    fields: uv_handle_fields,
-    a00: *u8, a01: *u8, a02: *u8, a03: *u8,
-    a04: *u8, a05: *u8, a06: *u8, a07: *u8,
-    a08: *u8, a09: *u8, a10: *u8, a11: *u8,
-    a12: *u8,
-    a14: uv_write_t_32bit_unix_riders,
-}
-#[cfg(target_arch="x86_64")]
-pub struct uv_write_t_32bit_unix_riders {
-    a13: *u8, a14: *u8, a15: *u8
-}
-#[cfg(target_arch="x86")]
-#[cfg(target_arch="arm")]
-#[cfg(target_arch="mips")]
-pub struct uv_write_t_32bit_unix_riders {
-    a13: *u8, a14: *u8, a15: *u8,
-    a16: *u8,
-}
-// win32 size: 136 (68)
-#[cfg(windows)]
-pub struct uv_write_t {
-    fields: uv_handle_fields,
-    a00: *u8, a01: *u8, a02: *u8, a03: *u8,
-    a04: *u8, a05: *u8, a06: *u8, a07: *u8,
-    a08: *u8, a09: *u8, a10: *u8, a11: *u8,
-    a12: *u8,
-}
-// 64bit unix size: 96
-// 32bit unix size: 152 (76)
-#[cfg(unix)]
-pub struct uv_async_t {
-    fields: uv_handle_fields,
-    a00: *u8, a01: *u8, a02: *u8, a03: *u8,
-    a04: *u8, a05: *u8, a06: *u8,
-    a07: uv_async_t_32bit_unix_riders,
-}
-#[cfg(target_arch="x86_64")]
-pub struct uv_async_t_32bit_unix_riders {
-    a10: *u8,
-}
-#[cfg(target_arch="x86")]
-#[cfg(target_arch="arm")]
-#[cfg(target_arch="mips")]
-pub struct uv_async_t_32bit_unix_riders {
-    a10: *u8,
-}
-// win32 size 132 (68)
-#[cfg(windows)]
-pub struct uv_async_t {
-    fields: uv_handle_fields,
-    a00: *u8, a01: *u8, a02: *u8, a03: *u8,
-    a04: *u8, a05: *u8, a06: *u8, a07: *u8,
-    a08: *u8, a09: *u8, a10: *u8, a11: *u8,
-    a12: *u8,
+pub type uv_handle_t = c_void;
+pub type uv_loop_t = c_void;
+pub type uv_idle_t = c_void;
+pub type uv_tcp_t = c_void;
+pub type uv_connect_t = c_void;
+pub type uv_write_t = c_void;
+pub type uv_async_t = c_void;
+pub type uv_timer_t = c_void;
+pub type uv_stream_t = c_void;
+
+pub type uv_idle_cb = *u8;
+
+pub type sockaddr_in = c_void;
+pub type sockaddr_in6 = c_void;
+
+#[deriving_eq]
+pub enum uv_handle_type {
+    UV_UNKNOWN_HANDLE,
+    UV_ASYNC,
+    UV_CHECK,
+    UV_FS_EVENT,
+    UV_FS_POLL,
+    UV_HANDLE,
+    UV_IDLE,
+    UV_NAMED_PIPE,
+    UV_POLL,
+    UV_PREPARE,
+    UV_PROCESS,
+    UV_STREAM,
+    UV_TCP,
+    UV_TIMER,
+    UV_TTY,
+    UV_UDP,
+    UV_SIGNAL,
+    UV_FILE,
+    UV_HANDLE_TYPE_MAX
 }
 
-// 64bit unix size: 120
-// 32bit unix size: 84
-#[cfg(unix)]
-pub struct uv_timer_t {
-    fields: uv_handle_fields,
-    a00: *u8, a01: *u8, a02: *u8, a03: *u8,
-    a04: *u8, a05: *u8, a06: *u8, a07: *u8,
-    a08: *u8, a09: *u8,
-    a11: uv_timer_t_32bit_unix_riders,
-}
-#[cfg(target_arch="x86_64")]
-pub struct uv_timer_t_32bit_unix_riders {
-    a10: *u8,
-}
-#[cfg(target_arch="x86")]
-#[cfg(target_arch="arm")]
-#[cfg(target_arch="mips")]
-pub struct uv_timer_t_32bit_unix_riders {
-    a10: *u8, a11: *u8, a12: *u8
-}
-// win32 size: 64
-#[cfg(windows)]
-pub struct uv_timer_t {
-    fields: uv_handle_fields,
-    a00: *u8, a01: *u8, a02: *u8, a03: *u8,
-    a04: *u8, a05: *u8, a06: *u8, a07: *u8,
-    a08: *u8, a09: *u8, a10: *u8, a11: *u8,
+#[deriving_eq]
+pub enum uv_req_type {
+    UV_UNKNOWN_REQ,
+    UV_REQ,
+    UV_CONNECT,
+    UV_WRITE,
+    UV_SHUTDOWN,
+    UV_UDP_SEND,
+    UV_FS,
+    UV_WORK,
+    UV_GETADDRINFO,
+    UV_REQ_TYPE_MAX
 }
 
-// unix size: 16
-pub struct sockaddr_in {
-    sin_family: u16,
-    sin_port: u16,
-    sin_addr: u32, // in_addr: this is an opaque, per-platform struct
-    sin_zero: (u8, u8, u8, u8, u8, u8, u8, u8),
+pub unsafe fn malloc_handle(handle: uv_handle_type) -> *c_void {
+    fail_unless!(handle != UV_UNKNOWN_HANDLE && handle != UV_HANDLE_TYPE_MAX);
+    let size = unsafe { rust_uv_handle_size(handle as uint) };
+    let p = malloc(size);
+    fail_unless!(p.is_not_null());
+    return p;
 }
 
-// unix size: 28 .. FIXME #1645
-// stuck with 32 becuse of rust padding structs?
-#[cfg(target_arch="x86_64")]
-pub struct sockaddr_in6 {
-    a0: *u8, a1: *u8,
-    a2: *u8, a3: *u8,
-}
-#[cfg(target_arch="x86")]
-#[cfg(target_arch="arm")]
-#[cfg(target_arch="mips")]
-pub struct sockaddr_in6 {
-    a0: *u8, a1: *u8,
-    a2: *u8, a3: *u8,
-    a4: *u8, a5: *u8,
-    a6: *u8, a7: *u8,
+pub unsafe fn free_handle(v: *c_void) {
+    free(v)
 }
 
-// unix size: 28 .. FIXME #1645
-// stuck with 32 becuse of rust padding structs?
-pub type addr_in = addr_in_impl::addr_in;
-#[cfg(unix)]
-pub mod addr_in_impl {
-    #[cfg(target_arch="x86_64")]
-    pub struct addr_in {
-        a0: *u8, a1: *u8,
-        a2: *u8, a3: *u8,
-    }
-    #[cfg(target_arch="x86")]
-    #[cfg(target_arch="arm")]
-    #[cfg(target_arch="mips")]
-    pub struct addr_in {
-        a0: *u8, a1: *u8,
-        a2: *u8, a3: *u8,
-        a4: *u8, a5: *u8,
-        a6: *u8, a7: *u8,
-    }
+pub unsafe fn malloc_req(req: uv_req_type) -> *c_void {
+    fail_unless!(req != UV_UNKNOWN_REQ && req != UV_REQ_TYPE_MAX);
+    let size = unsafe { rust_uv_req_size(req as uint) };
+    let p = malloc(size);
+    fail_unless!(p.is_not_null());
+    return p;
 }
-#[cfg(windows)]
-pub mod addr_in_impl {
-    pub struct addr_in {
-        a0: *u8, a1: *u8,
-        a2: *u8, a3: *u8,
+
+pub unsafe fn free_req(v: *c_void) {
+    free(v)
+}
+
+#[test]
+fn handle_sanity_check() {
+    unsafe {
+        fail_unless!(UV_HANDLE_TYPE_MAX as uint == rust_uv_handle_type_max());
     }
 }
 
-// unix size: 48, 32bit: 32
-pub type addrinfo = addrinfo_impl::addrinfo;
-#[cfg(target_os="linux")]
-#[cfg(target_os="android")]
-pub mod addrinfo_impl {
-    #[cfg(target_arch="x86_64")]
-    pub struct addrinfo {
-        a00: *u8, a01: *u8, a02: *u8, a03: *u8,
-        a04: *u8, a05: *u8,
-    }
-    #[cfg(target_arch="x86")]
-    #[cfg(target_arch="arm")]
-    #[cfg(target_arch="mips")]
-    pub struct addrinfo {
-        a00: *u8, a01: *u8, a02: *u8, a03: *u8,
-        a04: *u8, a05: *u8, a06: *u8, a07: *u8,
-    }
-}
-#[cfg(target_os="macos")]
-#[cfg(target_os="freebsd")]
-pub mod addrinfo_impl {
-    pub struct addrinfo {
-        a00: *u8, a01: *u8, a02: *u8, a03: *u8,
-        a04: *u8, a05: *u8,
-    }
-}
-#[cfg(windows)]
-pub mod addrinfo_impl {
-    pub struct addrinfo {
-        a00: *u8, a01: *u8, a02: *u8, a03: *u8,
-        a04: *u8, a05: *u8,
+#[test]
+fn request_sanity_check() {
+    unsafe {
+        fail_unless!(UV_REQ_TYPE_MAX as uint == rust_uv_req_type_max());
     }
 }
 
-// unix size: 72
-pub struct uv_getaddrinfo_t {
-    a00: *u8, a01: *u8, a02: *u8, a03: *u8, a04: *u8, a05: *u8,
-    a06: *u8, a07: *u8, a08: *u8, a09: *u8,
-    a10: *u8, a11: *u8, a12: *u8, a13: *u8, a14: *u8, a15: *u8
+pub unsafe fn loop_new() -> *c_void {
+    return rust_uv_loop_new();
 }
 
-pub mod uv_ll_struct_stubgen {
-
-    use ptr;
-
-    use super::{
-        uv_async_t,
-        uv_connect_t,
-        uv_getaddrinfo_t,
-        uv_handle_fields,
-        uv_tcp_t,
-        uv_timer_t,
-        uv_write_t,
-    };
-
-    #[cfg(target_os = "linux")]
-    #[cfg(target_os = "android")]
-    #[cfg(target_os = "macos")]
-    #[cfg(target_os = "freebsd")]
-    use super::{
-        uv_async_t_32bit_unix_riders,
-        uv_tcp_t_32bit_unix_riders,
-        uv_timer_t_32bit_unix_riders,
-        uv_write_t_32bit_unix_riders,
-    };
-
-    pub fn gen_stub_uv_tcp_t() -> uv_tcp_t {
-        return gen_stub_os();
-        #[cfg(target_os = "linux")]
-        #[cfg(target_os = "android")]
-        #[cfg(target_os = "freebsd")]
-        pub fn gen_stub_os() -> uv_tcp_t {
-            return gen_stub_arch();
-            #[cfg(target_arch="x86_64")]
-            pub fn gen_stub_arch() -> uv_tcp_t {
-                uv_tcp_t {
-                    fields: uv_handle_fields {
-                        loop_handle: ptr::null(), type_: 0u32,
-                        close_cb: ptr::null(),
-                        data: ptr::null(),
-                    },
-                    a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
-                    a03: 0 as *u8,
-                    a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
-                    a07: 0 as *u8,
-                    a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
-                    a11: 0 as *u8,
-                    a12: 0 as *u8, a13: 0 as *u8, a14: 0 as *u8,
-                    a15: 0 as *u8,
-                    a16: 0 as *u8, a17: 0 as *u8, a18: 0 as *u8,
-                    a19: 0 as *u8,
-                    a20: 0 as *u8, a21: 0 as *u8,
-                    a22: uv_tcp_t_32bit_unix_riders { a29: 0 as *u8 },
-                }
-            }
-            #[cfg(target_arch="x86")]
-            #[cfg(target_arch="arm")]
-            #[cfg(target_arch="mips")]
-            pub fn gen_stub_arch() -> uv_tcp_t {
-                uv_tcp_t {
-                    fields: uv_handle_fields {
-                        loop_handle: ptr::null(), type_: 0u32,
-                        close_cb: ptr::null(),
-                        data: ptr::null(),
-                    },
-                    a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
-                    a03: 0 as *u8,
-                    a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
-                    a07: 0 as *u8,
-                    a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
-                    a11: 0 as *u8,
-                    a12: 0 as *u8, a13: 0 as *u8, a14: 0 as *u8,
-                    a15: 0 as *u8,
-                    a16: 0 as *u8, a17: 0 as *u8, a18: 0 as *u8,
-                    a19: 0 as *u8,
-                    a20: 0 as *u8, a21: 0 as *u8,
-                    a22: uv_tcp_t_32bit_unix_riders {
-                        a29: 0 as *u8, a30: 0 as *u8, a31: 0 as *u8,
-                    },
-                }
-            }
-        }
-        #[cfg(windows)]
-        pub fn gen_stub_os() -> uv_tcp_t {
-            uv_tcp_t {
-                fields: uv_handle_fields {
-                    loop_handle: ptr::null(), type_: 0u32,
-                    close_cb: ptr::null(),
-                    data: ptr::null(),
-                },
-                a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
-                a03: 0 as *u8,
-                a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
-                a07: 0 as *u8,
-                a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
-                a11: 0 as *u8,
-                a12: 0 as *u8, a13: 0 as *u8, a14: 0 as *u8,
-                a15: 0 as *u8,
-                a16: 0 as *u8, a17: 0 as *u8, a18: 0 as *u8,
-                a19: 0 as *u8,
-                a20: 0 as *u8, a21: 0 as *u8, a22: 0 as *u8,
-                a23: 0 as *u8,
-                a24: 0 as *u8, a25: 0 as *u8,
-            }
-        }
-        #[cfg(target_os = "macos")]
-        pub fn gen_stub_os() -> uv_tcp_t {
-            use super::uv_tcp_t_osx_riders;
-
-            return gen_stub_arch();
-
-            #[cfg(target_arch = "x86_64")]
-            fn gen_stub_arch() -> uv_tcp_t {
-                uv_tcp_t {
-                    fields: uv_handle_fields {
-                        loop_handle: ptr::null(), type_: 0u32,
-                        close_cb: ptr::null(),
-                        data: ptr::null(),
-                    },
-                    a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
-                    a03: 0 as *u8,
-                    a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
-                    a07: 0 as *u8,
-                    a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
-                    a11: 0 as *u8,
-                    a12: 0 as *u8, a13: 0 as *u8, a14: 0 as *u8,
-                    a15: 0 as *u8,
-                    a16: 0 as *u8, a17: 0 as *u8, a18: 0 as *u8,
-                    a19: 0 as *u8,
-                    a20: 0 as *u8, a21: 0 as *u8, a22: 0 as *u8,
-                    a23: uv_tcp_t_osx_riders {
-                        a23: 0 as *u8,
-                    }
-                }
-            }
-
-            #[cfg(target_arch = "x86")]
-            #[cfg(target_arch = "arm")]
-            fn gen_stub_arch() -> uv_tcp_t {
-                uv_tcp_t {
-                    fields: uv_handle_fields {
-                        loop_handle: ptr::null(), type_: 0u32,
-                        close_cb: ptr::null(),
-                        data: ptr::null(),
-                    },
-                    a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
-                    a03: 0 as *u8,
-                    a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
-                    a07: 0 as *u8,
-                    a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
-                    a11: 0 as *u8,
-                    a12: 0 as *u8, a13: 0 as *u8, a14: 0 as *u8,
-                    a15: 0 as *u8,
-                    a16: 0 as *u8, a17: 0 as *u8, a18: 0 as *u8,
-                    a19: 0 as *u8,
-                    a20: 0 as *u8, a21: 0 as *u8, a22: 0 as *u8,
-                    a23: uv_tcp_t_osx_riders {
-                        a23: 0 as *u8,
-                        a24: 0 as *u8, a25: 0 as *u8,
-                    }
-                }
-            }
-        }
-    }
-    #[cfg(unix)]
-    pub fn gen_stub_uv_connect_t() -> uv_connect_t {
-        uv_connect_t {
-            a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
-            a03: 0 as *u8,
-            a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
-            a07: 0 as *u8
-        }
-    }
-    #[cfg(windows)]
-    pub fn gen_stub_uv_connect_t() -> uv_connect_t {
-        uv_connect_t {
-            a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
-            a03: 0 as *u8,
-            a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
-            a07: 0 as *u8,
-            a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
-        }
-    }
-    #[cfg(unix)]
-    pub fn gen_stub_uv_async_t() -> uv_async_t {
-        return gen_stub_arch();
-        #[cfg(target_arch = "x86_64")]
-        pub fn gen_stub_arch() -> uv_async_t {
-            uv_async_t {
-                fields: uv_handle_fields {
-                    loop_handle: ptr::null(), type_: 0u32,
-                    close_cb: ptr::null(),
-                    data: ptr::null(),
-                },
-                a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
-                a03: 0 as *u8,
-                a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
-                a07: uv_async_t_32bit_unix_riders { a10: 0 as *u8 },
-            }
-        }
-        #[cfg(target_arch = "x86")]
-        #[cfg(target_arch="arm")]
-        #[cfg(target_arch="mips")]
-        pub fn gen_stub_arch() -> uv_async_t {
-            uv_async_t {
-                fields: uv_handle_fields {
-                    loop_handle: ptr::null(), type_: 0u32,
-                    close_cb: ptr::null(),
-                    data: ptr::null(),
-                },
-                a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
-                a03: 0 as *u8,
-                a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
-                a07: uv_async_t_32bit_unix_riders {
-                    a10: 0 as *u8,
-                }
-            }
-        }
-    }
-    #[cfg(windows)]
-    pub fn gen_stub_uv_async_t() -> uv_async_t {
-        uv_async_t {
-            fields: uv_handle_fields {
-                loop_handle: ptr::null(), type_: 0u32,
-                close_cb: ptr::null(),
-                data: ptr::null(),
-            },
-            a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
-            a03: 0 as *u8,
-            a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
-            a07: 0 as *u8,
-            a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
-            a11: 0 as *u8,
-            a12: 0 as *u8,
-        }
-    }
-    #[cfg(unix)]
-    pub fn gen_stub_uv_timer_t() -> uv_timer_t {
-        return gen_stub_arch();
-        #[cfg(target_arch = "x86_64")]
-        pub fn gen_stub_arch() -> uv_timer_t {
-            uv_timer_t {
-                fields: uv_handle_fields {
-                    loop_handle: ptr::null(), type_: 0u32,
-                    close_cb: ptr::null(),
-                    data: ptr::null(),
-                },
-                a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
-                a03: 0 as *u8,
-                a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
-                a07: 0 as *u8,
-                a08: 0 as *u8, a09: 0 as *u8,
-                a11: uv_timer_t_32bit_unix_riders {
-                    a10: 0 as *u8
-                },
-            }
-        }
-        #[cfg(target_arch = "x86")]
-        #[cfg(target_arch="arm")]
-        #[cfg(target_arch="mips")]
-        pub fn gen_stub_arch() -> uv_timer_t {
-            uv_timer_t {
-                fields: uv_handle_fields {
-                    loop_handle: ptr::null(), type_: 0u32,
-                    close_cb: ptr::null(),
-                    data: ptr::null(),
-                },
-                a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
-                a03: 0 as *u8,
-                a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
-                a07: 0 as *u8,
-                a08: 0 as *u8, a09: 0 as *u8,
-                a11: uv_timer_t_32bit_unix_riders {
-                    a10: 0 as *u8, a11: 0 as *u8,
-                    a12: 0 as *u8,
-                },
-            }
-        }
-    }
-    #[cfg(windows)]
-    pub fn gen_stub_uv_timer_t() -> uv_timer_t {
-        uv_timer_t {
-            fields: uv_handle_fields {
-                loop_handle: ptr::null(), type_: 0u32,
-                close_cb: ptr::null(),
-                data: ptr::null(),
-            },
-            a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
-            a03: 0 as *u8,
-            a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
-            a07: 0 as *u8,
-            a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
-            a11: 0 as *u8,
-        }
-    }
-    #[cfg(unix)]
-    pub fn gen_stub_uv_write_t() -> uv_write_t {
-        return gen_stub_arch();
-        #[cfg(target_arch="x86_64")]
-        pub fn gen_stub_arch() -> uv_write_t {
-            uv_write_t {
-                fields: uv_handle_fields {
-                    loop_handle: ptr::null(), type_: 0u32,
-                    close_cb: ptr::null(),
-                    data: ptr::null(),
-                },
-                a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
-                a03: 0 as *u8,
-                a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
-                a07: 0 as *u8,
-                a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
-                a11: 0 as *u8,
-                a12: 0 as *u8,
-                a14: uv_write_t_32bit_unix_riders { a13: 0 as *u8,
-                                                   a14: 0 as *u8,
-                                                   a15: 0 as *u8},
-            }
-        }
-        #[cfg(target_arch="x86")]
-        #[cfg(target_arch="arm")]
-        #[cfg(target_arch="mips")]
-        pub fn gen_stub_arch() -> uv_write_t {
-            uv_write_t {
-                fields: uv_handle_fields {
-                    loop_handle: ptr::null(), type_: 0u32,
-                    close_cb: ptr::null(),
-                    data: ptr::null(),
-                },
-                a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
-                a03: 0 as *u8,
-                a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
-                a07: 0 as *u8,
-                a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
-                a11: 0 as *u8,
-                a12: 0 as *u8,
-                a14: uv_write_t_32bit_unix_riders {
-                    a13: 0 as *u8,
-                    a14: 0 as *u8,
-                    a15: 0 as *u8,
-                    a16: 0 as *u8,
-                }
-            }
-        }
-    }
-    #[cfg(windows)]
-    pub fn gen_stub_uv_write_t() -> uv_write_t {
-        uv_write_t {
-            fields: uv_handle_fields {
-                loop_handle: ptr::null(), type_: 0u32,
-                close_cb: ptr::null(),
-                data: ptr::null(),
-            },
-            a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
-            a03: 0 as *u8,
-            a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
-            a07: 0 as *u8,
-            a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
-            a11: 0 as *u8,
-            a12: 0 as *u8
-        }
-    }
-    pub fn gen_stub_uv_getaddrinfo_t() -> uv_getaddrinfo_t {
-        uv_getaddrinfo_t {
-            a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8, a03: 0 as *u8,
-            a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8, a07: 0 as *u8,
-            a08: 0 as *u8, a09: 0 as *u8,
-            a10: 1 as *u8, a11: 1 as *u8, a12: 1 as *u8, a13: 1 as *u8,
-            a14: 1 as *u8, a15: 1 as *u8
-        }
-    }
+pub unsafe fn loop_delete(loop_handle: *c_void) {
+    rust_uv_loop_delete(loop_handle);
 }
 
-#[nolink]
-extern mod rustrt {
-
-    // libuv public API
-    unsafe fn rust_uv_loop_new() -> *libc::c_void;
-    unsafe fn rust_uv_loop_delete(lp: *libc::c_void);
-    unsafe fn rust_uv_run(loop_handle: *libc::c_void);
-    unsafe fn rust_uv_close(handle: *libc::c_void, cb: *u8);
-    unsafe fn rust_uv_walk(loop_handle: *libc::c_void, cb: *u8,
-                           arg: *libc::c_void);
-
-    unsafe fn rust_uv_idle_new() -> *uv_idle_t;
-    unsafe fn rust_uv_idle_delete(handle: *uv_idle_t);
-    unsafe fn rust_uv_idle_init(loop_handle: *uv_loop_t,
-                                handle: *uv_idle_t) -> libc::c_int;
-    unsafe fn rust_uv_idle_start(handle: *uv_idle_t,
-                                 cb: uv_idle_cb) -> libc::c_int;
-    unsafe fn rust_uv_idle_stop(handle: *uv_idle_t) -> libc::c_int;
-
-    unsafe fn rust_uv_async_send(handle: *uv_async_t);
-    unsafe fn rust_uv_async_init(loop_handle: *libc::c_void,
-                          async_handle: *uv_async_t,
-                          cb: *u8) -> libc::c_int;
-    unsafe fn rust_uv_tcp_init(
-        loop_handle: *libc::c_void,
-        handle_ptr: *uv_tcp_t) -> libc::c_int;
-    // FIXME ref #2604 .. ?
-    unsafe fn rust_uv_buf_init(out_buf: *uv_buf_t, base: *u8,
-                        len: libc::size_t);
-    unsafe fn rust_uv_last_error(loop_handle: *libc::c_void) -> uv_err_t;
-    // FIXME ref #2064
-    unsafe fn rust_uv_strerror(err: *uv_err_t) -> *libc::c_char;
-    // FIXME ref #2064
-    unsafe fn rust_uv_err_name(err: *uv_err_t) -> *libc::c_char;
-    unsafe fn rust_uv_ip4_addr(ip: *u8, port: libc::c_int)
-        -> sockaddr_in;
-    unsafe fn rust_uv_ip6_addr(ip: *u8, port: libc::c_int)
-        -> sockaddr_in6;
-    unsafe fn rust_uv_ip4_name(src: *sockaddr_in,
-                               dst: *u8,
-                               size: libc::size_t)
-                            -> libc::c_int;
-    unsafe fn rust_uv_ip6_name(src: *sockaddr_in6,
-                               dst: *u8,
-                               size: libc::size_t)
-                            -> libc::c_int;
-    unsafe fn rust_uv_ip4_port(src: *sockaddr_in) -> libc::c_uint;
-    unsafe fn rust_uv_ip6_port(src: *sockaddr_in6) -> libc::c_uint;
-    // FIXME ref #2064
-    unsafe fn rust_uv_tcp_connect(connect_ptr: *uv_connect_t,
-                                  tcp_handle_ptr: *uv_tcp_t,
-                                  ++after_cb: *u8,
-                                  ++addr: *sockaddr_in) -> libc::c_int;
-    // FIXME ref #2064
-    unsafe fn rust_uv_tcp_bind(tcp_server: *uv_tcp_t,
-                               ++addr: *sockaddr_in) -> libc::c_int;
-    // FIXME ref #2064
-    unsafe fn rust_uv_tcp_connect6(connect_ptr: *uv_connect_t,
-                                   tcp_handle_ptr: *uv_tcp_t,
-                                   ++after_cb: *u8,
-                                   ++addr: *sockaddr_in6) -> libc::c_int;
-    // FIXME ref #2064
-    unsafe fn rust_uv_tcp_bind6(tcp_server: *uv_tcp_t,
-                                ++addr: *sockaddr_in6) -> libc::c_int;
-    unsafe fn rust_uv_tcp_getpeername(tcp_handle_ptr: *uv_tcp_t,
-                                      ++name: *sockaddr_in) -> libc::c_int;
-    unsafe fn rust_uv_tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t,
-                                       ++name: *sockaddr_in6) ->libc::c_int;
-    unsafe fn rust_uv_listen(stream: *libc::c_void,
-                             backlog: libc::c_int,
-                             cb: *u8) -> libc::c_int;
-    unsafe fn rust_uv_accept(server: *libc::c_void, client: *libc::c_void)
-                          -> libc::c_int;
-    unsafe fn rust_uv_write(req: *libc::c_void,
-                            stream: *libc::c_void,
-                            ++buf_in: *uv_buf_t,
-                            buf_cnt: libc::c_int,
-                            cb: *u8)
-        -> libc::c_int;
-    unsafe fn rust_uv_read_start(stream: *libc::c_void,
-                                 on_alloc: *u8,
-                                 on_read: *u8)
-        -> libc::c_int;
-    unsafe fn rust_uv_read_stop(stream: *libc::c_void) -> libc::c_int;
-    unsafe fn rust_uv_timer_init(loop_handle: *libc::c_void,
-                                 timer_handle: *uv_timer_t)
-        -> libc::c_int;
-    unsafe fn rust_uv_timer_start(
-        timer_handle: *uv_timer_t,
-        cb: *u8,
-        timeout: libc::c_uint,
-        repeat: libc::c_uint) -> libc::c_int;
-    unsafe fn rust_uv_timer_stop(handle: *uv_timer_t) -> libc::c_int;
-
-    unsafe fn rust_uv_getaddrinfo(loop_ptr: *libc::c_void,
-                                  handle: *uv_getaddrinfo_t,
-                                  cb: *u8,
-                                  node_name_ptr: *u8,
-                                  service_name_ptr: *u8,
-                                  // should probably only pass ptr::null()
-                                  hints: *addrinfo)
-        -> libc::c_int;
-    unsafe fn rust_uv_freeaddrinfo(res: *addrinfo);
-
-    // data accessors/helpers for rust-mapped uv structs
-    unsafe fn rust_uv_helper_get_INADDR_NONE() -> u32;
-    unsafe fn rust_uv_is_ipv4_addrinfo(input: *addrinfo) -> bool;
-    unsafe fn rust_uv_is_ipv6_addrinfo(input: *addrinfo) -> bool;
-    unsafe fn rust_uv_get_next_addrinfo(input: *addrinfo) -> *addrinfo;
-    unsafe fn rust_uv_addrinfo_as_sockaddr_in(input: *addrinfo)
-        -> *sockaddr_in;
-    unsafe fn rust_uv_addrinfo_as_sockaddr_in6(input: *addrinfo)
-        -> *sockaddr_in6;
-    unsafe fn rust_uv_malloc_buf_base_of(sug_size: libc::size_t) -> *u8;
-    unsafe fn rust_uv_free_base_of_buf(++buf: uv_buf_t);
-    unsafe fn rust_uv_get_stream_handle_from_connect_req(
-        connect_req: *uv_connect_t)
-        -> *uv_stream_t;
-    unsafe fn rust_uv_get_stream_handle_from_write_req(
-        write_req: *uv_write_t)
-        -> *uv_stream_t;
-    unsafe fn rust_uv_get_loop_for_uv_handle(handle: *libc::c_void)
-        -> *libc::c_void;
-    unsafe fn rust_uv_get_data_for_uv_loop(loop_ptr: *libc::c_void)
-        -> *libc::c_void;
-    unsafe fn rust_uv_set_data_for_uv_loop(loop_ptr: *libc::c_void,
-                                           data: *libc::c_void);
-    unsafe fn rust_uv_get_data_for_uv_handle(handle: *libc::c_void)
-        -> *libc::c_void;
-    unsafe fn rust_uv_set_data_for_uv_handle(handle: *libc::c_void,
-                                             data: *libc::c_void);
-    unsafe fn rust_uv_get_data_for_req(req: *libc::c_void)
-        -> *libc::c_void;
-    unsafe fn rust_uv_set_data_for_req(req: *libc::c_void,
-                                       data: *libc::c_void);
-    unsafe fn rust_uv_get_base_from_buf(++buf: uv_buf_t) -> *u8;
-    unsafe fn rust_uv_get_len_from_buf(++buf: uv_buf_t) -> libc::size_t;
-
-    // sizeof testing helpers
-    unsafe fn rust_uv_helper_uv_tcp_t_size() -> libc::c_uint;
-    unsafe fn rust_uv_helper_uv_connect_t_size() -> libc::c_uint;
-    unsafe fn rust_uv_helper_uv_buf_t_size() -> libc::c_uint;
-    unsafe fn rust_uv_helper_uv_write_t_size() -> libc::c_uint;
-    unsafe fn rust_uv_helper_uv_err_t_size() -> libc::c_uint;
-    unsafe fn rust_uv_helper_sockaddr_in_size() -> libc::c_uint;
-    unsafe fn rust_uv_helper_sockaddr_in6_size() -> libc::c_uint;
-    unsafe fn rust_uv_helper_uv_async_t_size() -> libc::c_uint;
-    unsafe fn rust_uv_helper_uv_timer_t_size() -> libc::c_uint;
-    unsafe fn rust_uv_helper_uv_getaddrinfo_t_size() -> libc::c_uint;
-    unsafe fn rust_uv_helper_addrinfo_size() -> libc::c_uint;
-    unsafe fn rust_uv_helper_addr_in_size() -> libc::c_uint;
-}
-
-pub unsafe fn loop_new() -> *libc::c_void {
-    return rustrt::rust_uv_loop_new();
-}
-
-pub unsafe fn loop_delete(loop_handle: *libc::c_void) {
-    rustrt::rust_uv_loop_delete(loop_handle);
-}
-
-pub unsafe fn run(loop_handle: *libc::c_void) {
-    rustrt::rust_uv_run(loop_handle);
+pub unsafe fn run(loop_handle: *c_void) {
+    rust_uv_run(loop_handle);
 }
 
 pub unsafe fn close<T>(handle: *T, cb: *u8) {
-    rustrt::rust_uv_close(handle as *libc::c_void, cb);
+    rust_uv_close(handle as *c_void, cb);
 }
 
-pub unsafe fn walk(loop_handle: *libc::c_void, cb: *u8, arg: *libc::c_void) {
-    rustrt::rust_uv_walk(loop_handle, cb, arg);
+pub unsafe fn walk(loop_handle: *c_void, cb: *u8, arg: *c_void) {
+    rust_uv_walk(loop_handle, cb, arg);
 }
 
 pub unsafe fn idle_new() -> *uv_idle_t {
-    rustrt::rust_uv_idle_new()
+    rust_uv_idle_new()
 }
 
 pub unsafe fn idle_delete(handle: *uv_idle_t) {
-    rustrt::rust_uv_idle_delete(handle)
+    rust_uv_idle_delete(handle)
 }
 
 pub unsafe fn idle_init(loop_handle: *uv_loop_t,
-                        handle: *uv_idle_t) -> libc::c_int {
-    rustrt::rust_uv_idle_init(loop_handle, handle)
+                        handle: *uv_idle_t) -> c_int {
+    rust_uv_idle_init(loop_handle, handle)
 }
 
-pub unsafe fn idle_start(handle: *uv_idle_t, cb: uv_idle_cb) -> libc::c_int {
-    rustrt::rust_uv_idle_start(handle, cb)
+pub unsafe fn idle_start(handle: *uv_idle_t, cb: uv_idle_cb) -> c_int {
+    rust_uv_idle_start(handle, cb)
 }
 
-pub unsafe fn idle_stop(handle: *uv_idle_t) -> libc::c_int {
-    rustrt::rust_uv_idle_stop(handle)
+pub unsafe fn idle_stop(handle: *uv_idle_t) -> c_int {
+    rust_uv_idle_stop(handle)
 }
 
-pub unsafe fn tcp_init(loop_handle: *libc::c_void, handle: *uv_tcp_t)
-    -> libc::c_int {
-    return rustrt::rust_uv_tcp_init(loop_handle, handle);
+pub unsafe fn tcp_init(loop_handle: *c_void, handle: *uv_tcp_t) -> c_int {
+    return rust_uv_tcp_init(loop_handle, handle);
 }
+
 // FIXME ref #2064
 pub unsafe fn tcp_connect(connect_ptr: *uv_connect_t,
-                      tcp_handle_ptr: *uv_tcp_t,
-                      addr_ptr: *sockaddr_in,
-                      after_connect_cb: *u8)
+                          tcp_handle_ptr: *uv_tcp_t,
+                          addr_ptr: *sockaddr_in,
+                          after_connect_cb: *u8)
 -> libc::c_int {
-    debug!("b4 foreign tcp_connect--addr port: %u cb: %u",
-                    (*addr_ptr).sin_port as uint, after_connect_cb as uint);
-    return rustrt::rust_uv_tcp_connect(connect_ptr, tcp_handle_ptr,
-                                    after_connect_cb, addr_ptr);
+    return rust_uv_tcp_connect(connect_ptr, tcp_handle_ptr,
+                                       after_connect_cb, addr_ptr);
 }
 // FIXME ref #2064
 pub unsafe fn tcp_connect6(connect_ptr: *uv_connect_t,
-                      tcp_handle_ptr: *uv_tcp_t,
-                      addr_ptr: *sockaddr_in6,
-                      after_connect_cb: *u8)
--> libc::c_int {
-    return rustrt::rust_uv_tcp_connect6(connect_ptr, tcp_handle_ptr,
-                                    after_connect_cb, addr_ptr);
+                           tcp_handle_ptr: *uv_tcp_t,
+                           addr_ptr: *sockaddr_in6,
+                           after_connect_cb: *u8) -> c_int {
+    return rust_uv_tcp_connect6(connect_ptr, tcp_handle_ptr,
+                                        after_connect_cb, addr_ptr);
 }
 // FIXME ref #2064
 pub unsafe fn tcp_bind(tcp_server_ptr: *uv_tcp_t,
-                   addr_ptr: *sockaddr_in) -> libc::c_int {
-    return rustrt::rust_uv_tcp_bind(tcp_server_ptr,
+                       addr_ptr: *sockaddr_in) -> c_int {
+    return rust_uv_tcp_bind(tcp_server_ptr,
                                  addr_ptr);
 }
 // FIXME ref #2064
 pub unsafe fn tcp_bind6(tcp_server_ptr: *uv_tcp_t,
-                   addr_ptr: *sockaddr_in6) -> libc::c_int {
-    return rustrt::rust_uv_tcp_bind6(tcp_server_ptr,
+                        addr_ptr: *sockaddr_in6) -> c_int {
+    return rust_uv_tcp_bind6(tcp_server_ptr,
                                  addr_ptr);
 }
 
 pub unsafe fn tcp_getpeername(tcp_handle_ptr: *uv_tcp_t,
-                              name: *sockaddr_in) -> libc::c_int {
-    return rustrt::rust_uv_tcp_getpeername(tcp_handle_ptr, name);
+                              name: *sockaddr_in) -> c_int {
+    return rust_uv_tcp_getpeername(tcp_handle_ptr, name);
 }
 
 pub unsafe fn tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t,
-                               name: *sockaddr_in6) ->libc::c_int {
-    return rustrt::rust_uv_tcp_getpeername6(tcp_handle_ptr, name);
+                               name: *sockaddr_in6) ->c_int {
+    return rust_uv_tcp_getpeername6(tcp_handle_ptr, name);
 }
 
-pub unsafe fn listen<T>(stream: *T, backlog: libc::c_int,
-                 cb: *u8) -> libc::c_int {
-    return rustrt::rust_uv_listen(stream as *libc::c_void, backlog, cb);
+pub unsafe fn listen<T>(stream: *T, backlog: c_int,
+                        cb: *u8) -> c_int {
+    return rust_uv_listen(stream as *c_void, backlog, cb);
 }
 
-pub unsafe fn accept(server: *libc::c_void, client: *libc::c_void)
-    -> libc::c_int {
-    return rustrt::rust_uv_accept(server as *libc::c_void,
-                               client as *libc::c_void);
+pub unsafe fn accept(server: *c_void, client: *c_void) -> c_int {
+    return rust_uv_accept(server as *c_void,
+                               client as *c_void);
 }
 
 pub unsafe fn write<T>(req: *uv_write_t, stream: *T,
-         buf_in: *~[uv_buf_t], cb: *u8) -> libc::c_int {
+         buf_in: *~[uv_buf_t], cb: *u8) -> c_int {
     let buf_ptr = vec::raw::to_ptr(*buf_in);
     let buf_cnt = vec::len(*buf_in) as i32;
-    return rustrt::rust_uv_write(req as *libc::c_void,
-                              stream as *libc::c_void,
+    return rust_uv_write(req as *c_void,
+                              stream as *c_void,
                               buf_ptr, buf_cnt, cb);
 }
 pub unsafe fn read_start(stream: *uv_stream_t, on_alloc: *u8,
-                     on_read: *u8) -> libc::c_int {
-    return rustrt::rust_uv_read_start(stream as *libc::c_void,
+                     on_read: *u8) -> c_int {
+    return rust_uv_read_start(stream as *c_void,
                                    on_alloc, on_read);
 }
 
-pub unsafe fn read_stop(stream: *uv_stream_t) -> libc::c_int {
-    return rustrt::rust_uv_read_stop(stream as *libc::c_void);
+pub unsafe fn read_stop(stream: *uv_stream_t) -> c_int {
+    return rust_uv_read_stop(stream as *c_void);
 }
 
-pub unsafe fn last_error(loop_handle: *libc::c_void) -> uv_err_t {
-    return rustrt::rust_uv_last_error(loop_handle);
+pub unsafe fn last_error(loop_handle: *c_void) -> uv_err_t {
+    return rust_uv_last_error(loop_handle);
 }
 
-pub unsafe fn strerror(err: *uv_err_t) -> *libc::c_char {
-    return rustrt::rust_uv_strerror(err);
+pub unsafe fn strerror(err: *uv_err_t) -> *c_char {
+    return rust_uv_strerror(err);
 }
-pub unsafe fn err_name(err: *uv_err_t) -> *libc::c_char {
-    return rustrt::rust_uv_err_name(err);
+pub unsafe fn err_name(err: *uv_err_t) -> *c_char {
+    return rust_uv_err_name(err);
 }
 
-pub unsafe fn async_init(loop_handle: *libc::c_void,
-                     async_handle: *uv_async_t,
-                     cb: *u8) -> libc::c_int {
-    return rustrt::rust_uv_async_init(loop_handle,
-                                   async_handle,
-                                   cb);
+pub unsafe fn async_init(loop_handle: *c_void,
+                         async_handle: *uv_async_t,
+                         cb: *u8) -> c_int {
+    return rust_uv_async_init(loop_handle,
+                                      async_handle,
+                                      cb);
 }
 
 pub unsafe fn async_send(async_handle: *uv_async_t) {
-    return rustrt::rust_uv_async_send(async_handle);
+    return rust_uv_async_send(async_handle);
 }
 pub unsafe fn buf_init(input: *u8, len: uint) -> uv_buf_t {
-    let out_buf = uv_buf_t { base: ptr::null(), len: 0 as libc::size_t };
+    let out_buf = uv_buf_t { base: ptr::null(), len: 0 as size_t };
     let out_buf_ptr = ptr::addr_of(&out_buf);
-    debug!("buf_init - input %u len %u out_buf: %u",
-                     input as uint,
-                     len as uint,
-                     out_buf_ptr as uint);
-    // yuck :/
-    rustrt::rust_uv_buf_init(out_buf_ptr, input, len as size_t);
-    //let result = rustrt::rust_uv_buf_init_2(input, len as size_t);
-    debug!("after rust_uv_buf_init");
-    let res_base = get_base_from_buf(out_buf);
-    let res_len = get_len_from_buf(out_buf);
-    //let res_base = get_base_from_buf(result);
-    debug!("buf_init - result %u len %u",
-                     res_base as uint,
-                     res_len as uint);
+    rust_uv_buf_init(out_buf_ptr, input, len as size_t);
     return out_buf;
-    //return result;
-}
-pub unsafe fn ip4_addr(ip: &str, port: int)
--> sockaddr_in {
-    do str::as_c_str(ip) |ip_buf| {
-        rustrt::rust_uv_ip4_addr(ip_buf as *u8,
-                                 port as libc::c_int)
-    }
-}
-pub unsafe fn ip6_addr(ip: &str, port: int)
--> sockaddr_in6 {
-    do str::as_c_str(ip) |ip_buf| {
-        rustrt::rust_uv_ip6_addr(ip_buf as *u8,
-                                 port as libc::c_int)
-    }
-}
-pub unsafe fn ip4_name(src: &sockaddr_in) -> ~str {
-    // ipv4 addr max size: 15 + 1 trailing null byte
-    let dst: ~[u8] = ~[0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8,
-                     0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8];
-    do vec::as_imm_buf(dst) |dst_buf, size| {
-        rustrt::rust_uv_ip4_name(to_unsafe_ptr(src),
-                                 dst_buf, size as libc::size_t);
-        // seems that checking the result of uv_ip4_name
-        // doesn't work too well..
-        // you're stuck looking at the value of dst_buf
-        // to see if it is the string representation of
-        // INADDR_NONE (0xffffffff or 255.255.255.255 on
-        // many platforms)
-        str::raw::from_buf(dst_buf)
-    }
-}
-pub unsafe fn ip6_name(src: &sockaddr_in6) -> ~str {
-    // ipv6 addr max size: 45 + 1 trailing null byte
-    let dst: ~[u8] = ~[0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8,
-                       0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8,
-                       0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8,
-                       0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8,
-                       0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8,
-                       0u8,0u8,0u8,0u8,0u8,0u8];
-    do vec::as_imm_buf(dst) |dst_buf, size| {
-        let src_unsafe_ptr = to_unsafe_ptr(src);
-        debug!("val of src *sockaddr_in6: %? sockaddr_in6: %?",
-                        src_unsafe_ptr, src);
-        let result = rustrt::rust_uv_ip6_name(src_unsafe_ptr,
-                                              dst_buf, size as libc::size_t);
-        match result {
-          0i32 => str::raw::from_buf(dst_buf),
-          _ => ~""
-        }
-    }
-}
-pub unsafe fn ip4_port(src: &sockaddr_in) -> uint {
-    rustrt::rust_uv_ip4_port(to_unsafe_ptr(src)) as uint
-}
-pub unsafe fn ip6_port(src: &sockaddr_in6) -> uint {
-    rustrt::rust_uv_ip6_port(to_unsafe_ptr(src)) as uint
 }
 
-pub unsafe fn timer_init(loop_ptr: *libc::c_void,
-                     timer_ptr: *uv_timer_t) -> libc::c_int {
-    return rustrt::rust_uv_timer_init(loop_ptr, timer_ptr);
+pub unsafe fn timer_init(loop_ptr: *c_void,
+                         timer_ptr: *uv_timer_t) -> c_int {
+    return rust_uv_timer_init(loop_ptr, timer_ptr);
 }
 pub unsafe fn timer_start(timer_ptr: *uv_timer_t, cb: *u8, timeout: uint,
-                      repeat: uint) -> libc::c_int {
-    return rustrt::rust_uv_timer_start(timer_ptr, cb, timeout as libc::c_uint,
-                                    repeat as libc::c_uint);
+                          repeat: uint) -> c_int {
+    return rust_uv_timer_start(timer_ptr, cb, timeout as c_uint,
+                                       repeat as c_uint);
 }
-pub unsafe fn timer_stop(timer_ptr: *uv_timer_t) -> libc::c_int {
-    return rustrt::rust_uv_timer_stop(timer_ptr);
-}
-pub unsafe fn getaddrinfo(loop_ptr: *libc::c_void,
-                           handle: *uv_getaddrinfo_t,
-                           cb: *u8,
-                           node_name_ptr: *u8,
-                           service_name_ptr: *u8,
-                           hints: *addrinfo) -> libc::c_int {
-    rustrt::rust_uv_getaddrinfo(loop_ptr,
-                           handle,
-                           cb,
-                           node_name_ptr,
-                           service_name_ptr,
-                           hints)
-}
-pub unsafe fn freeaddrinfo(res: *addrinfo) {
-    rustrt::rust_uv_freeaddrinfo(res);
+pub unsafe fn timer_stop(timer_ptr: *uv_timer_t) -> c_int {
+    return rust_uv_timer_stop(timer_ptr);
 }
 
-// libuv struct initializers
-pub unsafe fn tcp_t() -> uv_tcp_t {
-    return uv_ll_struct_stubgen::gen_stub_uv_tcp_t();
+pub unsafe fn malloc_ip4_addr(ip: &str, port: int)
+-> *sockaddr_in {
+    do str::as_c_str(ip) |ip_buf| {
+        rust_uv_ip4_addrp(ip_buf as *u8,
+                                  port as libc::c_int)
+    }
 }
-pub unsafe fn connect_t() -> uv_connect_t {
-    return uv_ll_struct_stubgen::gen_stub_uv_connect_t();
+pub unsafe fn malloc_ip6_addr(ip: &str, port: int)
+-> *sockaddr_in6 {
+    do str::as_c_str(ip) |ip_buf| {
+        rust_uv_ip6_addrp(ip_buf as *u8,
+                                  port as libc::c_int)
+    }
 }
-pub unsafe fn write_t() -> uv_write_t {
-    return uv_ll_struct_stubgen::gen_stub_uv_write_t();
+
+pub unsafe fn free_ip4_addr(addr: *sockaddr_in) {
+    rust_uv_free_ip4_addr(addr);
 }
-pub unsafe fn async_t() -> uv_async_t {
-    return uv_ll_struct_stubgen::gen_stub_uv_async_t();
-}
-pub unsafe fn timer_t() -> uv_timer_t {
-    return uv_ll_struct_stubgen::gen_stub_uv_timer_t();
-}
-pub unsafe fn getaddrinfo_t() -> uv_getaddrinfo_t {
-    return uv_ll_struct_stubgen::gen_stub_uv_getaddrinfo_t();
+
+pub unsafe fn free_ip6_addr(addr: *sockaddr_in6) {
+    rust_uv_free_ip6_addr(addr);
 }
 
 // data access helpers
-pub unsafe fn get_loop_for_uv_handle<T>(handle: *T)
-    -> *libc::c_void {
-    return rustrt::rust_uv_get_loop_for_uv_handle(handle as *libc::c_void);
+pub unsafe fn get_loop_for_uv_handle<T>(handle: *T) -> *c_void {
+    return rust_uv_get_loop_for_uv_handle(handle as *c_void);
 }
 pub unsafe fn get_stream_handle_from_connect_req(connect: *uv_connect_t)
     -> *uv_stream_t {
-    return rustrt::rust_uv_get_stream_handle_from_connect_req(
+    return rust_uv_get_stream_handle_from_connect_req(
         connect);
 }
 pub unsafe fn get_stream_handle_from_write_req(
     write_req: *uv_write_t)
     -> *uv_stream_t {
-    return rustrt::rust_uv_get_stream_handle_from_write_req(
+    return rust_uv_get_stream_handle_from_write_req(
         write_req);
 }
-pub unsafe fn get_data_for_uv_loop(loop_ptr: *libc::c_void) -> *libc::c_void {
-    rustrt::rust_uv_get_data_for_uv_loop(loop_ptr)
+pub unsafe fn get_data_for_uv_loop(loop_ptr: *c_void) -> *c_void {
+    rust_uv_get_data_for_uv_loop(loop_ptr)
 }
-pub unsafe fn set_data_for_uv_loop(loop_ptr: *libc::c_void,
-                                   data: *libc::c_void) {
-    rustrt::rust_uv_set_data_for_uv_loop(loop_ptr, data);
+pub unsafe fn set_data_for_uv_loop(loop_ptr: *c_void,
+                                   data: *c_void) {
+    rust_uv_set_data_for_uv_loop(loop_ptr, data);
 }
-pub unsafe fn get_data_for_uv_handle<T>(handle: *T) -> *libc::c_void {
-    return rustrt::rust_uv_get_data_for_uv_handle(handle as *libc::c_void);
+pub unsafe fn get_data_for_uv_handle<T>(handle: *T) -> *c_void {
+    return rust_uv_get_data_for_uv_handle(handle as *c_void);
 }
 pub unsafe fn set_data_for_uv_handle<T, U>(handle: *T,
                     data: *U) {
-    rustrt::rust_uv_set_data_for_uv_handle(handle as *libc::c_void,
-                                           data as *libc::c_void);
+    rust_uv_set_data_for_uv_handle(handle as *c_void,
+                                           data as *c_void);
 }
-pub unsafe fn get_data_for_req<T>(req: *T) -> *libc::c_void {
-    return rustrt::rust_uv_get_data_for_req(req as *libc::c_void);
+pub unsafe fn get_data_for_req<T>(req: *T) -> *c_void {
+    return rust_uv_get_data_for_req(req as *c_void);
 }
 pub unsafe fn set_data_for_req<T, U>(req: *T,
-                    data: *U) {
-    rustrt::rust_uv_set_data_for_req(req as *libc::c_void,
-                                     data as *libc::c_void);
+                                     data: *U) {
+    rust_uv_set_data_for_req(req as *c_void,
+                                     data as *c_void);
 }
 pub unsafe fn get_base_from_buf(buf: uv_buf_t) -> *u8 {
-    return rustrt::rust_uv_get_base_from_buf(buf);
+    return rust_uv_get_base_from_buf(buf);
 }
-pub unsafe fn get_len_from_buf(buf: uv_buf_t) -> libc::size_t {
-    return rustrt::rust_uv_get_len_from_buf(buf);
+pub unsafe fn get_len_from_buf(buf: uv_buf_t) -> size_t {
+    return rust_uv_get_len_from_buf(buf);
 }
-pub unsafe fn malloc_buf_base_of(suggested_size: libc::size_t)
-    -> *u8 {
-    return rustrt::rust_uv_malloc_buf_base_of(suggested_size);
+pub unsafe fn malloc_buf_base_of(suggested_size: size_t) -> *u8 {
+    return rust_uv_malloc_buf_base_of(suggested_size);
 }
 pub unsafe fn free_base_of_buf(buf: uv_buf_t) {
-    rustrt::rust_uv_free_base_of_buf(buf);
+    rust_uv_free_base_of_buf(buf);
 }
 
-pub unsafe fn get_last_err_info(uv_loop: *libc::c_void) -> ~str {
+pub unsafe fn get_last_err_info(uv_loop: *c_void) -> ~str {
     let err = last_error(uv_loop);
     let err_ptr = ptr::addr_of(&err);
     let err_name = str::raw::from_c_str(err_name(err_ptr));
@@ -1219,721 +385,92 @@ pub struct uv_err_data {
     err_msg: ~str,
 }
 
-pub unsafe fn is_ipv4_addrinfo(input: *addrinfo) -> bool {
-    rustrt::rust_uv_is_ipv4_addrinfo(input)
-}
-pub unsafe fn is_ipv6_addrinfo(input: *addrinfo) -> bool {
-    rustrt::rust_uv_is_ipv6_addrinfo(input)
-}
-pub unsafe fn get_INADDR_NONE() -> u32 {
-    rustrt::rust_uv_helper_get_INADDR_NONE()
-}
-pub unsafe fn get_next_addrinfo(input: *addrinfo) -> *addrinfo {
-    rustrt::rust_uv_get_next_addrinfo(input)
-}
-pub unsafe fn addrinfo_as_sockaddr_in(input: *addrinfo) -> *sockaddr_in {
-    rustrt::rust_uv_addrinfo_as_sockaddr_in(input)
-}
-pub unsafe fn addrinfo_as_sockaddr_in6(input: *addrinfo) -> *sockaddr_in6 {
-    rustrt::rust_uv_addrinfo_as_sockaddr_in6(input)
-}
-
-#[cfg(test)]
-pub mod test {
-    use prelude::*;
-    use super::*;
-    use comm::{SharedChan, stream, GenericChan, GenericPort};
-
-    enum tcp_read_data {
-        tcp_read_eof,
-        tcp_read_more(~[u8]),
-        tcp_read_error
-    }
-
-    struct request_wrapper {
-        write_req: *uv_write_t,
-        req_buf: *~[uv_buf_t],
-        read_chan: SharedChan<~str>,
-    }
-
-    extern fn after_close_cb(handle: *libc::c_void) {
-        debug!("after uv_close! handle ptr: %?",
-                        handle);
-    }
-
-    extern fn on_alloc_cb(handle: *libc::c_void,
-                         suggested_size: libc::size_t)
-        -> uv_buf_t {
-        unsafe {
-            debug!("on_alloc_cb!");
-            let char_ptr = malloc_buf_base_of(suggested_size);
-            debug!("on_alloc_cb h: %? char_ptr: %u sugsize: %u",
-                             handle,
-                             char_ptr as uint,
-                             suggested_size as uint);
-            return buf_init(char_ptr, suggested_size as uint);
-        }
-    }
-
-    extern fn on_read_cb(stream: *uv_stream_t,
-                        nread: libc::ssize_t,
-                        ++buf: uv_buf_t) {
-        unsafe {
-            let nread = nread as int;
-            debug!("CLIENT entering on_read_cb nred: %d",
-                            nread);
-            if (nread > 0) {
-                // we have data
-                debug!("CLIENT read: data! nread: %d", nread);
-                read_stop(stream);
-                let client_data =
-                    get_data_for_uv_handle(stream as *libc::c_void)
-                      as *request_wrapper;
-                let buf_base = get_base_from_buf(buf);
-                let bytes = vec::from_buf(buf_base, nread as uint);
-                let read_chan = (*client_data).read_chan.clone();
-                let msg_from_server = str::from_bytes(bytes);
-                read_chan.send(msg_from_server);
-                close(stream as *libc::c_void, after_close_cb)
-            }
-            else if (nread == -1) {
-                // err .. possibly EOF
-                debug!("read: eof!");
-            }
-            else {
-                // nread == 0 .. do nothing, just free buf as below
-                debug!("read: do nothing!");
-            }
-            // when we're done
-            free_base_of_buf(buf);
-            debug!("CLIENT exiting on_read_cb");
-        }
-    }
-
-    extern fn on_write_complete_cb(write_req: *uv_write_t,
-                                  status: libc::c_int) {
-        unsafe {
-            debug!(
-                "CLIENT beginning on_write_complete_cb status: %d",
-                     status as int);
-            let stream = get_stream_handle_from_write_req(write_req);
-            debug!(
-                "CLIENT on_write_complete_cb: tcp:%d write_handle:%d",
-                stream as int, write_req as int);
-            let result = read_start(stream, on_alloc_cb, on_read_cb);
-            debug!(
-                "CLIENT ending on_write_complete_cb .. status: %d",
-                     result as int);
-        }
-    }
-
-    extern fn on_connect_cb(connect_req_ptr: *uv_connect_t,
-                                 status: libc::c_int) {
-        unsafe {
-            debug!("beginning on_connect_cb .. status: %d",
-                             status as int);
-            let stream =
-                get_stream_handle_from_connect_req(connect_req_ptr);
-            if (status == 0i32) {
-                debug!("on_connect_cb: in status=0 if..");
-                let client_data = get_data_for_req(
-                    connect_req_ptr as *libc::c_void)
-                    as *request_wrapper;
-                let write_handle = (*client_data).write_req;
-                debug!("on_connect_cb: tcp: %d write_hdl: %d",
-                                stream as int, write_handle as int);
-                let write_result = write(write_handle,
-                                  stream as *libc::c_void,
-                                  (*client_data).req_buf,
-                                  on_write_complete_cb);
-                debug!("on_connect_cb: write() status: %d",
-                                 write_result as int);
-            }
-            else {
-                let test_loop = get_loop_for_uv_handle(
-                    stream as *libc::c_void);
-                let err_msg = get_last_err_info(test_loop);
-                debug!("%?", err_msg);
-                fail_unless!(false);
-            }
-            debug!("finishing on_connect_cb");
-        }
-    }
-
-    fn impl_uv_tcp_request(ip: &str, port: int, req_str: &str,
-                          client_chan: SharedChan<~str>) {
-        unsafe {
-            let test_loop = loop_new();
-            let tcp_handle = tcp_t();
-            let tcp_handle_ptr = ptr::addr_of(&tcp_handle);
-            let connect_handle = connect_t();
-            let connect_req_ptr = ptr::addr_of(&connect_handle);
-
-            // this is the persistent payload of data that we
-            // need to pass around to get this example to work.
-            // In C, this would be a malloc'd or stack-allocated
-            // struct that we'd cast to a void* and store as the
-            // data field in our uv_connect_t struct
-            let req_str_bytes = str::to_bytes(req_str);
-            let req_msg_ptr: *u8 = vec::raw::to_ptr(req_str_bytes);
-            debug!("req_msg ptr: %u", req_msg_ptr as uint);
-            let req_msg = ~[
-                buf_init(req_msg_ptr, vec::len(req_str_bytes))
-            ];
-            // this is the enclosing record, we'll pass a ptr to
-            // this to C..
-            let write_handle = write_t();
-            let write_handle_ptr = ptr::addr_of(&write_handle);
-            debug!("tcp req: tcp stream: %d write_handle: %d",
-                             tcp_handle_ptr as int,
-                             write_handle_ptr as int);
-            let client_data = request_wrapper {
-                write_req: write_handle_ptr,
-                req_buf: ptr::addr_of(&req_msg),
-                read_chan: client_chan
-            };
-
-            let tcp_init_result = tcp_init(
-                test_loop as *libc::c_void, tcp_handle_ptr);
-            if (tcp_init_result == 0i32) {
-                debug!("sucessful tcp_init_result");
-
-                debug!("building addr...");
-                let addr = ip4_addr(ip, port);
-                // FIXME ref #2064
-                let addr_ptr = ptr::addr_of(&addr);
-                debug!("after build addr in rust. port: %u",
-                                 addr.sin_port as uint);
-
-                // this should set up the connection request..
-                debug!("b4 call tcp_connect connect cb: %u ",
-                                on_connect_cb as uint);
-                let tcp_connect_result = tcp_connect(
-                    connect_req_ptr, tcp_handle_ptr,
-                    addr_ptr, on_connect_cb);
-                if (tcp_connect_result == 0i32) {
-                    // not set the data on the connect_req
-                    // until its initialized
-                    set_data_for_req(
-                        connect_req_ptr as *libc::c_void,
-                        ptr::addr_of(&client_data) as *libc::c_void);
-                    set_data_for_uv_handle(
-                        tcp_handle_ptr as *libc::c_void,
-                        ptr::addr_of(&client_data) as *libc::c_void);
-                    debug!("before run tcp req loop");
-                    run(test_loop);
-                    debug!("after run tcp req loop");
-                }
-                else {
-                   debug!("tcp_connect() failure");
-                   fail_unless!(false);
-                }
-            }
-            else {
-                debug!("tcp_init() failure");
-                fail_unless!(false);
-            }
-            loop_delete(test_loop);
-        }
-    }
-
-    extern fn server_after_close_cb(handle: *libc::c_void) {
-        unsafe {
-            debug!("SERVER server stream closed, should exit. h: %?",
-                       handle);
-        }
-    }
-
-    extern fn client_stream_after_close_cb(handle: *libc::c_void) {
-        unsafe {
-            debug!(
-                "SERVER: closed client stream, now closing server stream");
-            let client_data = get_data_for_uv_handle(
-                handle) as
-                *tcp_server_data;
-            close((*client_data).server as *libc::c_void,
-                          server_after_close_cb);
-        }
-    }
-
-    extern fn after_server_resp_write(req: *uv_write_t) {
-        unsafe {
-            let client_stream_ptr =
-                get_stream_handle_from_write_req(req);
-            debug!("SERVER: resp sent... closing client stream");
-            close(client_stream_ptr as *libc::c_void,
-                          client_stream_after_close_cb)
-        }
-    }
-
-    extern fn on_server_read_cb(client_stream_ptr: *uv_stream_t,
-                               nread: libc::ssize_t,
-                               ++buf: uv_buf_t) {
-        unsafe {
-            let nread = nread as int;
-            if (nread > 0) {
-                // we have data
-                debug!("SERVER read: data! nread: %d", nread);
-
-                // pull out the contents of the write from the client
-                let buf_base = get_base_from_buf(buf);
-                let buf_len = get_len_from_buf(buf) as uint;
-                debug!("SERVER buf base: %u, len: %u, nread: %d",
-                                buf_base as uint,
-                                buf_len as uint,
-                                nread);
-                let bytes = vec::from_buf(buf_base, nread as uint);
-                let request_str = str::from_bytes(bytes);
-
-                let client_data = get_data_for_uv_handle(
-                    client_stream_ptr as *libc::c_void) as *tcp_server_data;
-
-                let server_kill_msg = copy (*client_data).server_kill_msg;
-                let write_req = (*client_data).server_write_req;
-                if str::contains(request_str, server_kill_msg) {
-                    debug!("SERVER: client req contains kill_msg!");
-                    debug!("SERVER: sending response to client");
-                    read_stop(client_stream_ptr);
-                    let server_chan = (*client_data).server_chan.clone();
-                    server_chan.send(request_str);
-                    let write_result = write(
-                        write_req,
-                        client_stream_ptr as *libc::c_void,
-                        (*client_data).server_resp_buf,
-                        after_server_resp_write);
-                    debug!("SERVER: resp write result: %d",
-                                write_result as int);
-                    if (write_result != 0i32) {
-                        debug!("bad result for server resp write()");
-                        debug!("%s", get_last_err_info(
-                            get_loop_for_uv_handle(client_stream_ptr
-                                as *libc::c_void)));
-                        fail_unless!(false);
-                    }
-                }
-                else {
-                    debug!("SERVER: client req !contain kill_msg!");
-                }
-            }
-            else if (nread == -1) {
-                // err .. possibly EOF
-                debug!("read: eof!");
-            }
-            else {
-                // nread == 0 .. do nothing, just free buf as below
-                debug!("read: do nothing!");
-            }
-            // when we're done
-            free_base_of_buf(buf);
-            debug!("SERVER exiting on_read_cb");
-        }
-    }
-
-    extern fn server_connection_cb(server_stream_ptr:
-                                    *uv_stream_t,
-                                  status: libc::c_int) {
-        unsafe {
-            debug!("client connecting!");
-            let test_loop = get_loop_for_uv_handle(
-                                   server_stream_ptr as *libc::c_void);
-            if status != 0i32 {
-                let err_msg = get_last_err_info(test_loop);
-                debug!("server_connect_cb: non-zero status: %?",
-                             err_msg);
-                return;
-            }
-            let server_data = get_data_for_uv_handle(
-                server_stream_ptr as *libc::c_void) as *tcp_server_data;
-            let client_stream_ptr = (*server_data).client;
-            let client_init_result = tcp_init(test_loop,
-                                                      client_stream_ptr);
-            set_data_for_uv_handle(
-                client_stream_ptr as *libc::c_void,
-                server_data as *libc::c_void);
-            if (client_init_result == 0i32) {
-                debug!("successfully initialized client stream");
-                let accept_result = accept(server_stream_ptr as
-                                                     *libc::c_void,
-                                                   client_stream_ptr as
-                                                     *libc::c_void);
-                if (accept_result == 0i32) {
-                    // start reading
-                    let read_result = read_start(
-                        client_stream_ptr as *uv_stream_t,
-                                                         on_alloc_cb,
-                                                         on_server_read_cb);
-                    if (read_result == 0i32) {
-                        debug!("successful server read start");
-                    }
-                    else {
-                        debug!("server_connection_cb: bad read:%d",
-                                        read_result as int);
-                        fail_unless!(false);
-                    }
-                }
-                else {
-                    debug!("server_connection_cb: bad accept: %d",
-                                accept_result as int);
-                    fail_unless!(false);
-                }
-            }
-            else {
-                debug!("server_connection_cb: bad client init: %d",
-                            client_init_result as int);
-                fail_unless!(false);
-            }
-        }
-    }
-
-    struct tcp_server_data {
-        client: *uv_tcp_t,
-        server: *uv_tcp_t,
-        server_kill_msg: ~str,
-        server_resp_buf: *~[uv_buf_t],
-        server_chan: SharedChan<~str>,
-        server_write_req: *uv_write_t,
-    }
-
-    struct async_handle_data {
-        continue_chan: SharedChan<bool>,
-    }
-
-    extern fn async_close_cb(handle: *libc::c_void) {
-        debug!("SERVER: closing async cb... h: %?",
-                   handle);
-    }
-
-    extern fn continue_async_cb(async_handle: *uv_async_t,
-                               status: libc::c_int) {
-        unsafe {
-            // once we're in the body of this callback,
-            // the tcp server's loop is set up, so we
-            // can continue on to let the tcp client
-            // do its thang
-            let data = get_data_for_uv_handle(
-                async_handle as *libc::c_void) as *async_handle_data;
-            let continue_chan = (*data).continue_chan.clone();
-            let should_continue = status == 0i32;
-            continue_chan.send(should_continue);
-            close(async_handle as *libc::c_void, async_close_cb);
-        }
-    }
-
-    fn impl_uv_tcp_server(server_ip: &str,
-                          server_port: int,
-                          kill_server_msg: ~str,
-                          server_resp_msg: ~str,
-                          server_chan: SharedChan<~str>,
-                          continue_chan: SharedChan<bool>) {
-        unsafe {
-            let test_loop = loop_new();
-            let tcp_server = tcp_t();
-            let tcp_server_ptr = ptr::addr_of(&tcp_server);
-
-            let tcp_client = tcp_t();
-            let tcp_client_ptr = ptr::addr_of(&tcp_client);
-
-            let server_write_req = write_t();
-            let server_write_req_ptr = ptr::addr_of(&server_write_req);
-
-            let resp_str_bytes = str::to_bytes(server_resp_msg);
-            let resp_msg_ptr: *u8 = vec::raw::to_ptr(resp_str_bytes);
-            debug!("resp_msg ptr: %u", resp_msg_ptr as uint);
-            let resp_msg = ~[
-                buf_init(resp_msg_ptr, vec::len(resp_str_bytes))
-            ];
-
-            let continue_async_handle = async_t();
-            let continue_async_handle_ptr =
-                ptr::addr_of(&continue_async_handle);
-            let async_data =
-                async_handle_data { continue_chan: continue_chan };
-            let async_data_ptr = ptr::addr_of(&async_data);
-
-            let server_data = tcp_server_data {
-                client: tcp_client_ptr,
-                server: tcp_server_ptr,
-                server_kill_msg: kill_server_msg,
-                server_resp_buf: ptr::addr_of(&resp_msg),
-                server_chan: server_chan,
-                server_write_req: server_write_req_ptr
-            };
-            let server_data_ptr = ptr::addr_of(&server_data);
-            set_data_for_uv_handle(tcp_server_ptr as *libc::c_void,
-                                           server_data_ptr as *libc::c_void);
-
-            // uv_tcp_init()
-            let tcp_init_result = tcp_init(
-                test_loop as *libc::c_void, tcp_server_ptr);
-            if (tcp_init_result == 0i32) {
-                let server_addr = ip4_addr(server_ip, server_port);
-                // FIXME ref #2064
-                let server_addr_ptr = ptr::addr_of(&server_addr);
-
-                // uv_tcp_bind()
-                let bind_result = tcp_bind(tcp_server_ptr,
-                                                   server_addr_ptr);
-                if (bind_result == 0i32) {
-                    debug!("successful uv_tcp_bind, listening");
-
-                    // uv_listen()
-                    let listen_result = listen(tcp_server_ptr as
-                                                         *libc::c_void,
-                                                       128i32,
-                                                       server_connection_cb);
-                    if (listen_result == 0i32) {
-                        // let the test know it can set up the tcp server,
-                        // now.. this may still present a race, not sure..
-                        let async_result = async_init(test_loop,
-                                           continue_async_handle_ptr,
-                                           continue_async_cb);
-                        if (async_result == 0i32) {
-                            set_data_for_uv_handle(
-                                continue_async_handle_ptr as *libc::c_void,
-                                async_data_ptr as *libc::c_void);
-                            async_send(continue_async_handle_ptr);
-                            // uv_run()
-                            run(test_loop);
-                            debug!("server uv::run() has returned");
-                        }
-                        else {
-                            debug!("uv_async_init failure: %d",
-                                    async_result as int);
-                            fail_unless!(false);
-                        }
-                    }
-                    else {
-                        debug!("non-zero result on uv_listen: %d",
-                                    listen_result as int);
-                        fail_unless!(false);
-                    }
-                }
-                else {
-                    debug!("non-zero result on uv_tcp_bind: %d",
-                                bind_result as int);
-                    fail_unless!(false);
-                }
-            }
-            else {
-                debug!("non-zero result on uv_tcp_init: %d",
-                            tcp_init_result as int);
-                fail_unless!(false);
-            }
-            loop_delete(test_loop);
-        }
-    }
-
-    // this is the impl for a test that is (maybe) ran on a
-    // per-platform/arch basis below
-    pub fn impl_uv_tcp_server_and_request() {
-        unsafe {
-            let bind_ip = ~"0.0.0.0";
-            let request_ip = ~"127.0.0.1";
-            let port = 8886;
-            let kill_server_msg = ~"does a dog have buddha nature?";
-            let server_resp_msg = ~"mu!";
-            let (client_port, client_chan) = stream::<~str>();
-            let client_chan = SharedChan(client_chan);
-            let (server_port, server_chan) = stream::<~str>();
-            let server_chan = SharedChan(server_chan);
-
-            let (continue_port, continue_chan) = stream::<bool>();
-            let continue_chan = SharedChan(continue_chan);
-
-            let kill_server_msg_copy = copy kill_server_msg;
-            let server_resp_msg_copy = copy server_resp_msg;
-            do task::spawn_sched(task::ManualThreads(1)) {
-                impl_uv_tcp_server(bind_ip, port,
-                                   copy kill_server_msg_copy,
-                                   copy server_resp_msg_copy,
-                                   server_chan.clone(),
-                                   continue_chan.clone());
-            };
-
-            // block until the server up is.. possibly a race?
-            debug!("before receiving on server continue_port");
-            continue_port.recv();
-            debug!("received on continue port, set up tcp client");
-
-            let kill_server_msg_copy = copy kill_server_msg;
-            do task::spawn_sched(task::ManualThreads(1u)) {
-                impl_uv_tcp_request(request_ip, port,
-                                   kill_server_msg_copy,
-                                   client_chan.clone());
-            };
-
-            let msg_from_client = server_port.recv();
-            let msg_from_server = client_port.recv();
-
-            fail_unless!(str::contains(msg_from_client, kill_server_msg));
-            fail_unless!(str::contains(msg_from_server, server_resp_msg));
-        }
-    }
-
-    // FIXME don't run on fbsd or linux 32 bit(#2064)
-    #[cfg(target_os="win32")]
-    #[cfg(target_os="darwin")]
-    #[cfg(target_os="linux")]
-    #[cfg(target_os="android")]
-    pub mod tcp_and_server_client_test {
-        #[cfg(target_arch="x86_64")]
-        pub mod impl64 {
-            #[test]
-            pub fn test_uv_ll_tcp_server_and_request() {
-                unsafe {
-                    super::super::impl_uv_tcp_server_and_request();
-                }
-            }
-        }
-        #[cfg(target_arch="x86")]
-        #[cfg(target_arch="arm")]
-        #[cfg(target_arch="mips")]
-        pub mod impl32 {
-            #[test]
-            #[ignore(cfg(target_os = "linux"))]
-            pub fn test_uv_ll_tcp_server_and_request() {
-                unsafe {
-                    super::super::impl_uv_tcp_server_and_request();
-                }
-            }
-        }
-    }
-
-    fn struct_size_check_common<TStruct>(t_name: ~str,
-                                         foreign_size: libc::c_uint) {
-        unsafe {
-            let rust_size = sys::size_of::<TStruct>();
-            let sizes_match = foreign_size as uint == rust_size;
-            if !sizes_match {
-                let output = fmt!(
-                    "STRUCT_SIZE FAILURE: %s -- actual: %u expected: %u",
-                    t_name, rust_size, foreign_size as uint);
-                debug!("%s", output);
-            }
-            fail_unless!(sizes_match);
-        }
-    }
-
-    // struct size tests
-    #[test]
-    fn test_uv_ll_struct_size_uv_tcp_t() {
-        unsafe {
-            struct_size_check_common::<uv_tcp_t>(
-                ~"uv_tcp_t",
-                super::rustrt::rust_uv_helper_uv_tcp_t_size()
-            );
-        }
-    }
-    #[test]
-    fn test_uv_ll_struct_size_uv_connect_t() {
-        unsafe {
-            struct_size_check_common::<uv_connect_t>(
-                ~"uv_connect_t",
-                super::rustrt::rust_uv_helper_uv_connect_t_size()
-            );
-        }
-    }
-    #[test]
-    fn test_uv_ll_struct_size_uv_buf_t() {
-        unsafe {
-            struct_size_check_common::<uv_buf_t>(
-                ~"uv_buf_t",
-                super::rustrt::rust_uv_helper_uv_buf_t_size()
-            );
-        }
-    }
-    #[test]
-    fn test_uv_ll_struct_size_uv_write_t() {
-        unsafe {
-            struct_size_check_common::<uv_write_t>(
-                ~"uv_write_t",
-                super::rustrt::rust_uv_helper_uv_write_t_size()
-            );
-        }
-    }
-
-    #[test]
-    fn test_uv_ll_struct_size_sockaddr_in() {
-        unsafe {
-            struct_size_check_common::<sockaddr_in>(
-                ~"sockaddr_in",
-                super::rustrt::rust_uv_helper_sockaddr_in_size()
-            );
-        }
-    }
-    #[test]
-    fn test_uv_ll_struct_size_sockaddr_in6() {
-        unsafe {
-            let foreign_handle_size =
-                super::rustrt::rust_uv_helper_sockaddr_in6_size();
-            let rust_handle_size = sys::size_of::<sockaddr_in6>();
-            let output = fmt!("sockaddr_in6 -- foreign: %u rust: %u",
-                              foreign_handle_size as uint, rust_handle_size);
-            debug!(output);
-            // FIXME #1645 .. rust appears to pad structs to the nearest
-            // byte..?
-            // .. can't get the uv::ll::sockaddr_in6 to == 28 :/
-            // .. so the type always appears to be 32 in size.. which is
-            // good, i guess.. better too big than too little
-            fail_unless!((4u+foreign_handle_size as uint) ==
-                rust_handle_size);
-        }
-    }
-    #[test]
-    #[ignore(reason = "questionable size calculations")]
-    fn test_uv_ll_struct_size_addr_in() {
-        unsafe {
-            let foreign_handle_size =
-                super::rustrt::rust_uv_helper_addr_in_size();
-            let rust_handle_size = sys::size_of::<addr_in>();
-            let output = fmt!("addr_in -- foreign: %u rust: %u",
-                              foreign_handle_size as uint, rust_handle_size);
-            debug!(output);
-            // FIXME #1645 .. see note above about struct padding
-            fail_unless!((4u+foreign_handle_size as uint) ==
-                rust_handle_size);
-        }
-    }
-
-    #[test]
-    fn test_uv_ll_struct_size_uv_async_t() {
-        unsafe {
-            struct_size_check_common::<uv_async_t>(
-                ~"uv_async_t",
-                super::rustrt::rust_uv_helper_uv_async_t_size()
-            );
-        }
-    }
-
-    #[test]
-    fn test_uv_ll_struct_size_uv_timer_t() {
-        unsafe {
-            struct_size_check_common::<uv_timer_t>(
-                ~"uv_timer_t",
-                super::rustrt::rust_uv_helper_uv_timer_t_size()
-            );
-        }
-    }
-
-    #[test]
-    #[ignore(cfg(target_os = "win32"))]
-    fn test_uv_ll_struct_size_uv_getaddrinfo_t() {
-        unsafe {
-            struct_size_check_common::<uv_getaddrinfo_t>(
-                ~"uv_getaddrinfo_t",
-                super::rustrt::rust_uv_helper_uv_getaddrinfo_t_size()
-            );
-        }
-    }
-    #[test]
-    #[ignore(cfg(target_os = "macos"))]
-    #[ignore(cfg(target_os = "win32"))]
-    fn test_uv_ll_struct_size_addrinfo() {
-        unsafe {
-            struct_size_check_common::<uv_timer_t>(
-                ~"addrinfo",
-                super::rustrt::rust_uv_helper_uv_timer_t_size()
-            );
-        }
-    }
+extern {
+
+    fn rust_uv_handle_size(type_: uintptr_t) -> size_t;
+    fn rust_uv_req_size(type_: uintptr_t) -> size_t;
+    fn rust_uv_handle_type_max() -> uintptr_t;
+    fn rust_uv_req_type_max() -> uintptr_t;
+
+    // libuv public API
+    fn rust_uv_loop_new() -> *c_void;
+    fn rust_uv_loop_delete(lp: *c_void);
+    fn rust_uv_run(loop_handle: *c_void);
+    fn rust_uv_close(handle: *c_void, cb: *u8);
+    fn rust_uv_walk(loop_handle: *c_void, cb: *u8, arg: *c_void);
+
+    fn rust_uv_idle_new() -> *uv_idle_t;
+    fn rust_uv_idle_delete(handle: *uv_idle_t);
+    fn rust_uv_idle_init(loop_handle: *uv_loop_t, handle: *uv_idle_t) -> c_int;
+    fn rust_uv_idle_start(handle: *uv_idle_t, cb: uv_idle_cb) -> c_int;
+    fn rust_uv_idle_stop(handle: *uv_idle_t) -> c_int;
+
+    fn rust_uv_async_send(handle: *uv_async_t);
+    fn rust_uv_async_init(loop_handle: *c_void,
+                          async_handle: *uv_async_t,
+                          cb: *u8) -> c_int;
+    fn rust_uv_tcp_init(loop_handle: *c_void, handle_ptr: *uv_tcp_t) -> c_int;
+    // FIXME ref #2604 .. ?
+    fn rust_uv_buf_init(out_buf: *uv_buf_t, base: *u8, len: size_t);
+    fn rust_uv_last_error(loop_handle: *c_void) -> uv_err_t;
+    // FIXME ref #2064
+    fn rust_uv_strerror(err: *uv_err_t) -> *c_char;
+    // FIXME ref #2064
+    fn rust_uv_err_name(err: *uv_err_t) -> *c_char;
+    fn rust_uv_ip4_addrp(ip: *u8, port: c_int) -> *sockaddr_in;
+    fn rust_uv_ip6_addrp(ip: *u8, port: c_int) -> *sockaddr_in6;
+    fn rust_uv_free_ip4_addr(addr: *sockaddr_in);
+    fn rust_uv_free_ip6_addr(addr: *sockaddr_in6);
+    fn rust_uv_ip4_name(src: *sockaddr_in, dst: *u8, size: size_t) -> c_int;
+    fn rust_uv_ip6_name(src: *sockaddr_in6, dst: *u8, size: size_t) -> c_int;
+    fn rust_uv_ip4_port(src: *sockaddr_in) -> c_uint;
+    fn rust_uv_ip6_port(src: *sockaddr_in6) -> c_uint;
+    // FIXME ref #2064
+    fn rust_uv_tcp_connect(connect_ptr: *uv_connect_t,
+                           tcp_handle_ptr: *uv_tcp_t,
+                           ++after_cb: *u8,
+                           ++addr: *sockaddr_in) -> c_int;
+    // FIXME ref #2064
+    fn rust_uv_tcp_bind(tcp_server: *uv_tcp_t, ++addr: *sockaddr_in) -> c_int;
+    // FIXME ref #2064
+    fn rust_uv_tcp_connect6(connect_ptr: *uv_connect_t,
+                            tcp_handle_ptr: *uv_tcp_t,
+                            ++after_cb: *u8,
+                            ++addr: *sockaddr_in6) -> c_int;
+    // FIXME ref #2064
+    fn rust_uv_tcp_bind6(tcp_server: *uv_tcp_t, ++addr: *sockaddr_in6) -> c_int;
+    fn rust_uv_tcp_getpeername(tcp_handle_ptr: *uv_tcp_t, ++name: *sockaddr_in) -> c_int;
+    fn rust_uv_tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t, ++name: *sockaddr_in6) ->c_int;
+    fn rust_uv_listen(stream: *c_void, backlog: c_int, cb: *u8) -> c_int;
+    fn rust_uv_accept(server: *c_void, client: *c_void) -> c_int;
+    fn rust_uv_write(req: *c_void,
+                     stream: *c_void,
+                     ++buf_in: *uv_buf_t,
+                     buf_cnt: c_int,
+                     cb: *u8) -> c_int;
+    fn rust_uv_read_start(stream: *c_void,
+                          on_alloc: *u8,
+                          on_read: *u8) -> c_int;
+    fn rust_uv_read_stop(stream: *c_void) -> c_int;
+    fn rust_uv_timer_init(loop_handle: *c_void,
+                          timer_handle: *uv_timer_t) -> c_int;
+    fn rust_uv_timer_start(timer_handle: *uv_timer_t,
+                           cb: *u8,
+                           timeout: c_uint,
+                           repeat: c_uint) -> c_int;
+    fn rust_uv_timer_stop(handle: *uv_timer_t) -> c_int;
+
+    fn rust_uv_malloc_buf_base_of(sug_size: size_t) -> *u8;
+    fn rust_uv_free_base_of_buf(++buf: uv_buf_t);
+    fn rust_uv_get_stream_handle_from_connect_req(connect_req: *uv_connect_t) -> *uv_stream_t;
+    fn rust_uv_get_stream_handle_from_write_req(write_req: *uv_write_t) -> *uv_stream_t;
+    fn rust_uv_get_loop_for_uv_handle(handle: *c_void) -> *c_void;
+    fn rust_uv_get_data_for_uv_loop(loop_ptr: *c_void) -> *c_void;
+    fn rust_uv_set_data_for_uv_loop(loop_ptr: *c_void, data: *c_void);
+    fn rust_uv_get_data_for_uv_handle(handle: *c_void) -> *c_void;
+    fn rust_uv_set_data_for_uv_handle(handle: *c_void, data: *c_void);
+    fn rust_uv_get_data_for_req(req: *c_void) -> *c_void;
+    fn rust_uv_set_data_for_req(req: *c_void, data: *c_void);
+    fn rust_uv_get_base_from_buf(++buf: uv_buf_t) -> *u8;
+    fn rust_uv_get_len_from_buf(++buf: uv_buf_t) -> size_t;
 }
diff --git a/src/libstd/uv_ll.rs b/src/libstd/uv_ll.rs
index 682939975ef..b89441d055d 100644
--- a/src/libstd/uv_ll.rs
+++ b/src/libstd/uv_ll.rs
@@ -930,8 +930,6 @@ pub unsafe fn tcp_connect(connect_ptr: *uv_connect_t,
                       addr_ptr: *sockaddr_in,
                       after_connect_cb: *u8)
 -> libc::c_int {
-    log(debug, fmt!("b4 foreign tcp_connect--addr port: %u cb: %u",
-                    (*addr_ptr).sin_port as uint, after_connect_cb as uint));
     return rustrt::rust_uv_tcp_connect(connect_ptr, tcp_handle_ptr,
                                     after_connect_cb, addr_ptr);
 }
@@ -1021,22 +1019,8 @@ pub unsafe fn async_send(async_handle: *uv_async_t) {
 pub unsafe fn buf_init(input: *u8, len: uint) -> uv_buf_t {
     let out_buf = uv_buf_t { base: ptr::null(), len: 0 as libc::size_t };
     let out_buf_ptr = ptr::addr_of(&out_buf);
-    log(debug, fmt!("buf_init - input %u len %u out_buf: %u",
-                     input as uint,
-                     len as uint,
-                     out_buf_ptr as uint));
-    // yuck :/
     rustrt::rust_uv_buf_init(out_buf_ptr, input, len as size_t);
-    //let result = rustrt::rust_uv_buf_init_2(input, len as size_t);
-    log(debug, ~"after rust_uv_buf_init");
-    let res_base = get_base_from_buf(out_buf);
-    let res_len = get_len_from_buf(out_buf);
-    //let res_base = get_base_from_buf(result);
-    log(debug, fmt!("buf_init - result %u len %u",
-                     res_base as uint,
-                     res_len as uint));
     return out_buf;
-    //return result;
 }
 pub unsafe fn ip4_addr(ip: &str, port: int)
 -> sockaddr_in {
@@ -1078,8 +1062,6 @@ pub unsafe fn ip6_name(src: &sockaddr_in6) -> ~str {
                        0u8,0u8,0u8,0u8,0u8,0u8];
     do vec::as_imm_buf(dst) |dst_buf, size| {
         let src_unsafe_ptr = to_unsafe_ptr(src);
-        log(debug, fmt!("val of src *sockaddr_in6: %? sockaddr_in6: %?",
-                        src_unsafe_ptr, src));
         let result = rustrt::rust_uv_ip6_name(src_unsafe_ptr,
                                               dst_buf, size as libc::size_t);
         match result {
diff --git a/src/rt/rust_uv.cpp b/src/rt/rust_uv.cpp
index 51594348737..325b10b92df 100644
--- a/src/rt/rust_uv.cpp
+++ b/src/rt/rust_uv.cpp
@@ -479,6 +479,34 @@ extern "C" struct sockaddr_in6
 rust_uv_ip6_addr(const char* ip, int port) {
     return uv_ip6_addr(ip, port);
 }
+
+extern "C" struct sockaddr_in*
+rust_uv_ip4_addrp(const char* ip, int port) {
+  struct sockaddr_in addr = uv_ip4_addr(ip, port);
+  struct sockaddr_in *addrp = (sockaddr_in*)malloc(sizeof(struct sockaddr_in));
+  assert(addrp);
+  memcpy(addrp, &addr, sizeof(struct sockaddr_in));
+  return addrp;
+}
+extern "C" struct sockaddr_in6*
+rust_uv_ip6_addrp(const char* ip, int port) {
+  struct sockaddr_in6 addr = uv_ip6_addr(ip, port);
+  struct sockaddr_in6 *addrp = (sockaddr_in6*)malloc(sizeof(struct sockaddr_in6));
+  assert(addrp);
+  memcpy(addrp, &addr, sizeof(struct sockaddr_in6));
+  return addrp;
+}
+
+extern "C" void
+rust_uv_free_ip4_addr(sockaddr_in *addrp) {
+  free(addrp);
+}
+
+extern "C" void
+rust_uv_free_ip6_addr(sockaddr_in6 *addrp) {
+  free(addrp);
+}
+
 extern "C" int
 rust_uv_ip4_name(struct sockaddr_in* src, char* dst, size_t size) {
     return uv_ip4_name(src, dst, size);
@@ -563,3 +591,23 @@ extern "C" int
 rust_uv_idle_stop(uv_idle_t* idle) {
   return uv_idle_stop(idle);
 }
+
+extern "C" size_t
+rust_uv_handle_size(uintptr_t type) {
+  return uv_handle_size((uv_handle_type)type);
+}
+
+extern "C" size_t
+rust_uv_req_size(uintptr_t type) {
+  return uv_req_size((uv_req_type)type);
+}
+
+extern "C" uintptr_t
+rust_uv_handle_type_max() {
+  return UV_HANDLE_TYPE_MAX;
+}
+
+extern "C" uintptr_t
+rust_uv_req_type_max() {
+  return UV_REQ_TYPE_MAX;
+}
diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in
index 5a8868f33f9..4fde952ba95 100644
--- a/src/rt/rustrt.def.in
+++ b/src/rt/rustrt.def.in
@@ -202,3 +202,12 @@ rust_dbg_extern_identity_TwoU64s
 rust_dbg_extern_identity_double
 rust_dbg_extern_identity_u8
 rust_get_rt_env
+rust_uv_handle_size
+rust_uv_req_size
+rust_uv_handle_type_max
+rust_uv_req_type_max
+rust_uv_ip4_addrp
+rust_uv_ip6_addrp
+rust_uv_free_ip4_addr
+rust_uv_free_ip6_addr
+

From 42cba98509c6da6e7f99d1d8c87f3051cb9598d4 Mon Sep 17 00:00:00 2001
From: Brian Anderson <banderson@mozilla.com>
Date: Wed, 13 Mar 2013 17:58:23 -0700
Subject: [PATCH 05/12] core: Convert some multiline statements to single-line

---
 src/libcore/rt/context.rs | 15 ++----
 src/libcore/rt/sched.rs   | 14 +++---
 src/libcore/rt/uv.rs      | 62 ++++++++----------------
 src/libcore/rt/uvio.rs    | 12 ++---
 src/libcore/rt/uvll.rs    | 99 +++++++++++++--------------------------
 5 files changed, 67 insertions(+), 135 deletions(-)

diff --git a/src/libcore/rt/context.rs b/src/libcore/rt/context.rs
index 11512c3fe7a..55ea2eb3f50 100644
--- a/src/libcore/rt/context.rs
+++ b/src/libcore/rt/context.rs
@@ -54,8 +54,7 @@ pub impl Context {
         // which we will then modify to call the given function when restored
         let mut regs = new_regs();
         unsafe {
-            swap_registers(transmute_mut_region(&mut *regs),
-                           transmute_region(&*regs))
+            swap_registers(transmute_mut_region(&mut *regs), transmute_region(&*regs))
         };
 
         initialize_call_frame(&mut *regs, fp, argp, sp);
@@ -107,8 +106,7 @@ fn new_regs() -> ~Registers {
 }
 
 #[cfg(target_arch = "x86")]
-fn initialize_call_frame(regs: &mut Registers,
-                         fptr: *c_void, arg: *c_void, sp: *mut uint) {
+fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void, sp: *mut uint) {
 
     let sp = align_down(sp);
     let sp = mut_offset(sp, -4);
@@ -131,8 +129,7 @@ type Registers = [uint * 22];
 fn new_regs() -> ~Registers { ~[0, .. 22] }
 
 #[cfg(target_arch = "x86_64")]
-fn initialize_call_frame(regs: &mut Registers,
-                         fptr: *c_void, arg: *c_void, sp: *mut uint) {
+fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void, sp: *mut uint) {
 
     // Redefinitions from regs.h
     const RUSTRT_ARG0: uint = 3;
@@ -166,8 +163,7 @@ type Registers = [uint * 32];
 fn new_regs() -> ~Registers { ~[0, .. 32] }
 
 #[cfg(target_arch = "arm")]
-fn initialize_call_frame(regs: &mut Registers,
-                         fptr: *c_void, arg: *c_void, sp: *mut uint) {
+fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void, sp: *mut uint) {
     let sp = mut_offset(sp, -1);
 
     // The final return address. 0 indicates the bottom of the stack
@@ -185,8 +181,7 @@ type Registers = [uint * 32];
 fn new_regs() -> ~Registers { ~[0, .. 32] }
 
 #[cfg(target_arch = "mips")]
-fn initialize_call_frame(regs: &mut Registers,
-                         fptr: *c_void, arg: *c_void, sp: *mut uint) {
+fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void, sp: *mut uint) {
     let sp = mut_offset(sp, -1);
 
     // The final return address. 0 indicates the bottom of the stack
diff --git a/src/libcore/rt/sched.rs b/src/libcore/rt/sched.rs
index ff0b3d28e8d..74867dd7f12 100644
--- a/src/libcore/rt/sched.rs
+++ b/src/libcore/rt/sched.rs
@@ -183,8 +183,7 @@ pub impl Scheduler {
 
         let blocked_task = self.current_task.swap_unwrap();
         let f_fake_region = unsafe {
-            transmute::<&fn(&mut Scheduler, ~Task),
-                        &fn(&mut Scheduler, ~Task)>(f)
+            transmute::<&fn(&mut Scheduler, ~Task), &fn(&mut Scheduler, ~Task)>(f)
         };
         let f_opaque = HackAroundBorrowCk::from_fn(f_fake_region);
         self.enqueue_cleanup_job(GiveTask(blocked_task, f_opaque));
@@ -233,8 +232,7 @@ pub impl Scheduler {
         Context::swap(task_context, scheduler_context);
     }
 
-    priv fn swap_in_task_from_running_task(&mut self,
-                                           running_task: &mut Task) {
+    priv fn swap_in_task_from_running_task(&mut self, running_task: &mut Task) {
         let running_task_context = &mut running_task.saved_context;
         let next_context = &self.current_task.get_ref().saved_context;
         Context::swap(running_task_context, next_context);
@@ -344,8 +342,7 @@ impl ThreadLocalScheduler {
     fn put_scheduler(&mut self, scheduler: ~Scheduler) {
         unsafe {
             let key = match self { &ThreadLocalScheduler(key) => key };
-            let value: *mut c_void =
-                transmute::<~Scheduler, *mut c_void>(scheduler);
+            let value: *mut c_void = transmute::<~Scheduler, *mut c_void>(scheduler);
             tls::set(key, value);
         }
     }
@@ -357,8 +354,9 @@ impl ThreadLocalScheduler {
             fail_unless!(value.is_not_null());
             {
                 let value_ptr = &mut value;
-                let sched: &mut ~Scheduler =
-                    transmute::<&mut *mut c_void, &mut ~Scheduler>(value_ptr);
+                let sched: &mut ~Scheduler = {
+                    transmute::<&mut *mut c_void, &mut ~Scheduler>(value_ptr)
+                };
                 let sched: &mut Scheduler = &mut **sched;
                 return sched;
             }
diff --git a/src/libcore/rt/uv.rs b/src/libcore/rt/uv.rs
index 8280359eb2b..3bbd54b306f 100644
--- a/src/libcore/rt/uv.rs
+++ b/src/libcore/rt/uv.rs
@@ -157,10 +157,8 @@ pub impl IdleWatcher {
         };
 
         extern fn idle_cb(handle: *uvll::uv_idle_t, status: c_int) {
-            let idle_watcher: IdleWatcher =
-                NativeHandle::from_native_handle(handle);
-            let cb: &IdleCallback =
-                borrow_callback_from_watcher(&idle_watcher);
+            let idle_watcher: IdleWatcher = NativeHandle::from_native_handle(handle);
+            let cb: &IdleCallback = borrow_callback_from_watcher(&idle_watcher);
             let status = status_to_maybe_uv_error(handle, status);
             (*cb)(idle_watcher, status);
         }
@@ -175,9 +173,7 @@ pub impl IdleWatcher {
 
         extern fn close_cb(handle: *uvll::uv_idle_t) {
             let mut idle_watcher = NativeHandle::from_native_handle(handle);
-            drop_watcher_callback::<uvll::uv_idle_t,
-                                    IdleWatcher,
-                                    IdleCallback>(&mut idle_watcher);
+            drop_watcher_callback::<uvll::uv_idle_t, IdleWatcher, IdleCallback>(&mut idle_watcher);
             unsafe { uvll::idle_delete(handle) };
         }
     }
@@ -220,21 +216,17 @@ pub impl StreamWatcher {
         let handle = self.native_handle();
         unsafe { uvll::read_start(handle, alloc_cb, read_cb); }
 
-        extern fn alloc_cb(stream: *uvll::uv_stream_t,
-                           suggested_size: size_t) -> Buf {
-            let mut stream_watcher: StreamWatcher =
-                NativeHandle::from_native_handle(stream);
+        extern fn alloc_cb(stream: *uvll::uv_stream_t, suggested_size: size_t) -> Buf {
+            let mut stream_watcher: StreamWatcher = NativeHandle::from_native_handle(stream);
             let data = get_watcher_data(&mut stream_watcher);
             let alloc_cb = data.alloc_cb.get_ref();
             return (*alloc_cb)(suggested_size as uint);
         }
 
-        extern fn read_cb(stream: *uvll::uv_stream_t,
-                          nread: ssize_t, ++buf: Buf) {
+        extern fn read_cb(stream: *uvll::uv_stream_t, nread: ssize_t, ++buf: Buf) {
             rtdebug!("buf addr: %x", buf.base as uint);
             rtdebug!("buf len: %d", buf.len as int);
-            let mut stream_watcher: StreamWatcher =
-                NativeHandle::from_native_handle(stream);
+            let mut stream_watcher: StreamWatcher = NativeHandle::from_native_handle(stream);
             let data = get_watcher_data(&mut stream_watcher);
             let cb = data.read_cb.get_ref();
             let status = status_to_maybe_uv_error(stream, nread as c_int);
@@ -270,14 +262,11 @@ pub impl StreamWatcher {
         let _v = vec_from_uv_buf(buf);
 
         extern fn write_cb(req: *uvll::uv_write_t, status: c_int) {
-            let write_request: WriteRequest =
-                NativeHandle::from_native_handle(req);
+            let write_request: WriteRequest = NativeHandle::from_native_handle(req);
             let mut stream_watcher = write_request.stream();
             write_request.delete();
-            let cb = get_watcher_data(&mut stream_watcher)
-                .write_cb.swap_unwrap();
-            let status = status_to_maybe_uv_error(
-                stream_watcher.native_handle(), status);
+            let cb = get_watcher_data(&mut stream_watcher).write_cb.swap_unwrap();
+            let status = status_to_maybe_uv_error(stream_watcher.native_handle(), status);
             cb(stream_watcher, status);
         }
     }
@@ -301,8 +290,7 @@ pub impl StreamWatcher {
         unsafe { uvll::close(self.native_handle(), close_cb); }
 
         extern fn close_cb(handle: *uvll::uv_stream_t) {
-            let mut stream_watcher: StreamWatcher =
-                NativeHandle::from_native_handle(handle);
+            let mut stream_watcher: StreamWatcher = NativeHandle::from_native_handle(handle);
             {
                 let mut data = get_watcher_data(&mut stream_watcher);
                 data.close_cb.swap_unwrap()();
@@ -382,16 +370,14 @@ pub impl TcpWatcher {
 
             extern fn connect_cb(req: *uvll::uv_connect_t, status: c_int) {
                 rtdebug!("connect_t: %x", req as uint);
-                let connect_request: ConnectRequest =
-                    NativeHandle::from_native_handle(req);
+                let connect_request: ConnectRequest = NativeHandle::from_native_handle(req);
                 let mut stream_watcher = connect_request.stream();
                 connect_request.delete();
                 let cb: ConnectionCallback = {
                     let data = get_watcher_data(&mut stream_watcher);
                     data.connect_cb.swap_unwrap()
                 };
-                let status = status_to_maybe_uv_error(
-                    stream_watcher.native_handle(), status);
+                let status = status_to_maybe_uv_error(stream_watcher.native_handle(), status);
                 cb(stream_watcher, status);
             }
         }
@@ -412,19 +398,15 @@ pub impl TcpWatcher {
 
         extern fn connection_cb(handle: *uvll::uv_stream_t, status: c_int) {
             rtdebug!("connection_cb");
-            let mut stream_watcher: StreamWatcher =
-                NativeHandle::from_native_handle(handle);
-            let cb = get_watcher_data(&mut stream_watcher)
-                .connect_cb.swap_unwrap();
-            let status = status_to_maybe_uv_error(
-                stream_watcher.native_handle(), status);
+            let mut stream_watcher: StreamWatcher = NativeHandle::from_native_handle(handle);
+            let cb = get_watcher_data(&mut stream_watcher).connect_cb.swap_unwrap();
+            let status = status_to_maybe_uv_error(stream_watcher.native_handle(), status);
             cb(stream_watcher, status);
         }
     }
 
     fn as_stream(&self) -> StreamWatcher {
-        NativeHandle::from_native_handle(
-            self.native_handle() as *uvll::uv_stream_t)
+        NativeHandle::from_native_handle(self.native_handle() as *uvll::uv_stream_t)
     }
 }
 
@@ -460,9 +442,7 @@ impl ConnectRequest {
 
     fn stream(&self) -> StreamWatcher {
         unsafe {
-            let stream_handle =
-                uvll::get_stream_handle_from_connect_req(
-                    self.native_handle());
+            let stream_handle = uvll::get_stream_handle_from_connect_req(self.native_handle());
             NativeHandle::from_native_handle(stream_handle)
         }
     }
@@ -499,8 +479,7 @@ impl WriteRequest {
 
     fn stream(&self) -> StreamWatcher {
         unsafe {
-            let stream_handle =
-                uvll::get_stream_handle_from_write_req(self.native_handle());
+            let stream_handle = uvll::get_stream_handle_from_write_req(self.native_handle());
             NativeHandle::from_native_handle(stream_handle)
         }
     }
@@ -609,8 +588,7 @@ fn drop_watcher_callback<H, W: Watcher + NativeHandle<*H>, CB: Callback>(
             // Take ownership of the callback and drop it
             let _cb = transmute::<*c_void, ~CB>(handle_data);
             // Make sure the pointer is zeroed
-            uvll::set_data_for_uv_handle(
-                watcher.native_handle(), null::<()>());
+            uvll::set_data_for_uv_handle(watcher.native_handle(), null::<()>());
         }
     }
 }
diff --git a/src/libcore/rt/uvio.rs b/src/libcore/rt/uvio.rs
index f7275652e7f..53156ccc73d 100644
--- a/src/libcore/rt/uvio.rs
+++ b/src/libcore/rt/uvio.rs
@@ -189,12 +189,9 @@ impl TcpListener for UvTcpListener {
                 do server_tcp_watcher.listen |server_stream_watcher, status| {
                     let maybe_stream = if status.is_none() {
                         let mut server_stream_watcher = server_stream_watcher;
-                        let mut loop_ =
-                            loop_from_watcher(&server_stream_watcher);
-                        let mut client_tcp_watcher =
-                            TcpWatcher::new(&mut loop_);
-                        let mut client_tcp_watcher =
-                            client_tcp_watcher.as_stream();
+                        let mut loop_ = loop_from_watcher(&server_stream_watcher);
+                        let mut client_tcp_watcher = TcpWatcher::new(&mut loop_);
+                        let mut client_tcp_watcher = client_tcp_watcher.as_stream();
                         // XXX: Need's to be surfaced in interface
                         server_stream_watcher.accept(client_tcp_watcher);
                         Some(~UvStream::new(client_tcp_watcher))
@@ -425,8 +422,7 @@ fn test_read_and_block() {
                         // Yield to the other task in hopes that it
                         // will trigger a read callback while we are
                         // not ready for it
-                        do scheduler.block_running_task_and_then
-                            |scheduler, task| {
+                        do scheduler.block_running_task_and_then |scheduler, task| {
                             scheduler.task_queue.push_back(task);
                         }
                     }
diff --git a/src/libcore/rt/uvll.rs b/src/libcore/rt/uvll.rs
index 1332ddf1127..3606c9f4dd6 100644
--- a/src/libcore/rt/uvll.rs
+++ b/src/libcore/rt/uvll.rs
@@ -162,8 +162,7 @@ pub unsafe fn idle_delete(handle: *uv_idle_t) {
     rust_uv_idle_delete(handle)
 }
 
-pub unsafe fn idle_init(loop_handle: *uv_loop_t,
-                        handle: *uv_idle_t) -> c_int {
+pub unsafe fn idle_init(loop_handle: *uv_loop_t, handle: *uv_idle_t) -> c_int {
     rust_uv_idle_init(loop_handle, handle)
 }
 
@@ -183,8 +182,7 @@ pub unsafe fn tcp_init(loop_handle: *c_void, handle: *uv_tcp_t) -> c_int {
 pub unsafe fn tcp_connect(connect_ptr: *uv_connect_t,
                           tcp_handle_ptr: *uv_tcp_t,
                           addr_ptr: *sockaddr_in,
-                          after_connect_cb: *u8)
--> libc::c_int {
+                          after_connect_cb: *u8) -> c_int {
     return rust_uv_tcp_connect(connect_ptr, tcp_handle_ptr,
                                        after_connect_cb, addr_ptr);
 }
@@ -197,50 +195,37 @@ pub unsafe fn tcp_connect6(connect_ptr: *uv_connect_t,
                                         after_connect_cb, addr_ptr);
 }
 // FIXME ref #2064
-pub unsafe fn tcp_bind(tcp_server_ptr: *uv_tcp_t,
-                       addr_ptr: *sockaddr_in) -> c_int {
-    return rust_uv_tcp_bind(tcp_server_ptr,
-                                 addr_ptr);
+pub unsafe fn tcp_bind(tcp_server_ptr: *uv_tcp_t, addr_ptr: *sockaddr_in) -> c_int {
+    return rust_uv_tcp_bind(tcp_server_ptr, addr_ptr);
 }
 // FIXME ref #2064
-pub unsafe fn tcp_bind6(tcp_server_ptr: *uv_tcp_t,
-                        addr_ptr: *sockaddr_in6) -> c_int {
-    return rust_uv_tcp_bind6(tcp_server_ptr,
-                                 addr_ptr);
+pub unsafe fn tcp_bind6(tcp_server_ptr: *uv_tcp_t, addr_ptr: *sockaddr_in6) -> c_int {
+    return rust_uv_tcp_bind6(tcp_server_ptr, addr_ptr);
 }
 
-pub unsafe fn tcp_getpeername(tcp_handle_ptr: *uv_tcp_t,
-                              name: *sockaddr_in) -> c_int {
+pub unsafe fn tcp_getpeername(tcp_handle_ptr: *uv_tcp_t, name: *sockaddr_in) -> c_int {
     return rust_uv_tcp_getpeername(tcp_handle_ptr, name);
 }
 
-pub unsafe fn tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t,
-                               name: *sockaddr_in6) ->c_int {
+pub unsafe fn tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t, name: *sockaddr_in6) ->c_int {
     return rust_uv_tcp_getpeername6(tcp_handle_ptr, name);
 }
 
-pub unsafe fn listen<T>(stream: *T, backlog: c_int,
-                        cb: *u8) -> c_int {
+pub unsafe fn listen<T>(stream: *T, backlog: c_int, cb: *u8) -> c_int {
     return rust_uv_listen(stream as *c_void, backlog, cb);
 }
 
 pub unsafe fn accept(server: *c_void, client: *c_void) -> c_int {
-    return rust_uv_accept(server as *c_void,
-                               client as *c_void);
+    return rust_uv_accept(server as *c_void, client as *c_void);
 }
 
-pub unsafe fn write<T>(req: *uv_write_t, stream: *T,
-         buf_in: *~[uv_buf_t], cb: *u8) -> c_int {
+pub unsafe fn write<T>(req: *uv_write_t, stream: *T, buf_in: *~[uv_buf_t], cb: *u8) -> c_int {
     let buf_ptr = vec::raw::to_ptr(*buf_in);
     let buf_cnt = vec::len(*buf_in) as i32;
-    return rust_uv_write(req as *c_void,
-                              stream as *c_void,
-                              buf_ptr, buf_cnt, cb);
+    return rust_uv_write(req as *c_void, stream as *c_void, buf_ptr, buf_cnt, cb);
 }
-pub unsafe fn read_start(stream: *uv_stream_t, on_alloc: *u8,
-                     on_read: *u8) -> c_int {
-    return rust_uv_read_start(stream as *c_void,
-                                   on_alloc, on_read);
+pub unsafe fn read_start(stream: *uv_stream_t, on_alloc: *u8, on_read: *u8) -> c_int {
+    return rust_uv_read_start(stream as *c_void, on_alloc, on_read);
 }
 
 pub unsafe fn read_stop(stream: *uv_stream_t) -> c_int {
@@ -258,12 +243,8 @@ pub unsafe fn err_name(err: *uv_err_t) -> *c_char {
     return rust_uv_err_name(err);
 }
 
-pub unsafe fn async_init(loop_handle: *c_void,
-                         async_handle: *uv_async_t,
-                         cb: *u8) -> c_int {
-    return rust_uv_async_init(loop_handle,
-                                      async_handle,
-                                      cb);
+pub unsafe fn async_init(loop_handle: *c_void, async_handle: *uv_async_t, cb: *u8) -> c_int {
+    return rust_uv_async_init(loop_handle, async_handle, cb);
 }
 
 pub unsafe fn async_send(async_handle: *uv_async_t) {
@@ -276,31 +257,25 @@ pub unsafe fn buf_init(input: *u8, len: uint) -> uv_buf_t {
     return out_buf;
 }
 
-pub unsafe fn timer_init(loop_ptr: *c_void,
-                         timer_ptr: *uv_timer_t) -> c_int {
+pub unsafe fn timer_init(loop_ptr: *c_void, timer_ptr: *uv_timer_t) -> c_int {
     return rust_uv_timer_init(loop_ptr, timer_ptr);
 }
 pub unsafe fn timer_start(timer_ptr: *uv_timer_t, cb: *u8, timeout: uint,
                           repeat: uint) -> c_int {
-    return rust_uv_timer_start(timer_ptr, cb, timeout as c_uint,
-                                       repeat as c_uint);
+    return rust_uv_timer_start(timer_ptr, cb, timeout as c_uint, repeat as c_uint);
 }
 pub unsafe fn timer_stop(timer_ptr: *uv_timer_t) -> c_int {
     return rust_uv_timer_stop(timer_ptr);
 }
 
-pub unsafe fn malloc_ip4_addr(ip: &str, port: int)
--> *sockaddr_in {
+pub unsafe fn malloc_ip4_addr(ip: &str, port: int) -> *sockaddr_in {
     do str::as_c_str(ip) |ip_buf| {
-        rust_uv_ip4_addrp(ip_buf as *u8,
-                                  port as libc::c_int)
+        rust_uv_ip4_addrp(ip_buf as *u8, port as libc::c_int)
     }
 }
-pub unsafe fn malloc_ip6_addr(ip: &str, port: int)
--> *sockaddr_in6 {
+pub unsafe fn malloc_ip6_addr(ip: &str, port: int) -> *sockaddr_in6 {
     do str::as_c_str(ip) |ip_buf| {
-        rust_uv_ip6_addrp(ip_buf as *u8,
-                                  port as libc::c_int)
+        rust_uv_ip6_addrp(ip_buf as *u8, port as libc::c_int)
     }
 }
 
@@ -316,39 +291,29 @@ pub unsafe fn free_ip6_addr(addr: *sockaddr_in6) {
 pub unsafe fn get_loop_for_uv_handle<T>(handle: *T) -> *c_void {
     return rust_uv_get_loop_for_uv_handle(handle as *c_void);
 }
-pub unsafe fn get_stream_handle_from_connect_req(connect: *uv_connect_t)
-    -> *uv_stream_t {
-    return rust_uv_get_stream_handle_from_connect_req(
-        connect);
+pub unsafe fn get_stream_handle_from_connect_req(connect: *uv_connect_t) -> *uv_stream_t {
+    return rust_uv_get_stream_handle_from_connect_req(connect);
 }
-pub unsafe fn get_stream_handle_from_write_req(
-    write_req: *uv_write_t)
-    -> *uv_stream_t {
-    return rust_uv_get_stream_handle_from_write_req(
-        write_req);
+pub unsafe fn get_stream_handle_from_write_req(write_req: *uv_write_t) -> *uv_stream_t {
+    return rust_uv_get_stream_handle_from_write_req(write_req);
 }
 pub unsafe fn get_data_for_uv_loop(loop_ptr: *c_void) -> *c_void {
     rust_uv_get_data_for_uv_loop(loop_ptr)
 }
-pub unsafe fn set_data_for_uv_loop(loop_ptr: *c_void,
-                                   data: *c_void) {
+pub unsafe fn set_data_for_uv_loop(loop_ptr: *c_void, data: *c_void) {
     rust_uv_set_data_for_uv_loop(loop_ptr, data);
 }
 pub unsafe fn get_data_for_uv_handle<T>(handle: *T) -> *c_void {
     return rust_uv_get_data_for_uv_handle(handle as *c_void);
 }
-pub unsafe fn set_data_for_uv_handle<T, U>(handle: *T,
-                    data: *U) {
-    rust_uv_set_data_for_uv_handle(handle as *c_void,
-                                           data as *c_void);
+pub unsafe fn set_data_for_uv_handle<T, U>(handle: *T, data: *U) {
+    rust_uv_set_data_for_uv_handle(handle as *c_void, data as *c_void);
 }
 pub unsafe fn get_data_for_req<T>(req: *T) -> *c_void {
     return rust_uv_get_data_for_req(req as *c_void);
 }
-pub unsafe fn set_data_for_req<T, U>(req: *T,
-                                     data: *U) {
-    rust_uv_set_data_for_req(req as *c_void,
-                                     data as *c_void);
+pub unsafe fn set_data_for_req<T, U>(req: *T, data: *U) {
+    rust_uv_set_data_for_req(req as *c_void, data as *c_void);
 }
 pub unsafe fn get_base_from_buf(buf: uv_buf_t) -> *u8 {
     return rust_uv_get_base_from_buf(buf);
@@ -372,7 +337,7 @@ pub unsafe fn get_last_err_info(uv_loop: *c_void) -> ~str {
                     err_name, err_msg);
 }
 
-pub unsafe fn get_last_err_data(uv_loop: *libc::c_void) -> uv_err_data {
+pub unsafe fn get_last_err_data(uv_loop: *c_void) -> uv_err_data {
     let err = last_error(uv_loop);
     let err_ptr = ptr::addr_of(&err);
     let err_name = str::raw::from_c_str(err_name(err_ptr));

From 9a075f264a1024a3c03edc033be59971ad590171 Mon Sep 17 00:00:00 2001
From: Brian Anderson <banderson@mozilla.com>
Date: Wed, 13 Mar 2013 18:21:47 -0700
Subject: [PATCH 06/12] core: Rename rt::io to rt::rtio

This is an internal interface. I want to use rt::io for public interfaces.
---
 src/libcore/rt/mod.rs             | 2 +-
 src/libcore/rt/{io.rs => rtio.rs} | 0
 src/libcore/rt/sched.rs           | 2 +-
 src/libcore/rt/uv.rs              | 2 +-
 src/libcore/rt/uvio.rs            | 4 +---
 5 files changed, 4 insertions(+), 6 deletions(-)
 rename src/libcore/rt/{io.rs => rtio.rs} (100%)

diff --git a/src/libcore/rt/mod.rs b/src/libcore/rt/mod.rs
index 556431e9315..bc0efc01fbb 100644
--- a/src/libcore/rt/mod.rs
+++ b/src/libcore/rt/mod.rs
@@ -30,7 +30,7 @@ macro_rules! rtdebug (
 )
 
 mod sched;
-mod io;
+mod rtio;
 pub mod uvll;
 mod uvio;
 mod uv;
diff --git a/src/libcore/rt/io.rs b/src/libcore/rt/rtio.rs
similarity index 100%
rename from src/libcore/rt/io.rs
rename to src/libcore/rt/rtio.rs
diff --git a/src/libcore/rt/sched.rs b/src/libcore/rt/sched.rs
index 74867dd7f12..f47f86fd5fd 100644
--- a/src/libcore/rt/sched.rs
+++ b/src/libcore/rt/sched.rs
@@ -16,7 +16,7 @@ use ptr::mut_null;
 
 use super::work_queue::WorkQueue;
 use super::stack::{StackPool, StackSegment};
-use super::io::{EventLoop, EventLoopObject};
+use super::rtio::{EventLoop, EventLoopObject};
 use super::context::Context;
 use tls = super::thread_local_storage;
 
diff --git a/src/libcore/rt/uv.rs b/src/libcore/rt/uv.rs
index 3bbd54b306f..cc9e2fe8a7a 100644
--- a/src/libcore/rt/uv.rs
+++ b/src/libcore/rt/uv.rs
@@ -45,7 +45,7 @@ use ptr::null;
 use sys::size_of;
 use super::uvll;
 use super::uvll::*;
-use super::io::{IpAddr, Ipv4, Ipv6};
+use super::rtio::{IpAddr, Ipv4, Ipv6};
 use unstable::finally::Finally;
 
 #[cfg(test)] use unstable::run_in_bare_thread;
diff --git a/src/libcore/rt/uvio.rs b/src/libcore/rt/uvio.rs
index 53156ccc73d..1806da55efa 100644
--- a/src/libcore/rt/uvio.rs
+++ b/src/libcore/rt/uvio.rs
@@ -12,13 +12,11 @@ use option::*;
 use result::*;
 
 use super::uv::*;
-use super::io::*;
+use super::rtio::*;
 use ops::Drop;
 use cell::{Cell, empty_cell};
 use cast::transmute;
-use super::StreamObject;
 use super::sched::Scheduler;
-use super::IoFactoryObject;
 
 #[cfg(test)] use super::sched::Task;
 #[cfg(test)] use unstable::run_in_bare_thread;

From 5e6dacf32edc5b8529e6f0aafd17754d0e2e2284 Mon Sep 17 00:00:00 2001
From: Brian Anderson <banderson@mozilla.com>
Date: Thu, 14 Mar 2013 15:37:38 -0700
Subject: [PATCH 07/12] mk: If NO_REBUILD is set then don't rebuild core/std
 before testing

Can make turnaround of testing changes to core/std/syntax much faster.
---
 mk/tests.mk | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/mk/tests.mk b/mk/tests.mk
index 33a828d6e67..f96b7325f60 100644
--- a/mk/tests.mk
+++ b/mk/tests.mk
@@ -244,21 +244,29 @@ $(foreach host,$(CFG_HOST_TRIPLES), \
 
 define TEST_RUNNER
 
+# If NO_REBUILD is set then break the dependencies on std so we can
+# test crates without rebuilding core and std first
+ifeq ($(NO_REBUILD),)
+STDTESTDEP_$(1)_$(2)_$(3) = $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_STDLIB_$(2))
+else
+STDTESTDEP_$(1)_$(2)_$(3) =
+endif
+
 $(3)/test/coretest.stage$(1)-$(2)$$(X_$(2)):			\
 		$$(CORELIB_CRATE) $$(CORELIB_INPUTS)	\
-		$$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_STDLIB_$(2))
+		$$(STDTESTDEP_$(1)_$(2)_$(3))
 	@$$(call E, compile_and_link: $$@)
 	$$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test
 
 $(3)/test/stdtest.stage$(1)-$(2)$$(X_$(2)):			\
 		$$(STDLIB_CRATE) $$(STDLIB_INPUTS)	\
-		$$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_STDLIB_$(2))
+		$$(STDTESTDEP_$(1)_$(2)_$(3))
 	@$$(call E, compile_and_link: $$@)
 	$$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test
 
 $(3)/test/syntaxtest.stage$(1)-$(2)$$(X_$(2)):			\
 		$$(LIBSYNTAX_CRATE) $$(LIBSYNTAX_INPUTS)	\
-		$$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_STDLIB_$(2))
+		$$(STDTESTDEP_$(1)_$(2)_$(3))
 	@$$(call E, compile_and_link: $$@)
 	$$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test
 

From 57e85b5f947387195cec1338fcb94b7cfb88bd86 Mon Sep 17 00:00:00 2001
From: Brian Anderson <banderson@mozilla.com>
Date: Wed, 13 Mar 2013 20:02:48 -0700
Subject: [PATCH 08/12] core: Add rt::io and start sketching the API

---
 Makefile.in               |  2 +-
 src/libcore/rt/io/file.rs | 45 +++++++++++++++++++++++++++++++++++++++
 src/libcore/rt/io/mod.rs  | 45 +++++++++++++++++++++++++++++++++++++++
 src/libcore/rt/mod.rs     |  2 ++
 4 files changed, 93 insertions(+), 1 deletion(-)
 create mode 100644 src/libcore/rt/io/file.rs
 create mode 100644 src/libcore/rt/io/mod.rs

diff --git a/Makefile.in b/Makefile.in
index 268a25d72fc..dd2e6a95861 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -238,7 +238,7 @@ $(foreach target,$(CFG_TARGET_TRIPLES),\
 
 CORELIB_CRATE := $(S)src/libcore/core.rc
 CORELIB_INPUTS := $(wildcard $(addprefix $(S)src/libcore/,        \
-                                           core.rc *.rs */*.rs))
+                                           core.rc *.rs */*.rs */*/*rs))
 
 ######################################################################
 # Standard library variables
diff --git a/src/libcore/rt/io/file.rs b/src/libcore/rt/io/file.rs
new file mode 100644
index 00000000000..02ad6a00a14
--- /dev/null
+++ b/src/libcore/rt/io/file.rs
@@ -0,0 +1,45 @@
+// 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.
+
+use prelude::*;
+use super::super::sched::*;
+use super::super::rtio::*;
+use super::Stream;
+
+pub struct FileStream;
+
+pub impl FileStream {
+    static fn new(path: Path) -> FileStream {
+        fail!()
+    }
+}
+
+impl Stream for FileStream {
+    fn read(&mut self, buf: &mut [u8]) -> uint {
+        fail!()
+    }
+
+    fn eof(&mut self) -> bool {
+        fail!()
+    }
+
+    fn write(&mut self, v: &const [u8]) {
+        fail!()
+    }
+}
+
+#[test]
+#[ignore]
+fn super_simple_smoke_test_lets_go_read_some_files_and_have_a_good_time() {
+    let message = "it's alright. have a good time";
+    let filename = Path("test.txt");
+    let mut outstream = FileStream::new(filename);
+    outstream.write(message.to_bytes());
+}
diff --git a/src/libcore/rt/io/mod.rs b/src/libcore/rt/io/mod.rs
new file mode 100644
index 00000000000..f82092b829c
--- /dev/null
+++ b/src/libcore/rt/io/mod.rs
@@ -0,0 +1,45 @@
+// 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.
+
+use option::*;
+use comm::{GenericPort, GenericChan};
+
+pub mod file;
+
+// FIXME #5370 Strongly want this to be StreamError(&mut Stream)
+pub struct StreamError;
+
+// XXX: Can't put doc comments on macros
+// Raised by `Stream` instances on error. Returning `true` from the handler
+// indicates that the `Stream` should continue, `false` that it should fail.
+condition! {
+    stream_error: super::StreamError -> bool;
+}
+
+pub trait Stream {
+    /// Read bytes, up to the length of `buf` and place them in `buf`,
+    /// returning the number of bytes read or an `IoError`. Reads
+    /// 0 bytes on EOF.
+    ///
+    /// # Failure
+    ///
+    /// Raises the `reader_error` condition on error
+    fn read(&mut self, buf: &mut [u8]) -> uint;
+
+    /// Return whether the Reader has reached the end of the stream
+    fn eof(&mut self) -> bool;
+
+    /// Write the given buffer
+    ///
+    /// # Failure
+    ///
+    /// Raises the `writer_error` condition on error
+    fn write(&mut self, v: &const [u8]);
+}
diff --git a/src/libcore/rt/mod.rs b/src/libcore/rt/mod.rs
index bc0efc01fbb..c00162287fd 100644
--- a/src/libcore/rt/mod.rs
+++ b/src/libcore/rt/mod.rs
@@ -34,6 +34,8 @@ mod rtio;
 pub mod uvll;
 mod uvio;
 mod uv;
+#[path = "io/mod.rs"]
+mod io;
 // FIXME #5248: The import in `sched` doesn't resolve unless this is pub!
 pub mod thread_local_storage;
 mod work_queue;

From 7ef54c7ecd625376de092cbd741621987673c45f Mon Sep 17 00:00:00 2001
From: Brian Anderson <banderson@mozilla.com>
Date: Thu, 14 Mar 2013 19:54:04 -0700
Subject: [PATCH 09/12] core: Begin uv file system bindings

---
 src/libcore/rt/uv.rs | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/src/libcore/rt/uv.rs b/src/libcore/rt/uv.rs
index cc9e2fe8a7a..aab6d898ea8 100644
--- a/src/libcore/rt/uv.rs
+++ b/src/libcore/rt/uv.rs
@@ -498,6 +498,42 @@ impl NativeHandle<*uvll::uv_write_t> for WriteRequest {
     }
 }
 
+type FsCallback = ~fn(FsRequest, Option<UvError>);
+impl Callback for FsCallback { }
+
+pub struct FsRequest(*uvll::uv_fs_t);
+
+impl Request for FsRequest;
+
+impl FsRequest {
+    static fn new() -> FsRequest {
+        let fs_req = unsafe { malloc_req(UV_FS) };
+        fail_unless!(fs_req.is_not_null());
+        let fs_req = fs_req as *uvll::uv_write_t;
+        uvll::set_data_for_uv_req(fs_req, null::<()>());
+        Native(fs_req)
+    }
+
+    fn delete(self) {
+        unsafe { free_req(self.native_handle() as *c_void) }
+    }
+
+    fn open(&mut self, loop_: &EventLoop, cb: FsCallback) {
+    }
+
+    fn close(&mut self, loop_: &EventLoop, cb: FsCallback) {
+    }
+}
+
+impl NativeHandle<*uvll::uv_fs_t> for FsRequest {
+    static fn from_native_handle(handle: *uvll:: uv_fs_t) -> FsRequest {
+        FsRequest(handle)
+    }
+    fn native_handle(&self) -> *uvll::uv_fs_t {
+        match self { &FsRequest(ptr) => ptr }
+    }
+}
+
 // XXX: Need to define the error constants like EOF so they can be
 // compared to the UvError type
 

From a882554a785152c74c96cee036d252b071ed5ce1 Mon Sep 17 00:00:00 2001
From: Brian Anderson <banderson@mozilla.com>
Date: Fri, 15 Mar 2013 18:07:36 -0700
Subject: [PATCH 10/12] core: Refactor uv bindings

I can already see these are going to get massive. Putting them into multiple
files.
---
 src/libcore/rt/io/file.rs           |   6 +-
 src/libcore/rt/mod.rs               |   1 +
 src/libcore/rt/thread.rs            |   4 +-
 src/libcore/rt/uv/file.rs           |  52 +++
 src/libcore/rt/uv/mod.rs            | 456 +++++++++++++++++++++++++
 src/libcore/rt/{uv.rs => uv/net.rs} | 496 ++--------------------------
 src/libcore/rt/uvll.rs              |   1 +
 7 files changed, 534 insertions(+), 482 deletions(-)
 create mode 100644 src/libcore/rt/uv/file.rs
 create mode 100644 src/libcore/rt/uv/mod.rs
 rename src/libcore/rt/{uv.rs => uv/net.rs} (53%)

diff --git a/src/libcore/rt/io/file.rs b/src/libcore/rt/io/file.rs
index 02ad6a00a14..621cdca89e8 100644
--- a/src/libcore/rt/io/file.rs
+++ b/src/libcore/rt/io/file.rs
@@ -16,13 +16,13 @@ use super::Stream;
 pub struct FileStream;
 
 pub impl FileStream {
-    static fn new(path: Path) -> FileStream {
+    static fn new(_path: Path) -> FileStream {
         fail!()
     }
 }
 
 impl Stream for FileStream {
-    fn read(&mut self, buf: &mut [u8]) -> uint {
+    fn read(&mut self, _buf: &mut [u8]) -> uint {
         fail!()
     }
 
@@ -30,7 +30,7 @@ impl Stream for FileStream {
         fail!()
     }
 
-    fn write(&mut self, v: &const [u8]) {
+    fn write(&mut self, _v: &const [u8]) {
         fail!()
     }
 }
diff --git a/src/libcore/rt/mod.rs b/src/libcore/rt/mod.rs
index c00162287fd..1e919af4d14 100644
--- a/src/libcore/rt/mod.rs
+++ b/src/libcore/rt/mod.rs
@@ -33,6 +33,7 @@ mod sched;
 mod rtio;
 pub mod uvll;
 mod uvio;
+#[path = "uv/mod.rs"]
 mod uv;
 #[path = "io/mod.rs"]
 mod io;
diff --git a/src/libcore/rt/thread.rs b/src/libcore/rt/thread.rs
index be1d86c9cf7..5eb951be784 100644
--- a/src/libcore/rt/thread.rs
+++ b/src/libcore/rt/thread.rs
@@ -14,12 +14,12 @@ use ops::Drop;
 #[allow(non_camel_case_types)] // runtime type
 type raw_thread = libc::c_void;
 
-struct Thread {
+pub struct Thread {
     main: ~fn(),
     raw_thread: *raw_thread
 }
 
-impl Thread {
+pub impl Thread {
     static fn start(main: ~fn()) -> Thread {
         fn substart(main: &fn()) -> *raw_thread {
             unsafe { rust_raw_thread_start(&main) }
diff --git a/src/libcore/rt/uv/file.rs b/src/libcore/rt/uv/file.rs
new file mode 100644
index 00000000000..3a7b7f135d5
--- /dev/null
+++ b/src/libcore/rt/uv/file.rs
@@ -0,0 +1,52 @@
+// 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.
+
+use prelude::*;
+use ptr::null;
+use libc::c_void;
+use super::{UvError, Callback, Request, NativeHandle, Loop};
+use super::super::uvll;
+use super::super::uvll::*;
+
+pub type FsCallback = ~fn(FsRequest, Option<UvError>);
+impl Callback for FsCallback { }
+
+pub struct FsRequest(*uvll::uv_fs_t);
+
+impl Request for FsRequest;
+
+impl FsRequest {
+    static fn new() -> FsRequest {
+        let fs_req = unsafe { malloc_req(UV_FS) };
+        fail_unless!(fs_req.is_not_null());
+        let fs_req = fs_req as *uvll::uv_write_t;
+        unsafe { uvll::set_data_for_req(fs_req, null::<()>()); }
+        NativeHandle::from_native_handle(fs_req)
+    }
+
+    fn delete(self) {
+        unsafe { free_req(self.native_handle() as *c_void) }
+    }
+
+    fn open(&mut self, _loop_: &Loop, _cb: FsCallback) {
+    }
+
+    fn close(&mut self, _loop_: &Loop, _cb: FsCallback) {
+    }
+}
+
+impl NativeHandle<*uvll::uv_fs_t> for FsRequest {
+    static fn from_native_handle(handle: *uvll:: uv_fs_t) -> FsRequest {
+        FsRequest(handle)
+    }
+    fn native_handle(&self) -> *uvll::uv_fs_t {
+        match self { &FsRequest(ptr) => ptr }
+    }
+}
diff --git a/src/libcore/rt/uv/mod.rs b/src/libcore/rt/uv/mod.rs
new file mode 100644
index 00000000000..c44998532eb
--- /dev/null
+++ b/src/libcore/rt/uv/mod.rs
@@ -0,0 +1,456 @@
+// 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.
+
+/*!
+
+Bindings to libuv.
+
+UV types consist of the event loop (Loop), Watchers, Requests and
+Callbacks.
+
+Watchers and Requests encapsulate pointers to uv *handles*, which have
+subtyping relationships with each other.  This subtyping is reflected
+in the bindings with explicit or implicit coercions. For example, an
+upcast from TcpWatcher to StreamWatcher is done with
+`tcp_watcher.as_stream()`. In other cases a callback on a specific
+type of watcher will be passed a watcher of a supertype.
+
+Currently all use of Request types (connect/write requests) are
+encapsulated in the bindings and don't need to be dealt with by the
+caller.
+
+# Safety note
+
+Due to the complex lifecycle of uv handles, as well as compiler bugs,
+this module is not memory safe and requires explicit memory management,
+via `close` and `delete` methods.
+
+*/
+
+use option::*;
+use str::raw::from_c_str;
+use to_str::ToStr;
+use vec;
+use ptr;
+use libc::{c_void, c_int, size_t, malloc, free, ssize_t};
+use cast::{transmute, transmute_mut_region};
+use ptr::null;
+use sys::size_of;
+use super::uvll;
+use super::uvll::*;
+use unstable::finally::Finally;
+
+#[cfg(test)] use unstable::run_in_bare_thread;
+#[cfg(test)] use super::thread::Thread;
+#[cfg(test)] use cell::Cell;
+
+pub use self::file::{FsRequest, FsCallback};
+pub use self::net::{StreamWatcher, TcpWatcher};
+pub use self::net::{ReadCallback, AllocCallback, ConnectionCallback, ConnectCallback};
+
+pub mod file;
+pub mod net;
+
+/// A trait for callbacks to implement. Provides a little extra type safety
+/// for generic, unsafe interop functions like `set_watcher_callback`.
+pub trait Callback { }
+
+pub trait Request { }
+
+/// The trait implemented by uv 'watchers' (handles). Watchers are
+/// non-owning wrappers around the uv handles and are not completely
+/// safe - there may be multiple instances for a single underlying
+/// handle.  Watchers are generally created, then `start`ed, `stop`ed
+/// and `close`ed, but due to their complex life cycle may not be
+/// entirely memory safe if used in unanticipated patterns.
+pub trait Watcher {
+    fn event_loop(&self) -> Loop;
+}
+
+pub type NullCallback = ~fn();
+impl Callback for NullCallback { }
+
+/// A type that wraps a native handle
+pub trait NativeHandle<T> {
+    static pub fn from_native_handle(T) -> Self;
+    pub fn native_handle(&self) -> T;
+}
+
+/// XXX: Loop(*handle) is buggy with destructors. Normal structs
+/// with dtors may not be destructured, but tuple structs can,
+/// but the results are not correct.
+pub struct Loop {
+    handle: *uvll::uv_loop_t
+}
+
+pub impl Loop {
+    static fn new() -> Loop {
+        let handle = unsafe { uvll::loop_new() };
+        fail_unless!(handle.is_not_null());
+        NativeHandle::from_native_handle(handle)
+    }
+
+    fn run(&mut self) {
+        unsafe { uvll::run(self.native_handle()) };
+    }
+
+    fn close(&mut self) {
+        unsafe { uvll::loop_delete(self.native_handle()) };
+    }
+}
+
+impl NativeHandle<*uvll::uv_loop_t> for Loop {
+    static fn from_native_handle(handle: *uvll::uv_loop_t) -> Loop {
+        Loop { handle: handle }
+    }
+    fn native_handle(&self) -> *uvll::uv_loop_t {
+        self.handle
+    }
+}
+
+pub struct IdleWatcher(*uvll::uv_idle_t);
+
+impl Watcher for IdleWatcher {
+    fn event_loop(&self) -> Loop {
+        loop_from_watcher(self)
+    }
+}
+
+pub type IdleCallback = ~fn(IdleWatcher, Option<UvError>);
+impl Callback for IdleCallback { }
+
+pub impl IdleWatcher {
+    static fn new(loop_: &mut Loop) -> IdleWatcher {
+        unsafe {
+            let handle = uvll::idle_new();
+            fail_unless!(handle.is_not_null());
+            fail_unless!(0 == uvll::idle_init(loop_.native_handle(), handle));
+            uvll::set_data_for_uv_handle(handle, null::<()>());
+            NativeHandle::from_native_handle(handle)
+        }
+    }
+
+    fn start(&mut self, cb: IdleCallback) {
+
+        set_watcher_callback(self, cb);
+        unsafe {
+            fail_unless!(0 == uvll::idle_start(self.native_handle(), idle_cb))
+        };
+
+        extern fn idle_cb(handle: *uvll::uv_idle_t, status: c_int) {
+            let idle_watcher: IdleWatcher = NativeHandle::from_native_handle(handle);
+            let cb: &IdleCallback = borrow_callback_from_watcher(&idle_watcher);
+            let status = status_to_maybe_uv_error(handle, status);
+            (*cb)(idle_watcher, status);
+        }
+    }
+
+    fn stop(&mut self) {
+        unsafe { fail_unless!(0 == uvll::idle_stop(self.native_handle())); }
+    }
+
+    fn close(self) {
+        unsafe { uvll::close(self.native_handle(), close_cb) };
+
+        extern fn close_cb(handle: *uvll::uv_idle_t) {
+            let mut idle_watcher = NativeHandle::from_native_handle(handle);
+            drop_watcher_callback::<uvll::uv_idle_t, IdleWatcher, IdleCallback>(&mut idle_watcher);
+            unsafe { uvll::idle_delete(handle) };
+        }
+    }
+}
+
+impl NativeHandle<*uvll::uv_idle_t> for IdleWatcher {
+    static fn from_native_handle(handle: *uvll::uv_idle_t) -> IdleWatcher {
+        IdleWatcher(handle)
+    }
+    fn native_handle(&self) -> *uvll::uv_idle_t {
+        match self { &IdleWatcher(ptr) => ptr }
+    }
+}
+
+// XXX: Need to define the error constants like EOF so they can be
+// compared to the UvError type
+
+pub struct UvError(uvll::uv_err_t);
+
+pub impl UvError {
+
+    pure fn name(&self) -> ~str {
+        unsafe {
+            let inner = match self { &UvError(ref a) => a };
+            let name_str = uvll::err_name(inner);
+            fail_unless!(name_str.is_not_null());
+            from_c_str(name_str)
+        }
+    }
+
+    pure fn desc(&self) -> ~str {
+        unsafe {
+            let inner = match self { &UvError(ref a) => a };
+            let desc_str = uvll::strerror(inner);
+            fail_unless!(desc_str.is_not_null());
+            from_c_str(desc_str)
+        }
+    }
+}
+
+impl ToStr for UvError {
+    pure fn to_str(&self) -> ~str {
+        fmt!("%s: %s", self.name(), self.desc())
+    }
+}
+
+#[test]
+fn error_smoke_test() {
+    let err = uvll::uv_err_t { code: 1, sys_errno_: 1 };
+    let err: UvError = UvError(err);
+    fail_unless!(err.to_str() == ~"EOF: end of file");
+}
+
+
+/// Given a uv handle, convert a callback status to a UvError
+// XXX: Follow the pattern below by parameterizing over T: Watcher, not T
+pub fn status_to_maybe_uv_error<T>(handle: *T, status: c_int) -> Option<UvError> {
+    if status != -1 {
+        None
+    } else {
+        unsafe {
+            rtdebug!("handle: %x", handle as uint);
+            let loop_ = uvll::get_loop_for_uv_handle(handle);
+            rtdebug!("loop: %x", loop_ as uint);
+            let err = uvll::last_error(loop_);
+            Some(UvError(err))
+        }
+    }
+}
+
+/// Get the uv event loop from a Watcher
+pub fn loop_from_watcher<H, W: Watcher + NativeHandle<*H>>(
+    watcher: &W) -> Loop {
+
+    let handle = watcher.native_handle();
+    let loop_ = unsafe { uvll::get_loop_for_uv_handle(handle) };
+    NativeHandle::from_native_handle(loop_)
+}
+
+/// Set the custom data on a handle to a callback Note: This is only
+/// suitable for watchers that make just one type of callback.  For
+/// others use WatcherData
+pub fn set_watcher_callback<H, W: Watcher + NativeHandle<*H>, CB: Callback>(
+    watcher: &mut W, cb: CB) {
+
+    drop_watcher_callback::<H, W, CB>(watcher);
+    // XXX: Boxing the callback so it fits into a
+    // pointer. Unfortunate extra allocation
+    let boxed_cb = ~cb;
+    let data = unsafe { transmute::<~CB, *c_void>(boxed_cb) };
+    unsafe { uvll::set_data_for_uv_handle(watcher.native_handle(), data) };
+}
+
+/// Delete a callback from a handle's custom data
+pub fn drop_watcher_callback<H, W: Watcher + NativeHandle<*H>, CB: Callback>(
+    watcher: &mut W) {
+
+    unsafe {
+        let handle = watcher.native_handle();
+        let handle_data: *c_void = uvll::get_data_for_uv_handle(handle);
+        if handle_data.is_not_null() {
+            // Take ownership of the callback and drop it
+            let _cb = transmute::<*c_void, ~CB>(handle_data);
+            // Make sure the pointer is zeroed
+            uvll::set_data_for_uv_handle(watcher.native_handle(), null::<()>());
+        }
+    }
+}
+
+/// Take a pointer to the callback installed as custom data
+pub fn borrow_callback_from_watcher<H, W: Watcher + NativeHandle<*H>,
+                                CB: Callback>(watcher: &W) -> &CB {
+
+    unsafe {
+        let handle = watcher.native_handle();
+        let handle_data: *c_void = uvll::get_data_for_uv_handle(handle);
+        fail_unless!(handle_data.is_not_null());
+        let cb = transmute::<&*c_void, &~CB>(&handle_data);
+        return &**cb;
+    }
+}
+
+/// Take ownership of the callback installed as custom data
+pub fn take_callback_from_watcher<H, W: Watcher + NativeHandle<*H>, CB: Callback>(
+    watcher: &mut W) -> CB {
+
+    unsafe {
+        let handle = watcher.native_handle();
+        let handle_data: *c_void = uvll::get_data_for_uv_handle(handle);
+        fail_unless!(handle_data.is_not_null());
+        uvll::set_data_for_uv_handle(handle, null::<()>());
+        let cb: ~CB = transmute::<*c_void, ~CB>(handle_data);
+        let cb = match cb { ~cb => cb };
+        return cb;
+    }
+}
+
+/// Callbacks used by StreamWatchers, set as custom data on the foreign handle
+struct WatcherData {
+    read_cb: Option<ReadCallback>,
+    write_cb: Option<ConnectionCallback>,
+    connect_cb: Option<ConnectionCallback>,
+    close_cb: Option<NullCallback>,
+    alloc_cb: Option<AllocCallback>
+}
+
+pub fn install_watcher_data<H, W: Watcher + NativeHandle<*H>>(watcher: &mut W) {
+    unsafe {
+        let data = ~WatcherData {
+            read_cb: None,
+            write_cb: None,
+            connect_cb: None,
+            close_cb: None,
+            alloc_cb: None
+        };
+        let data = transmute::<~WatcherData, *c_void>(data);
+        uvll::set_data_for_uv_handle(watcher.native_handle(), data);
+    }
+}
+
+pub fn get_watcher_data<H, W: Watcher + NativeHandle<*H>>(
+    watcher: &r/mut W) -> &r/mut WatcherData {
+
+    unsafe {
+        let data = uvll::get_data_for_uv_handle(watcher.native_handle());
+        let data = transmute::<&*c_void, &mut ~WatcherData>(&data);
+        return &mut **data;
+    }
+}
+
+pub fn drop_watcher_data<H, W: Watcher + NativeHandle<*H>>(watcher: &mut W) {
+    unsafe {
+        let data = uvll::get_data_for_uv_handle(watcher.native_handle());
+        let _data = transmute::<*c_void, ~WatcherData>(data);
+        uvll::set_data_for_uv_handle(watcher.native_handle(), null::<()>());
+    }
+}
+
+#[test]
+fn test_slice_to_uv_buf() {
+    let slice = [0, .. 20];
+    let buf = slice_to_uv_buf(slice);
+
+    fail_unless!(buf.len == 20);
+
+    unsafe {
+        let base = transmute::<*u8, *mut u8>(buf.base);
+        (*base) = 1;
+        (*ptr::mut_offset(base, 1)) = 2;
+    }
+
+    fail_unless!(slice[0] == 1);
+    fail_unless!(slice[1] == 2);
+}
+
+/// The uv buffer type
+pub type Buf = uvll::uv_buf_t;
+
+/// Borrow a slice to a Buf
+pub fn slice_to_uv_buf(v: &[u8]) -> Buf {
+    let data = unsafe { vec::raw::to_ptr(v) };
+    unsafe { uvll::buf_init(data, v.len()) }
+}
+
+// XXX: Do these conversions without copying
+
+/// Transmute an owned vector to a Buf
+pub fn vec_to_uv_buf(v: ~[u8]) -> Buf {
+    let data = unsafe { malloc(v.len() as size_t) } as *u8;
+    fail_unless!(data.is_not_null());
+    do vec::as_imm_buf(v) |b, l| {
+        let data = data as *mut u8;
+        unsafe { ptr::copy_memory(data, b, l) }
+    }
+    let buf = unsafe { uvll::buf_init(data, v.len()) };
+    return buf;
+}
+
+/// Transmute a Buf that was once a ~[u8] back to ~[u8]
+pub fn vec_from_uv_buf(buf: Buf) -> Option<~[u8]> {
+    if !(buf.len == 0 && buf.base.is_null()) {
+        let v = unsafe { vec::from_buf(buf.base, buf.len as uint) };
+        unsafe { free(buf.base as *c_void) };
+        return Some(v);
+    } else {
+        // No buffer
+        return None;
+    }
+}
+
+#[test]
+fn loop_smoke_test() {
+    do run_in_bare_thread {
+        let mut loop_ = Loop::new();
+        loop_.run();
+        loop_.close();
+    }
+}
+
+#[test]
+#[ignore(reason = "valgrind - loop destroyed before watcher?")]
+fn idle_new_then_close() {
+    do run_in_bare_thread {
+        let mut loop_ = Loop::new();
+        let mut idle_watcher = { IdleWatcher::new(&mut loop_) };
+        idle_watcher.close();
+    }
+}
+
+#[test]
+fn idle_smoke_test() {
+    do run_in_bare_thread {
+        let mut loop_ = Loop::new();
+        let mut idle_watcher = { IdleWatcher::new(&mut loop_) };
+        let mut count = 10;
+        let count_ptr: *mut int = &mut count;
+        do idle_watcher.start |idle_watcher, status| {
+            let mut idle_watcher = idle_watcher;
+            fail_unless!(status.is_none());
+            if unsafe { *count_ptr == 10 } {
+                idle_watcher.stop();
+                idle_watcher.close();
+            } else {
+                unsafe { *count_ptr = *count_ptr + 1; }
+            }
+        }
+        loop_.run();
+        loop_.close();
+        fail_unless!(count == 10);
+    }
+}
+
+#[test]
+fn idle_start_stop_start() {
+    do run_in_bare_thread {
+        let mut loop_ = Loop::new();
+        let mut idle_watcher = { IdleWatcher::new(&mut loop_) };
+        do idle_watcher.start |idle_watcher, status| {
+            let mut idle_watcher = idle_watcher;
+            fail_unless!(status.is_none());
+            idle_watcher.stop();
+            do idle_watcher.start |idle_watcher, status| {
+                fail_unless!(status.is_none());
+                let mut idle_watcher = idle_watcher;
+                idle_watcher.stop();
+                idle_watcher.close();
+            }
+        }
+        loop_.run();
+        loop_.close();
+    }
+}
diff --git a/src/libcore/rt/uv.rs b/src/libcore/rt/uv/net.rs
similarity index 53%
rename from src/libcore/rt/uv.rs
rename to src/libcore/rt/uv/net.rs
index aab6d898ea8..bcbb1b2d02e 100644
--- a/src/libcore/rt/uv.rs
+++ b/src/libcore/rt/uv/net.rs
@@ -8,49 +8,23 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-/*!
-
-Bindings to libuv.
-
-UV types consist of the event loop (Loop), Watchers, Requests and
-Callbacks.
-
-Watchers and Requests encapsulate pointers to uv *handles*, which have
-subtyping relationships with each other.  This subtyping is reflected
-in the bindings with explicit or implicit coercions. For example, an
-upcast from TcpWatcher to StreamWatcher is done with
-`tcp_watcher.as_stream()`. In other cases a callback on a specific
-type of watcher will be passed a watcher of a supertype.
-
-Currently all use of Request types (connect/write requests) are
-encapsulated in the bindings and don't need to be dealt with by the
-caller.
-
-# Safety note
-
-Due to the complex lifecycle of uv handles, as well as compiler bugs,
-this module is not memory safe and requires explicit memory management,
-via `close` and `delete` methods.
-
-*/
-
-use option::*;
-use str::raw::from_c_str;
-use to_str::ToStr;
-use vec;
-use ptr;
-use libc::{c_void, c_int, size_t, malloc, free, ssize_t};
+use prelude::*;
+use libc::{size_t, ssize_t, c_int, c_void};
 use cast::{transmute, transmute_mut_region};
-use ptr::null;
-use sys::size_of;
-use super::uvll;
-use super::uvll::*;
-use super::rtio::{IpAddr, Ipv4, Ipv6};
-use unstable::finally::Finally;
+use super::super::uvll;
+use super::super::uvll::*;
+use super::{Loop, Watcher, Request, UvError, Buf, Callback, NativeHandle, NullCallback,
+            loop_from_watcher, status_to_maybe_uv_error,
+            install_watcher_data, get_watcher_data, drop_watcher_data,
+            vec_to_uv_buf, vec_from_uv_buf};
+use super::super::rtio::{IpAddr, Ipv4, Ipv6};
 
-#[cfg(test)] use unstable::run_in_bare_thread;
-#[cfg(test)] use super::thread::Thread;
-#[cfg(test)] use cell::Cell;
+#[cfg(test)]
+use unstable::run_in_bare_thread;
+#[cfg(test)]
+use super::super::thread::Thread;
+#[cfg(test)]
+use cell::Cell;
 
 fn ip4_as_uv_ip4(addr: IpAddr, f: &fn(*sockaddr_in)) {
     match addr {
@@ -72,122 +46,6 @@ fn ip4_as_uv_ip4(addr: IpAddr, f: &fn(*sockaddr_in)) {
     }
 }
 
-/// A trait for callbacks to implement. Provides a little extra type safety
-/// for generic, unsafe interop functions like `set_watcher_callback`.
-trait Callback { }
-
-type NullCallback = ~fn();
-impl Callback for NullCallback { }
-
-/// A type that wraps a native handle
-trait NativeHandle<T> {
-    static pub fn from_native_handle(T) -> Self;
-    pub fn native_handle(&self) -> T;
-}
-
-/// XXX: Loop(*handle) is buggy with destructors. Normal structs
-/// with dtors may not be destructured, but tuple structs can,
-/// but the results are not correct.
-pub struct Loop {
-    handle: *uvll::uv_loop_t
-}
-
-pub impl Loop {
-    static fn new() -> Loop {
-        let handle = unsafe { uvll::loop_new() };
-        fail_unless!(handle.is_not_null());
-        NativeHandle::from_native_handle(handle)
-    }
-
-    fn run(&mut self) {
-        unsafe { uvll::run(self.native_handle()) };
-    }
-
-    fn close(&mut self) {
-        unsafe { uvll::loop_delete(self.native_handle()) };
-    }
-}
-
-impl NativeHandle<*uvll::uv_loop_t> for Loop {
-    static fn from_native_handle(handle: *uvll::uv_loop_t) -> Loop {
-        Loop { handle: handle }
-    }
-    fn native_handle(&self) -> *uvll::uv_loop_t {
-        self.handle
-    }
-}
-
-/// The trait implemented by uv 'watchers' (handles). Watchers are
-/// non-owning wrappers around the uv handles and are not completely
-/// safe - there may be multiple instances for a single underlying
-/// handle.  Watchers are generally created, then `start`ed, `stop`ed
-/// and `close`ed, but due to their complex life cycle may not be
-/// entirely memory safe if used in unanticipated patterns.
-trait Watcher {
-    fn event_loop(&self) -> Loop;
-}
-
-pub struct IdleWatcher(*uvll::uv_idle_t);
-
-impl Watcher for IdleWatcher {
-    fn event_loop(&self) -> Loop {
-        loop_from_watcher(self)
-    }
-}
-
-type IdleCallback = ~fn(IdleWatcher, Option<UvError>);
-impl Callback for IdleCallback { }
-
-pub impl IdleWatcher {
-    static fn new(loop_: &mut Loop) -> IdleWatcher {
-        unsafe {
-            let handle = uvll::idle_new();
-            fail_unless!(handle.is_not_null());
-            fail_unless!(0 == uvll::idle_init(loop_.native_handle(), handle));
-            uvll::set_data_for_uv_handle(handle, null::<()>());
-            NativeHandle::from_native_handle(handle)
-        }
-    }
-
-    fn start(&mut self, cb: IdleCallback) {
-
-        set_watcher_callback(self, cb);
-        unsafe {
-            fail_unless!(0 == uvll::idle_start(self.native_handle(), idle_cb))
-        };
-
-        extern fn idle_cb(handle: *uvll::uv_idle_t, status: c_int) {
-            let idle_watcher: IdleWatcher = NativeHandle::from_native_handle(handle);
-            let cb: &IdleCallback = borrow_callback_from_watcher(&idle_watcher);
-            let status = status_to_maybe_uv_error(handle, status);
-            (*cb)(idle_watcher, status);
-        }
-    }
-
-    fn stop(&mut self) {
-        unsafe { fail_unless!(0 == uvll::idle_stop(self.native_handle())); }
-    }
-
-    fn close(self) {
-        unsafe { uvll::close(self.native_handle(), close_cb) };
-
-        extern fn close_cb(handle: *uvll::uv_idle_t) {
-            let mut idle_watcher = NativeHandle::from_native_handle(handle);
-            drop_watcher_callback::<uvll::uv_idle_t, IdleWatcher, IdleCallback>(&mut idle_watcher);
-            unsafe { uvll::idle_delete(handle) };
-        }
-    }
-}
-
-impl NativeHandle<*uvll::uv_idle_t> for IdleWatcher {
-    static fn from_native_handle(handle: *uvll::uv_idle_t) -> IdleWatcher {
-        IdleWatcher(handle)
-    }
-    fn native_handle(&self) -> *uvll::uv_idle_t {
-        match self { &IdleWatcher(ptr) => ptr }
-    }
-}
-
 // uv_stream t is the parent class of uv_tcp_t, uv_pipe_t, uv_tty_t
 // and uv_file_t
 pub struct StreamWatcher(*uvll::uv_stream_t);
@@ -198,7 +56,7 @@ impl Watcher for StreamWatcher {
     }
 }
 
-type ReadCallback = ~fn(StreamWatcher, int, Buf, Option<UvError>);
+pub type ReadCallback = ~fn(StreamWatcher, int, Buf, Option<UvError>);
 impl Callback for ReadCallback { }
 
 // XXX: The uv alloc callback also has a *uv_handle_t arg
@@ -319,7 +177,7 @@ impl Watcher for TcpWatcher {
     }
 }
 
-type ConnectionCallback = ~fn(StreamWatcher, Option<UvError>);
+pub type ConnectionCallback = ~fn(StreamWatcher, Option<UvError>);
 impl Callback for ConnectionCallback { }
 
 pub impl TcpWatcher {
@@ -419,9 +277,7 @@ impl NativeHandle<*uvll::uv_tcp_t> for TcpWatcher {
     }
 }
 
-trait Request { }
-
-type ConnectCallback = ~fn(ConnectRequest, Option<UvError>);
+pub type ConnectCallback = ~fn(ConnectRequest, Option<UvError>);
 impl Callback for ConnectCallback { }
 
 // uv_connect_t is a subclass of uv_req_t
@@ -466,7 +322,7 @@ pub struct WriteRequest(*uvll::uv_write_t);
 
 impl Request for WriteRequest { }
 
-impl WriteRequest {
+pub impl WriteRequest {
 
     static fn new() -> WriteRequest {
         let write_handle = unsafe {
@@ -498,320 +354,6 @@ impl NativeHandle<*uvll::uv_write_t> for WriteRequest {
     }
 }
 
-type FsCallback = ~fn(FsRequest, Option<UvError>);
-impl Callback for FsCallback { }
-
-pub struct FsRequest(*uvll::uv_fs_t);
-
-impl Request for FsRequest;
-
-impl FsRequest {
-    static fn new() -> FsRequest {
-        let fs_req = unsafe { malloc_req(UV_FS) };
-        fail_unless!(fs_req.is_not_null());
-        let fs_req = fs_req as *uvll::uv_write_t;
-        uvll::set_data_for_uv_req(fs_req, null::<()>());
-        Native(fs_req)
-    }
-
-    fn delete(self) {
-        unsafe { free_req(self.native_handle() as *c_void) }
-    }
-
-    fn open(&mut self, loop_: &EventLoop, cb: FsCallback) {
-    }
-
-    fn close(&mut self, loop_: &EventLoop, cb: FsCallback) {
-    }
-}
-
-impl NativeHandle<*uvll::uv_fs_t> for FsRequest {
-    static fn from_native_handle(handle: *uvll:: uv_fs_t) -> FsRequest {
-        FsRequest(handle)
-    }
-    fn native_handle(&self) -> *uvll::uv_fs_t {
-        match self { &FsRequest(ptr) => ptr }
-    }
-}
-
-// XXX: Need to define the error constants like EOF so they can be
-// compared to the UvError type
-
-struct UvError(uvll::uv_err_t);
-
-impl UvError {
-
-    pure fn name(&self) -> ~str {
-        unsafe {
-            let inner = match self { &UvError(ref a) => a };
-            let name_str = uvll::err_name(inner);
-            fail_unless!(name_str.is_not_null());
-            from_c_str(name_str)
-        }
-    }
-
-    pure fn desc(&self) -> ~str {
-        unsafe {
-            let inner = match self { &UvError(ref a) => a };
-            let desc_str = uvll::strerror(inner);
-            fail_unless!(desc_str.is_not_null());
-            from_c_str(desc_str)
-        }
-    }
-}
-
-impl ToStr for UvError {
-    pure fn to_str(&self) -> ~str {
-        fmt!("%s: %s", self.name(), self.desc())
-    }
-}
-
-#[test]
-fn error_smoke_test() {
-    let err = uvll::uv_err_t { code: 1, sys_errno_: 1 };
-    let err: UvError = UvError(err);
-    fail_unless!(err.to_str() == ~"EOF: end of file");
-}
-
-
-/// Given a uv handle, convert a callback status to a UvError
-// XXX: Follow the pattern below by parameterizing over T: Watcher, not T
-fn status_to_maybe_uv_error<T>(handle: *T, status: c_int) -> Option<UvError> {
-    if status != -1 {
-        None
-    } else {
-        unsafe {
-            rtdebug!("handle: %x", handle as uint);
-            let loop_ = uvll::get_loop_for_uv_handle(handle);
-            rtdebug!("loop: %x", loop_ as uint);
-            let err = uvll::last_error(loop_);
-            Some(UvError(err))
-        }
-    }
-}
-
-/// Get the uv event loop from a Watcher
-pub fn loop_from_watcher<H, W: Watcher + NativeHandle<*H>>(
-    watcher: &W) -> Loop {
-
-    let handle = watcher.native_handle();
-    let loop_ = unsafe { uvll::get_loop_for_uv_handle(handle) };
-    NativeHandle::from_native_handle(loop_)
-}
-
-/// Set the custom data on a handle to a callback Note: This is only
-/// suitable for watchers that make just one type of callback.  For
-/// others use WatcherData
-fn set_watcher_callback<H, W: Watcher + NativeHandle<*H>, CB: Callback>(
-    watcher: &mut W, cb: CB) {
-
-    drop_watcher_callback::<H, W, CB>(watcher);
-    // XXX: Boxing the callback so it fits into a
-    // pointer. Unfortunate extra allocation
-    let boxed_cb = ~cb;
-    let data = unsafe { transmute::<~CB, *c_void>(boxed_cb) };
-    unsafe { uvll::set_data_for_uv_handle(watcher.native_handle(), data) };
-}
-
-/// Delete a callback from a handle's custom data
-fn drop_watcher_callback<H, W: Watcher + NativeHandle<*H>, CB: Callback>(
-    watcher: &mut W) {
-
-    unsafe {
-        let handle = watcher.native_handle();
-        let handle_data: *c_void = uvll::get_data_for_uv_handle(handle);
-        if handle_data.is_not_null() {
-            // Take ownership of the callback and drop it
-            let _cb = transmute::<*c_void, ~CB>(handle_data);
-            // Make sure the pointer is zeroed
-            uvll::set_data_for_uv_handle(watcher.native_handle(), null::<()>());
-        }
-    }
-}
-
-/// Take a pointer to the callback installed as custom data
-fn borrow_callback_from_watcher<H, W: Watcher + NativeHandle<*H>,
-                                CB: Callback>(watcher: &W) -> &CB {
-
-    unsafe {
-        let handle = watcher.native_handle();
-        let handle_data: *c_void = uvll::get_data_for_uv_handle(handle);
-        fail_unless!(handle_data.is_not_null());
-        let cb = transmute::<&*c_void, &~CB>(&handle_data);
-        return &**cb;
-    }
-}
-
-/// Take ownership of the callback installed as custom data
-fn take_callback_from_watcher<H, W: Watcher + NativeHandle<*H>, CB: Callback>(
-    watcher: &mut W) -> CB {
-
-    unsafe {
-        let handle = watcher.native_handle();
-        let handle_data: *c_void = uvll::get_data_for_uv_handle(handle);
-        fail_unless!(handle_data.is_not_null());
-        uvll::set_data_for_uv_handle(handle, null::<()>());
-        let cb: ~CB = transmute::<*c_void, ~CB>(handle_data);
-        let cb = match cb { ~cb => cb };
-        return cb;
-    }
-}
-
-/// Callbacks used by StreamWatchers, set as custom data on the foreign handle
-struct WatcherData {
-    read_cb: Option<ReadCallback>,
-    write_cb: Option<ConnectionCallback>,
-    connect_cb: Option<ConnectionCallback>,
-    close_cb: Option<NullCallback>,
-    alloc_cb: Option<AllocCallback>
-}
-
-fn install_watcher_data<H, W: Watcher + NativeHandle<*H>>(watcher: &mut W) {
-    unsafe {
-        let data = ~WatcherData {
-            read_cb: None,
-            write_cb: None,
-            connect_cb: None,
-            close_cb: None,
-            alloc_cb: None
-        };
-        let data = transmute::<~WatcherData, *c_void>(data);
-        uvll::set_data_for_uv_handle(watcher.native_handle(), data);
-    }
-}
-
-fn get_watcher_data<H, W: Watcher + NativeHandle<*H>>(
-    watcher: &r/mut W) -> &r/mut WatcherData {
-
-    unsafe {
-        let data = uvll::get_data_for_uv_handle(watcher.native_handle());
-        let data = transmute::<&*c_void, &mut ~WatcherData>(&data);
-        return &mut **data;
-    }
-}
-
-fn drop_watcher_data<H, W: Watcher + NativeHandle<*H>>(watcher: &mut W) {
-    unsafe {
-        let data = uvll::get_data_for_uv_handle(watcher.native_handle());
-        let _data = transmute::<*c_void, ~WatcherData>(data);
-        uvll::set_data_for_uv_handle(watcher.native_handle(), null::<()>());
-    }
-}
-
-#[test]
-fn test_slice_to_uv_buf() {
-    let slice = [0, .. 20];
-    let buf = slice_to_uv_buf(slice);
-
-    fail_unless!(buf.len == 20);
-
-    unsafe {
-        let base = transmute::<*u8, *mut u8>(buf.base);
-        (*base) = 1;
-        (*ptr::mut_offset(base, 1)) = 2;
-    }
-
-    fail_unless!(slice[0] == 1);
-    fail_unless!(slice[1] == 2);
-}
-
-/// The uv buffer type
-pub type Buf = uvll::uv_buf_t;
-
-/// Borrow a slice to a Buf
-pub fn slice_to_uv_buf(v: &[u8]) -> Buf {
-    let data = unsafe { vec::raw::to_ptr(v) };
-    unsafe { uvll::buf_init(data, v.len()) }
-}
-
-// XXX: Do these conversions without copying
-
-/// Transmute an owned vector to a Buf
-fn vec_to_uv_buf(v: ~[u8]) -> Buf {
-    let data = unsafe { malloc(v.len() as size_t) } as *u8;
-    fail_unless!(data.is_not_null());
-    do vec::as_imm_buf(v) |b, l| {
-        let data = data as *mut u8;
-        unsafe { ptr::copy_memory(data, b, l) }
-    }
-    let buf = unsafe { uvll::buf_init(data, v.len()) };
-    return buf;
-}
-
-/// Transmute a Buf that was once a ~[u8] back to ~[u8]
-fn vec_from_uv_buf(buf: Buf) -> Option<~[u8]> {
-    if !(buf.len == 0 && buf.base.is_null()) {
-        let v = unsafe { vec::from_buf(buf.base, buf.len as uint) };
-        unsafe { free(buf.base as *c_void) };
-        return Some(v);
-    } else {
-        // No buffer
-        return None;
-    }
-}
-
-#[test]
-fn loop_smoke_test() {
-    do run_in_bare_thread {
-        let mut loop_ = Loop::new();
-        loop_.run();
-        loop_.close();
-    }
-}
-
-#[test]
-#[ignore(reason = "valgrind - loop destroyed before watcher?")]
-fn idle_new_then_close() {
-    do run_in_bare_thread {
-        let mut loop_ = Loop::new();
-        let mut idle_watcher = { IdleWatcher::new(&mut loop_) };
-        idle_watcher.close();
-    }
-}
-
-#[test]
-fn idle_smoke_test() {
-    do run_in_bare_thread {
-        let mut loop_ = Loop::new();
-        let mut idle_watcher = { IdleWatcher::new(&mut loop_) };
-        let mut count = 10;
-        let count_ptr: *mut int = &mut count;
-        do idle_watcher.start |idle_watcher, status| {
-            let mut idle_watcher = idle_watcher;
-            fail_unless!(status.is_none());
-            if unsafe { *count_ptr == 10 } {
-                idle_watcher.stop();
-                idle_watcher.close();
-            } else {
-                unsafe { *count_ptr = *count_ptr + 1; }
-            }
-        }
-        loop_.run();
-        loop_.close();
-        fail_unless!(count == 10);
-    }
-}
-
-#[test]
-fn idle_start_stop_start() {
-    do run_in_bare_thread {
-        let mut loop_ = Loop::new();
-        let mut idle_watcher = { IdleWatcher::new(&mut loop_) };
-        do idle_watcher.start |idle_watcher, status| {
-            let mut idle_watcher = idle_watcher;
-            fail_unless!(status.is_none());
-            idle_watcher.stop();
-            do idle_watcher.start |idle_watcher, status| {
-                fail_unless!(status.is_none());
-                let mut idle_watcher = idle_watcher;
-                idle_watcher.stop();
-                idle_watcher.close();
-            }
-        }
-        loop_.run();
-        loop_.close();
-    }
-}
 
 #[test]
 #[ignore(reason = "ffi struct issues")]
diff --git a/src/libcore/rt/uvll.rs b/src/libcore/rt/uvll.rs
index 3606c9f4dd6..a91e37d92e4 100644
--- a/src/libcore/rt/uvll.rs
+++ b/src/libcore/rt/uvll.rs
@@ -53,6 +53,7 @@ pub type uv_write_t = c_void;
 pub type uv_async_t = c_void;
 pub type uv_timer_t = c_void;
 pub type uv_stream_t = c_void;
+pub type uv_fs_t = c_void;
 
 pub type uv_idle_cb = *u8;
 

From 044703435ba7e1338456f7a83393eb2c6fecf238 Mon Sep 17 00:00:00 2001
From: Brian Anderson <banderson@mozilla.com>
Date: Fri, 15 Mar 2013 18:06:19 -0700
Subject: [PATCH 11/12] Add a way to run the test suite with the new scheduler

TESTARGS=--newrt make check-stage1-rpass

Conflicts:
	src/rt/rustrt.def.in
---
 src/compiletest/common.rs      |  3 +++
 src/compiletest/compiletest.rc |  5 ++++-
 src/compiletest/runtest.rs     | 10 +++++++++-
 src/libcore/rt/mod.rs          | 31 +++++++++++++++++++++++++++++++
 src/libcore/unstable/lang.rs   | 19 ++++++++++++++-----
 src/rt/rust.cpp                | 15 ---------------
 src/rt/rust_builtin.cpp        | 31 +++++++++++++++++++++++++++++++
 src/rt/rustrt.def.in           |  3 +++
 8 files changed, 95 insertions(+), 22 deletions(-)

diff --git a/src/compiletest/common.rs b/src/compiletest/common.rs
index b7c4e26c4b1..36691380e17 100644
--- a/src/compiletest/common.rs
+++ b/src/compiletest/common.rs
@@ -63,6 +63,9 @@ pub struct config {
     // Run tests using the JIT
     jit: bool,
 
+    // Run tests using the new runtime
+    newrt: bool,
+
     // Explain what's going on
     verbose: bool
 
diff --git a/src/compiletest/compiletest.rc b/src/compiletest/compiletest.rc
index 7d53b29e040..0c1f328ad09 100644
--- a/src/compiletest/compiletest.rc
+++ b/src/compiletest/compiletest.rc
@@ -61,7 +61,8 @@ pub fn parse_config(args: ~[~str]) -> config {
           getopts::optopt(~"runtool"), getopts::optopt(~"rustcflags"),
           getopts::optflag(~"verbose"),
           getopts::optopt(~"logfile"),
-          getopts::optflag(~"jit")];
+          getopts::optflag(~"jit"),
+          getopts::optflag(~"newrt")];
 
     fail_unless!(!args.is_empty());
     let args_ = vec::tail(args);
@@ -95,6 +96,7 @@ pub fn parse_config(args: ~[~str]) -> config {
         runtool: getopts::opt_maybe_str(matches, ~"runtool"),
         rustcflags: getopts::opt_maybe_str(matches, ~"rustcflags"),
         jit: getopts::opt_present(matches, ~"jit"),
+        newrt: getopts::opt_present(matches, ~"newrt"),
         verbose: getopts::opt_present(matches, ~"verbose")
     }
 }
@@ -114,6 +116,7 @@ pub fn log_config(config: config) {
     logv(c, fmt!("runtool: %s", opt_str(config.runtool)));
     logv(c, fmt!("rustcflags: %s", opt_str(config.rustcflags)));
     logv(c, fmt!("jit: %b", config.jit));
+    logv(c, fmt!("newrt: %b", config.newrt));
     logv(c, fmt!("verbose: %b", config.verbose));
     logv(c, fmt!("\n"));
 }
diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs
index 03f3fa9fcf6..736aa4eebf0 100644
--- a/src/compiletest/runtest.rs
+++ b/src/compiletest/runtest.rs
@@ -483,9 +483,17 @@ fn compile_test_(config: config, props: TestProps,
 
 fn exec_compiled_test(config: config, props: TestProps,
                       testfile: &Path) -> ProcRes {
+
+    // If testing the new runtime then set the RUST_NEWRT env var
+    let env = if config.newrt {
+        props.exec_env + ~[(~"RUST_NEWRT", ~"1")]
+    } else {
+        props.exec_env
+    };
+
     compose_and_run(config, testfile,
                     make_run_args(config, props, testfile),
-                    props.exec_env,
+                    env,
                     config.run_lib_path, None)
 }
 
diff --git a/src/libcore/rt/mod.rs b/src/libcore/rt/mod.rs
index 1e919af4d14..f900747c996 100644
--- a/src/libcore/rt/mod.rs
+++ b/src/libcore/rt/mod.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use libc::c_char;
 
 // Some basic logging
 macro_rules! rtdebug_ (
@@ -44,3 +45,33 @@ mod stack;
 mod context;
 mod thread;
 pub mod env;
+
+pub fn initialize() {
+    unsafe { rust_initialize_global_state(); }
+    extern {
+        fn rust_initialize_global_state();
+    }
+}
+
+pub fn start(main: *u8, _argc: int, _argv: *c_char, _crate_map: *u8) -> int {
+    use self::sched::{Scheduler, Task};
+    use self::uvio::UvEventLoop;
+
+    // XXX: Would rather do this lazily in Scheduler
+    initialize();
+
+    let loop_ = ~UvEventLoop::new();
+    let mut sched = ~Scheduler::new(loop_);
+    let main_task = ~do Task::new(&mut sched.stack_pool) {
+        // XXX: Can't call a C function pointer from Rust yet
+        unsafe { rust_call_nullary_fn(main) };
+    };
+    sched.task_queue.push_back(main_task);
+    sched.run();
+    return 0;
+
+    extern {
+        fn rust_call_nullary_fn(f: *u8);
+    }
+}
+
diff --git a/src/libcore/unstable/lang.rs b/src/libcore/unstable/lang.rs
index db0b1cc33cd..855c6b250ec 100644
--- a/src/libcore/unstable/lang.rs
+++ b/src/libcore/unstable/lang.rs
@@ -120,16 +120,25 @@ pub unsafe fn strdup_uniq(ptr: *c_uchar, len: uint) -> ~str {
 #[lang="start"]
 pub fn start(main: *u8, argc: int, argv: *c_char,
              crate_map: *u8) -> int {
+    use libc::getenv;
+    use rt::start;
+
+    unsafe {
+        let use_new_rt = do str::as_c_str("RUST_NEWRT") |s| {
+            getenv(s).is_null()
+        };
+        if use_new_rt {
+            return rust_start(main as *c_void, argc as c_int, argv,
+                              crate_map as *c_void) as int;
+        } else {
+            return start(main, argc, argv, crate_map);
+        }
+    }
 
     extern {
         fn rust_start(main: *c_void, argc: c_int, argv: *c_char,
                       crate_map: *c_void) -> c_int;
     }
-
-    unsafe {
-        return rust_start(main as *c_void, argc as c_int, argv,
-                          crate_map as *c_void) as int;
-    }
 }
 
 // Local Variables:
diff --git a/src/rt/rust.cpp b/src/rt/rust.cpp
index d9ef6a52dbe..803da32cbc8 100644
--- a/src/rt/rust.cpp
+++ b/src/rt/rust.cpp
@@ -21,17 +21,6 @@
 
 void* global_crate_map = NULL;
 
-#ifndef _WIN32
-pthread_key_t sched_key;
-#else
-DWORD sched_key;
-#endif
-
-extern "C" void*
-rust_get_sched_tls_key() {
-    return &sched_key;
-}
-
 /**
    The runtime entrypoint. The (C ABI) main function generated by rustc calls
    `rust_start`, providing the address of the Rust ABI main function, the
@@ -41,10 +30,6 @@ rust_get_sched_tls_key() {
 extern "C" CDECL int
 rust_start(uintptr_t main_fn, int argc, char **argv, void* crate_map) {
 
-#ifndef _WIN32
-    pthread_key_create(&sched_key, NULL);
-#endif
-
     // Load runtime configuration options from the environment.
     // FIXME #1497: Should provide a way to get these from the command
     // line as well.
diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp
index a2053c115bb..9349db17d56 100644
--- a/src/rt/rust_builtin.cpp
+++ b/src/rt/rust_builtin.cpp
@@ -882,6 +882,37 @@ rust_get_rt_env() {
     return task->kernel->env;
 }
 
+typedef void *(*nullary_fn)();
+
+extern "C" CDECL void
+rust_call_nullary_fn(nullary_fn f) {
+    f();
+}
+
+
+#ifndef _WIN32
+pthread_key_t sched_key;
+#else
+DWORD sched_key;
+#endif
+
+extern "C" void*
+rust_get_sched_tls_key() {
+    return &sched_key;
+}
+
+extern "C" CDECL void
+rust_initialize_global_state() {
+
+#ifndef _WIN32
+    assert(!pthread_key_create(&sched_key, NULL));
+#else
+    sched_key = TlsAlloc();
+    assert(sched_key != TLS_OUT_OF_INDEXES);
+#endif
+
+}
+
 //
 // Local Variables:
 // mode: C++
diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in
index 4fde952ba95..59fd8991622 100644
--- a/src/rt/rustrt.def.in
+++ b/src/rt/rustrt.def.in
@@ -210,4 +210,7 @@ rust_uv_ip4_addrp
 rust_uv_ip6_addrp
 rust_uv_free_ip4_addr
 rust_uv_free_ip6_addr
+rust_call_nullary_fn
+rust_initialize_global_state
+
 

From 5af5766512b0e90a3a076a09b35286aca332e48e Mon Sep 17 00:00:00 2001
From: Brian Anderson <banderson@mozilla.com>
Date: Fri, 15 Mar 2013 18:35:33 -0700
Subject: [PATCH 12/12] core: Initialize global state lazily in the Scheduler
 ctor

I don't want any global one-time initalization functions because
that will make embedding harder.
---
 src/libcore/rt/mod.rs   | 10 ----------
 src/libcore/rt/sched.rs |  7 +++++++
 src/rt/rust_builtin.cpp | 17 +++++++++++++----
 3 files changed, 20 insertions(+), 14 deletions(-)

diff --git a/src/libcore/rt/mod.rs b/src/libcore/rt/mod.rs
index f900747c996..04891a1673c 100644
--- a/src/libcore/rt/mod.rs
+++ b/src/libcore/rt/mod.rs
@@ -46,20 +46,10 @@ mod context;
 mod thread;
 pub mod env;
 
-pub fn initialize() {
-    unsafe { rust_initialize_global_state(); }
-    extern {
-        fn rust_initialize_global_state();
-    }
-}
-
 pub fn start(main: *u8, _argc: int, _argv: *c_char, _crate_map: *u8) -> int {
     use self::sched::{Scheduler, Task};
     use self::uvio::UvEventLoop;
 
-    // XXX: Would rather do this lazily in Scheduler
-    initialize();
-
     let loop_ = ~UvEventLoop::new();
     let mut sched = ~Scheduler::new(loop_);
     let main_task = ~do Task::new(&mut sched.stack_pool) {
diff --git a/src/libcore/rt/sched.rs b/src/libcore/rt/sched.rs
index f47f86fd5fd..312c6655f55 100644
--- a/src/libcore/rt/sched.rs
+++ b/src/libcore/rt/sched.rs
@@ -71,6 +71,13 @@ enum CleanupJob {
 pub impl Scheduler {
 
     static fn new(event_loop: ~EventLoopObject) -> Scheduler {
+
+        // Lazily initialize the global state, currently the scheduler TLS key
+        unsafe { rust_initialize_global_state(); }
+        extern {
+            fn rust_initialize_global_state();
+        }
+
         Scheduler {
             event_loop: event_loop,
             task_queue: WorkQueue::new(),
diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp
index 9349db17d56..f586e05772b 100644
--- a/src/rt/rust_builtin.cpp
+++ b/src/rt/rust_builtin.cpp
@@ -889,7 +889,6 @@ rust_call_nullary_fn(nullary_fn f) {
     f();
 }
 
-
 #ifndef _WIN32
 pthread_key_t sched_key;
 #else
@@ -901,16 +900,26 @@ rust_get_sched_tls_key() {
     return &sched_key;
 }
 
+// Initialize the global state required by the new scheduler
 extern "C" CDECL void
 rust_initialize_global_state() {
 
+    static lock_and_signal init_lock;
+    static bool initialized = false;
+
+    scoped_lock with(init_lock);
+
+    if (!initialized) {
+
 #ifndef _WIN32
-    assert(!pthread_key_create(&sched_key, NULL));
+        assert(!pthread_key_create(&sched_key, NULL));
 #else
-    sched_key = TlsAlloc();
-    assert(sched_key != TLS_OUT_OF_INDEXES);
+        sched_key = TlsAlloc();
+        assert(sched_key != TLS_OUT_OF_INDEXES);
 #endif
 
+        initialized = true;
+    }
 }
 
 //