Skip to content

Commit

Permalink
Replace most uses of intrinsics in core with builtins
Browse files Browse the repository at this point in the history
Issue #1981
  • Loading branch information
marijnh committed Mar 23, 2012
1 parent b2aace2 commit 894b746
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 85 deletions.
47 changes: 17 additions & 30 deletions src/libcore/comm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Expand All @@ -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
Expand Down
22 changes: 15 additions & 7 deletions src/libcore/ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
Expand Down Expand Up @@ -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 = "
Expand All @@ -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]
Expand Down
16 changes: 7 additions & 9 deletions src/libcore/sys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 = "
Expand All @@ -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"]
Expand All @@ -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"]
Expand Down
15 changes: 5 additions & 10 deletions src/libcore/unsafe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,18 @@

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 = "
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 ="
Expand All @@ -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 {
Expand Down
29 changes: 0 additions & 29 deletions src/test/run-pass/interior-vec.rs

This file was deleted.

0 comments on commit 894b746

Please sign in to comment.