mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
parent
b2aace2cca
commit
894b7469d6
@ -55,9 +55,9 @@ native mod rustrt {
|
||||
yield: *libc::uintptr_t);
|
||||
}
|
||||
|
||||
#[abi = "rust-intrinsic"]
|
||||
#[abi = "rust-builtin"]
|
||||
native mod rusti {
|
||||
fn call_with_retptr<T: send>(&&f: fn(*uint)) -> T;
|
||||
fn init<T>() -> T;
|
||||
}
|
||||
|
||||
type port_id = int;
|
||||
@ -137,18 +137,13 @@ fn recv<T: send>(p: port<T>) -> T { recv_(***p) }
|
||||
|
||||
#[doc = "Receive on a raw port pointer"]
|
||||
fn recv_<T: send>(p: *rust_port) -> T {
|
||||
// FIXME: Due to issue 1185 we can't use a return pointer when
|
||||
// calling C code, and since we can't create our own return
|
||||
// pointer on the stack, we're going to call a little intrinsic
|
||||
// that will grab the value of the return pointer, then call this
|
||||
// function, which we will then use to call the runtime.
|
||||
fn recv(dptr: *uint, port: *rust_port,
|
||||
yield: *libc::uintptr_t) unsafe {
|
||||
rustrt::port_recv(dptr, port, yield);
|
||||
}
|
||||
let yield = 0u;
|
||||
let yieldp = ptr::addr_of(yield);
|
||||
let res = rusti::call_with_retptr(bind recv(_, p, yieldp));
|
||||
let mut res;
|
||||
res = rusti::init::<T>();
|
||||
log(debug, ptr::addr_of(res));
|
||||
rustrt::port_recv(ptr::addr_of(res) as *uint, p, yieldp);
|
||||
|
||||
if yield != 0u {
|
||||
// Data isn't available yet, so res has not been initialized.
|
||||
task::yield();
|
||||
@ -161,26 +156,18 @@ fn recv_<T: send>(p: *rust_port) -> T {
|
||||
}
|
||||
|
||||
#[doc = "Receive on one of two ports"]
|
||||
fn select2<A: send, B: send>(
|
||||
p_a: port<A>, p_b: port<B>
|
||||
) -> either<A, B> unsafe {
|
||||
|
||||
fn select(dptr: **rust_port, ports: **rust_port,
|
||||
n_ports: libc::size_t, yield: *libc::uintptr_t) {
|
||||
rustrt::rust_port_select(dptr, ports, n_ports, yield)
|
||||
}
|
||||
|
||||
let mut ports = [];
|
||||
ports += [***p_a, ***p_b];
|
||||
fn select2<A: send, B: send>(p_a: port<A>, p_b: port<B>)
|
||||
-> either<A, B> unsafe {
|
||||
let ports = [***p_a, ***p_b];
|
||||
let n_ports = 2 as libc::size_t;
|
||||
let yield = 0u;
|
||||
let yieldp = ptr::addr_of(yield);
|
||||
let yield = 0u, yieldp = ptr::addr_of(yield);
|
||||
|
||||
let resport: *rust_port = vec::as_buf(ports) {|ports|
|
||||
rusti::call_with_retptr {|retptr|
|
||||
select(unsafe::reinterpret_cast(retptr), ports, n_ports, yieldp)
|
||||
}
|
||||
};
|
||||
let mut resport: *rust_port;
|
||||
resport = rusti::init::<*rust_port>();
|
||||
vec::as_buf(ports) {|ports|
|
||||
rustrt::rust_port_select(ptr::addr_of(resport), ports, n_ports,
|
||||
yieldp);
|
||||
}
|
||||
|
||||
if yield != 0u {
|
||||
// Wait for data
|
||||
|
@ -8,22 +8,28 @@ export null;
|
||||
export memcpy;
|
||||
export memmove;
|
||||
|
||||
import libc::c_void;
|
||||
|
||||
#[abi = "rust-intrinsic"]
|
||||
#[nolink]
|
||||
#[abi = "cdecl"]
|
||||
native mod libc_ {
|
||||
fn memcpy(dest: *c_void, src: *c_void, n: libc::size_t) -> *c_void;
|
||||
fn memmove(dest: *c_void, src: *c_void, n: libc::size_t) -> *c_void;
|
||||
}
|
||||
|
||||
#[abi = "rust-builtin"]
|
||||
native mod rusti {
|
||||
fn addr_of<T>(val: T) -> *T;
|
||||
fn memcpy<T>(dst: *T, src: *T, count: libc::uintptr_t);
|
||||
fn memmove<T>(dst: *T, src: *T, count: libc::uintptr_t);
|
||||
}
|
||||
|
||||
#[doc = "Get an unsafe pointer to a value"]
|
||||
#[inline(always)]
|
||||
fn addr_of<T>(val: T) -> *T { ret rusti::addr_of(val); }
|
||||
fn addr_of<T>(val: T) -> *T { rusti::addr_of(val) }
|
||||
|
||||
#[doc = "Get an unsafe mutable pointer to a value"]
|
||||
#[inline(always)]
|
||||
fn mut_addr_of<T>(val: T) -> *mutable T unsafe {
|
||||
ret unsafe::reinterpret_cast(rusti::addr_of(val));
|
||||
unsafe::reinterpret_cast(rusti::addr_of(val))
|
||||
}
|
||||
|
||||
#[doc = "Calculate the offset from a pointer"]
|
||||
@ -51,7 +57,8 @@ and destination may not overlap.
|
||||
"]
|
||||
#[inline(always)]
|
||||
unsafe fn memcpy<T>(dst: *T, src: *T, count: uint) {
|
||||
rusti::memcpy(dst, src, count);
|
||||
let n = count * sys::size_of::<T>();
|
||||
libc_::memcpy(dst as *c_void, src as *c_void, n);
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
@ -62,7 +69,8 @@ and destination may overlap.
|
||||
"]
|
||||
#[inline(always)]
|
||||
unsafe fn memmove<T>(dst: *T, src: *T, count: uint) {
|
||||
rusti::memmove(dst, src, count);
|
||||
let n = count * sys::size_of::<T>();
|
||||
libc_::memmove(dst as *c_void, src as *c_void, n);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -28,13 +28,11 @@ native mod rustrt {
|
||||
fn rust_set_exit_status(code: libc::intptr_t);
|
||||
}
|
||||
|
||||
#[abi = "rust-intrinsic"]
|
||||
#[abi = "rust-builtin"]
|
||||
native mod rusti {
|
||||
fn get_type_desc<T>() -> *type_desc;
|
||||
|
||||
// Invokes __builtin_frame_address().
|
||||
// See <http://gcc.gnu.org/onlinedocs/gcc/Return-Address.html>.
|
||||
fn frame_address(n: libc::c_uint) -> libc::uintptr_t;
|
||||
fn get_tydesc<T>() -> *();
|
||||
fn size_of<T>() -> uint;
|
||||
fn align_of<T>() -> uint;
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
@ -44,7 +42,7 @@ Useful for calling certain function in the Rust runtime or otherwise
|
||||
performing dark magick.
|
||||
"]
|
||||
fn get_type_desc<T>() -> *type_desc {
|
||||
ret rusti::get_type_desc::<T>();
|
||||
rusti::get_tydesc::<T>() as *type_desc
|
||||
}
|
||||
|
||||
#[doc = "Get a string representing the platform-dependent last error"]
|
||||
@ -54,12 +52,12 @@ fn last_os_error() -> str {
|
||||
|
||||
#[doc = "Returns the size of a type"]
|
||||
fn size_of<T>() -> uint unsafe {
|
||||
ret (*get_type_desc::<T>()).size;
|
||||
rusti::size_of::<T>()
|
||||
}
|
||||
|
||||
#[doc = "Returns the alignment of a type"]
|
||||
fn align_of<T>() -> uint unsafe {
|
||||
ret (*get_type_desc::<T>()).align;
|
||||
rusti::align_of::<T>()
|
||||
}
|
||||
|
||||
#[doc = "Returns the refcount of a shared box"]
|
||||
|
@ -2,10 +2,10 @@
|
||||
|
||||
export reinterpret_cast, forget;
|
||||
|
||||
#[abi = "rust-intrinsic"]
|
||||
#[abi = "rust-builtin"]
|
||||
native mod rusti {
|
||||
fn cast<T, U>(src: T) -> U;
|
||||
fn leak<T>(-thing: T);
|
||||
fn forget<T>(-x: T);
|
||||
fn reinterpret_cast<T, U>(e: T) -> U;
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
@ -13,12 +13,7 @@ Casts the value at `src` to U. The two types must have the same length.
|
||||
"]
|
||||
#[inline(always)]
|
||||
unsafe fn reinterpret_cast<T, U>(src: T) -> U {
|
||||
let t1 = sys::get_type_desc::<T>();
|
||||
let t2 = sys::get_type_desc::<U>();
|
||||
if (*t1).size != (*t2).size {
|
||||
fail "attempt to cast values of differing sizes";
|
||||
}
|
||||
ret rusti::cast(src);
|
||||
rusti::reinterpret_cast(src)
|
||||
}
|
||||
|
||||
#[doc ="
|
||||
@ -30,7 +25,7 @@ can be used for various acts of magick, particularly when using
|
||||
reinterpret_cast on managed pointer types.
|
||||
"]
|
||||
#[inline(always)]
|
||||
unsafe fn forget<T>(-thing: T) { rusti::leak(thing); }
|
||||
unsafe fn forget<T>(-thing: T) { rusti::forget(thing); }
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
@ -1,29 +0,0 @@
|
||||
import rusti::vec_len;
|
||||
|
||||
#[abi = "rust-intrinsic"]
|
||||
native mod rusti {
|
||||
fn vec_len<T>(&&v: [T]) -> uint;
|
||||
}
|
||||
|
||||
fn main() unsafe {
|
||||
let mut v: [int] = [];
|
||||
assert (vec_len(v) == 0u); // zero-length
|
||||
let mut x = [1, 2];
|
||||
assert (vec_len(x) == 2u); // on stack
|
||||
let mut y = [1, 2, 3, 4, 5];
|
||||
assert (vec_len(y) == 5u); // on heap
|
||||
|
||||
v += [];
|
||||
assert (vec_len(v) == 0u); // zero-length append
|
||||
x += [3];
|
||||
assert (vec_len(x) == 3u); // on-stack append
|
||||
y += [6, 7, 8, 9];
|
||||
assert (vec_len(y) == 9u); // on-heap append
|
||||
|
||||
let vv = v + v;
|
||||
assert (vec_len(vv) == 0u); // zero-length add
|
||||
let xx = x + [4];
|
||||
assert (vec_len(xx) == 4u); // on-stack add
|
||||
let yy = y + [10, 11];
|
||||
assert (vec_len(yy) == 11u); // on-heap add
|
||||
}
|
Loading…
Reference in New Issue
Block a user