Skip to content

Commit 3e98593

Browse files
Magnus Auvinenbrson
authored andcommitted
made leak an intrinsic to avoid a c-call. added memmove and memcpy intrinsics
1 parent a63780a commit 3e98593

File tree

5 files changed

+100
-5
lines changed

5 files changed

+100
-5
lines changed

src/libcore/ptr.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ Unsafe pointer utility functions
77
native mod rusti {
88
fn addr_of<T>(val: T) -> *T;
99
fn ptr_offset<T>(ptr: *T, count: ctypes::uintptr_t) -> *T;
10+
fn memcpy<T>(dst: *T, src: *T, count: ctypes::uintptr_t);
11+
fn memmove<T>(dst: *T, src: *T, count: ctypes::uintptr_t);
1012
}
1113

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

56+
/*
57+
Function: memcpy
58+
59+
Copies data from one src to dst that is not overlapping each other.
60+
*/
61+
fn memcpy<T>(dst: *T, src: *T, count: uint) unsafe { rusti::memcpy(dst, src, count); }
62+
63+
/*
64+
Function: memmove
65+
66+
Copies data from one src to dst, overlap between the two pointers may occur.
67+
*/
68+
fn memmove<T>(dst: *T, src: *T, count: uint) unsafe { rusti::memcpy(dst, src, count); }
69+
5470
#[test]
5571
fn test() unsafe {
5672
type pair = {mutable fst: int, mutable snd: int};
@@ -66,4 +82,14 @@ fn test() unsafe {
6682
assert (*iptr == 50);
6783
assert (p.fst == 50);
6884
assert (p.snd == 60);
85+
86+
let v0 = [32000u16, 32001u16, 32002u16];
87+
let v1 = [0u16, 0u16, 0u16];
88+
89+
ptr::memcpy(ptr::offset(vec::unsafe::to_ptr(v1), 1u), ptr::offset(vec::unsafe::to_ptr(v0), 1u), 1u);
90+
assert (v1[0] == 0u16 && v1[1] == 32001u16 && v1[2] == 0u16);
91+
ptr::memcpy(vec::unsafe::to_ptr(v1), ptr::offset(vec::unsafe::to_ptr(v0), 2u), 1u);
92+
assert (v1[0] == 32002u16 && v1[1] == 32001u16 && v1[2] == 0u16);
93+
ptr::memcpy(ptr::offset(vec::unsafe::to_ptr(v1), 2u), vec::unsafe::to_ptr(v0), 1u);
94+
assert (v1[0] == 32002u16 && v1[1] == 32001u16 && v1[2] == 32000u16);
6995
}

src/libcore/unsafe.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,6 @@ export reinterpret_cast, leak;
99
#[abi = "rust-intrinsic"]
1010
native mod rusti {
1111
fn cast<T, U>(src: T) -> U;
12-
}
13-
14-
#[abi = "cdecl"]
15-
native mod rustrt {
1612
fn leak<T>(-thing: T);
1713
}
1814

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

4541
#[cfg(test)]
4642
mod tests {

src/rt/intrinsics/intrinsics.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,3 +83,32 @@ rust_intrinsic_task_yield(void **retptr,
8383
rust_task_yield(task, killed);
8484
}
8585

86+
extern "C" void
87+
rust_intrinsic_memmove(void *retptr,
88+
void *env,
89+
type_desc *ty,
90+
void *dst,
91+
void *src,
92+
uintptr_t count)
93+
{
94+
memmove(dst, src, ty->size * count);
95+
}
96+
97+
extern "C" void
98+
rust_intrinsic_memcpy(void *retptr,
99+
void *env,
100+
type_desc *ty,
101+
void *dst,
102+
void *src,
103+
uintptr_t count)
104+
{
105+
memcpy(dst, src, ty->size * count);
106+
}
107+
108+
extern "C" void
109+
rust_intrinsic_leak(void *retptr,
110+
void *env,
111+
type_desc *ty,
112+
void *thing)
113+
{
114+
}

src/rt/intrinsics/intrinsics.i386.ll.in

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,28 @@ entry:
120120

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

123+
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 {
124+
%1 = getelementptr inbounds %struct.type_desc* %ty, i32 0, i32 1
125+
%2 = load i32* %1, align 4, !tbaa !3
126+
%3 = mul i32 %2, %count
127+
tail call void @llvm.memmove.p0i8.p0i8.i32(i8* %dst, i8* %src, i32 %3, i32 1, i1 false)
128+
ret void
129+
}
130+
131+
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 {
132+
%1 = getelementptr inbounds %struct.type_desc* %ty, i32 0, i32 1
133+
%2 = load i32* %1, align 4, !tbaa !3
134+
%3 = mul i32 %2, %count
135+
tail call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dst, i8* %src, i32 %3, i32 1, i1 false)
136+
ret void
137+
}
138+
139+
declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind
140+
141+
define void @rust_intrinsic_leak(i8* nocapture %retptr, i8* nocapture %env, %struct.type_desc* nocapture %ty, i8* nocapture %thing) nounwind readnone {
142+
ret void
143+
}
144+
123145
!0 = metadata !{metadata !"any pointer", metadata !1}
124146
!1 = metadata !{metadata !"omnipotent char", metadata !2}
125147
!2 = metadata !{metadata !"Simple C/C++ TBAA", null}

src/rt/intrinsics/intrinsics.x86_64.ll.in

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,28 @@ entry:
120120

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

123+
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 {
124+
%1 = getelementptr inbounds %struct.type_desc* %ty, i64 0, i32 1
125+
%2 = load i64* %1, align 8, !tbaa !3
126+
%3 = mul i64 %2, %count
127+
tail call void @llvm.memmove.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %3, i32 1, i1 false)
128+
ret void
129+
}
130+
131+
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 {
132+
%1 = getelementptr inbounds %struct.type_desc* %ty, i64 0, i32 1
133+
%2 = load i64* %1, align 8, !tbaa !3
134+
%3 = mul i64 %2, %count
135+
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %3, i32 1, i1 false)
136+
ret void
137+
}
138+
139+
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind
140+
141+
define void @rust_intrinsic_leak(i8* nocapture %retptr, i8* nocapture %env, %struct.type_desc* nocapture %ty, i8* nocapture %thing) nounwind uwtable readnone {
142+
ret void
143+
}
144+
123145
!0 = metadata !{metadata !"any pointer", metadata !1}
124146
!1 = metadata !{metadata !"omnipotent char", metadata !2}
125147
!2 = metadata !{metadata !"Simple C/C++ TBAA", null}

0 commit comments

Comments
 (0)