Replace most uses of intrinsics in core with builtins

Issue #1981
This commit is contained in:
Marijn Haverbeke 2012-03-22 12:30:10 +01:00
parent b2aace2cca
commit 894b7469d6
5 changed files with 44 additions and 85 deletions

View File

@ -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

View File

@ -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]

View File

@ -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"]

View File

@ -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 {

View File

@ -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
}