Skip to content

Commit

Permalink
made leak an intrinsic to avoid a c-call. added memmove and memcpy in…
Browse files Browse the repository at this point in the history
…trinsics
  • Loading branch information
Magnus Auvinen authored and brson committed Feb 7, 2012
1 parent a63780a commit 3e98593
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 5 deletions.
26 changes: 26 additions & 0 deletions src/libcore/ptr.rs
Expand Up @@ -7,6 +7,8 @@ Unsafe pointer utility functions
native mod rusti {
fn addr_of<T>(val: T) -> *T;
fn ptr_offset<T>(ptr: *T, count: ctypes::uintptr_t) -> *T;
fn memcpy<T>(dst: *T, src: *T, count: ctypes::uintptr_t);
fn memmove<T>(dst: *T, src: *T, count: ctypes::uintptr_t);
}

/*
Expand Down Expand Up @@ -51,6 +53,20 @@ Create an unsafe null pointer
*/
fn null<T>() -> *T unsafe { ret unsafe::reinterpret_cast(0u); }

/*
Function: memcpy
Copies data from one src to dst that is not overlapping each other.
*/
fn memcpy<T>(dst: *T, src: *T, count: uint) unsafe { rusti::memcpy(dst, src, count); }

/*
Function: memmove
Copies data from one src to dst, overlap between the two pointers may occur.
*/
fn memmove<T>(dst: *T, src: *T, count: uint) unsafe { rusti::memcpy(dst, src, count); }

#[test]
fn test() unsafe {
type pair = {mutable fst: int, mutable snd: int};
Expand All @@ -66,4 +82,14 @@ fn test() unsafe {
assert (*iptr == 50);
assert (p.fst == 50);
assert (p.snd == 60);

let v0 = [32000u16, 32001u16, 32002u16];
let v1 = [0u16, 0u16, 0u16];

ptr::memcpy(ptr::offset(vec::unsafe::to_ptr(v1), 1u), ptr::offset(vec::unsafe::to_ptr(v0), 1u), 1u);
assert (v1[0] == 0u16 && v1[1] == 32001u16 && v1[2] == 0u16);
ptr::memcpy(vec::unsafe::to_ptr(v1), ptr::offset(vec::unsafe::to_ptr(v0), 2u), 1u);
assert (v1[0] == 32002u16 && v1[1] == 32001u16 && v1[2] == 0u16);
ptr::memcpy(ptr::offset(vec::unsafe::to_ptr(v1), 2u), vec::unsafe::to_ptr(v0), 1u);
assert (v1[0] == 32002u16 && v1[1] == 32001u16 && v1[2] == 32000u16);
}
6 changes: 1 addition & 5 deletions src/libcore/unsafe.rs
Expand Up @@ -9,10 +9,6 @@ export reinterpret_cast, leak;
#[abi = "rust-intrinsic"]
native mod rusti {
fn cast<T, U>(src: T) -> U;
}

#[abi = "cdecl"]
native mod rustrt {
fn leak<T>(-thing: T);
}

Expand Down Expand Up @@ -40,7 +36,7 @@ to run any required cleanup or memory-management operations on it. This
can be used for various acts of magick, particularly when using
reinterpret_cast on managed pointer types.
*/
unsafe fn leak<T>(-thing: T) { rustrt::leak(thing); }
unsafe fn leak<T>(-thing: T) { rusti::leak(thing); }

#[cfg(test)]
mod tests {
Expand Down
29 changes: 29 additions & 0 deletions src/rt/intrinsics/intrinsics.cpp
Expand Up @@ -83,3 +83,32 @@ rust_intrinsic_task_yield(void **retptr,
rust_task_yield(task, killed);
}

extern "C" void
rust_intrinsic_memmove(void *retptr,
void *env,
type_desc *ty,
void *dst,
void *src,
uintptr_t count)
{
memmove(dst, src, ty->size * count);
}

extern "C" void
rust_intrinsic_memcpy(void *retptr,
void *env,
type_desc *ty,
void *dst,
void *src,
uintptr_t count)
{
memcpy(dst, src, ty->size * count);
}

extern "C" void
rust_intrinsic_leak(void *retptr,
void *env,
type_desc *ty,
void *thing)
{
}
22 changes: 22 additions & 0 deletions src/rt/intrinsics/intrinsics.i386.ll.in
Expand Up @@ -120,6 +120,28 @@ entry:

declare void @rust_task_yield(%struct.rust_task*, i8*)

define void @rust_intrinsic_memmove(i8* nocapture %retptr, i8* nocapture %env, %struct.type_desc* nocapture %ty, i8* nocapture %dst, i8* nocapture %src, i32 %count) nounwind {
%1 = getelementptr inbounds %struct.type_desc* %ty, i32 0, i32 1
%2 = load i32* %1, align 4, !tbaa !3
%3 = mul i32 %2, %count
tail call void @llvm.memmove.p0i8.p0i8.i32(i8* %dst, i8* %src, i32 %3, i32 1, i1 false)
ret void
}

define void @rust_intrinsic_memcpy(i8* nocapture %retptr, i8* nocapture %env, %struct.type_desc* nocapture %ty, i8* nocapture %dst, i8* nocapture %src, i32 %count) nounwind {
%1 = getelementptr inbounds %struct.type_desc* %ty, i32 0, i32 1
%2 = load i32* %1, align 4, !tbaa !3
%3 = mul i32 %2, %count
tail call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dst, i8* %src, i32 %3, i32 1, i1 false)
ret void
}

declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind

define void @rust_intrinsic_leak(i8* nocapture %retptr, i8* nocapture %env, %struct.type_desc* nocapture %ty, i8* nocapture %thing) nounwind readnone {
ret void
}

!0 = metadata !{metadata !"any pointer", metadata !1}
!1 = metadata !{metadata !"omnipotent char", metadata !2}
!2 = metadata !{metadata !"Simple C/C++ TBAA", null}
Expand Down
22 changes: 22 additions & 0 deletions src/rt/intrinsics/intrinsics.x86_64.ll.in
Expand Up @@ -120,6 +120,28 @@ entry:

declare void @rust_task_yield(%struct.rust_task*, i8*)

define void @rust_intrinsic_memmove(i8* nocapture %retptr, i8* nocapture %env, %struct.type_desc* nocapture %ty, i8* nocapture %dst, i8* nocapture %src, i64 %count) nounwind uwtable {
%1 = getelementptr inbounds %struct.type_desc* %ty, i64 0, i32 1
%2 = load i64* %1, align 8, !tbaa !3
%3 = mul i64 %2, %count
tail call void @llvm.memmove.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %3, i32 1, i1 false)
ret void
}

define void @rust_intrinsic_memcpy(i8* nocapture %retptr, i8* nocapture %env, %struct.type_desc* nocapture %ty, i8* nocapture %dst, i8* nocapture %src, i64 %count) nounwind uwtable {
%1 = getelementptr inbounds %struct.type_desc* %ty, i64 0, i32 1
%2 = load i64* %1, align 8, !tbaa !3
%3 = mul i64 %2, %count
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %3, i32 1, i1 false)
ret void
}

declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind

define void @rust_intrinsic_leak(i8* nocapture %retptr, i8* nocapture %env, %struct.type_desc* nocapture %ty, i8* nocapture %thing) nounwind uwtable readnone {
ret void
}

!0 = metadata !{metadata !"any pointer", metadata !1}
!1 = metadata !{metadata !"omnipotent char", metadata !2}
!2 = metadata !{metadata !"Simple C/C++ TBAA", null}
Expand Down

0 comments on commit 3e98593

Please sign in to comment.