Skip to content

Commit fd7c202

Browse files
committed
---
yaml --- r: 3183 b: refs/heads/master c: 40746fa h: refs/heads/master i: 3181: b720b82 3179: 679a5d1 3175: be3e04d 3167: 00683a1 v: v3
1 parent 9d01fa8 commit fd7c202

File tree

5 files changed

+81
-1
lines changed

5 files changed

+81
-1
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: e50c918e6b35c853813480b5c65c35813ceb6aa1
2+
refs/heads/master: 40746fa447b78a27b649db41a6bfe63f6645d5eb

trunk/src/lib/ivec.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ native "rust-intrinsic" mod rusti {
1212
native "rust" mod rustrt {
1313
fn ivec_reserve[T](&mutable T[] v, uint n);
1414
fn ivec_on_heap[T](&T[] v) -> bool;
15+
fn ivec_to_ptr[T](&T[] v) -> *T;
16+
fn ivec_copy_from_buf[T](&mutable T[] v, *T ptr, uint count);
1517
}
1618

1719
/// Reserves space for `n` elements in the given vector.
@@ -23,3 +25,17 @@ fn on_heap[T](&T[] v) -> bool {
2325
ret rustrt::ivec_on_heap(v);
2426
}
2527

28+
fn to_ptr[T](&T[] v) -> *T {
29+
ret rustrt::ivec_to_ptr(v);
30+
}
31+
32+
fn len[T](&T[] v) -> uint {
33+
ret rusti::ivec_len(v);
34+
}
35+
36+
mod unsafe {
37+
fn copy_from_buf[T](&mutable T[] v, *T ptr, uint count) {
38+
ret rustrt::ivec_copy_from_buf(v, ptr, count);
39+
}
40+
}
41+

trunk/src/rt/rust_builtin.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,43 @@ ivec_on_heap(rust_task *task, type_desc *ty, rust_ivec *v)
616616
return !v->fill && v->payload.ptr;
617617
}
618618

619+
/**
620+
* Returns an unsafe pointer to the data part of an interior vector.
621+
*/
622+
extern "C" void *
623+
ivec_to_ptr(rust_task *task, type_desc *ty, rust_ivec *v)
624+
{
625+
return v->fill ? v->payload.data : v->payload.ptr->data;
626+
}
627+
628+
/**
629+
* Copies elements in an unsafe buffer to the given interior vector. The
630+
* vector must have size zero.
631+
*/
632+
extern "C" void
633+
ivec_copy_from_buf(rust_task *task, type_desc *ty, rust_ivec *v, void *ptr,
634+
size_t count)
635+
{
636+
if (v->fill || (v->payload.ptr && v->payload.ptr->fill)) {
637+
task->fail(1);
638+
return;
639+
}
640+
641+
ivec_reserve(task, ty, v, count);
642+
643+
size_t new_size = count * ty->size;
644+
if (v->fill) {
645+
// On stack.
646+
memmove(v->payload.data, ptr, new_size);
647+
v->fill = new_size;
648+
return;
649+
}
650+
651+
// On heap.
652+
memmove(v->payload.ptr->data, ptr, new_size);
653+
v->payload.ptr->fill = new_size;
654+
}
655+
619656

620657
//
621658
// Local Variables:

trunk/src/rt/rustrt.def.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ debug_trap
99
debug_tydesc
1010
do_gc
1111
get_time
12+
ivec_copy_from_buf
1213
ivec_on_heap
1314
ivec_reserve
15+
ivec_to_ptr
1416
last_os_error
1517
rand_free
1618
rand_new

trunk/src/test/run-pass/lib-ivec.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,32 @@ fn test_reserve_and_on_heap() {
1010
assert (ivec::on_heap(v));
1111
}
1212

13+
fn test_unsafe_ptrs() {
14+
// Test on-stack copy-from-buf.
15+
auto a = ~[ 1, 2, 3 ];
16+
auto ptr = ivec::to_ptr(a);
17+
auto b = ~[];
18+
ivec::unsafe::copy_from_buf(b, ptr, 3u);
19+
assert (ivec::len(b) == 3u);
20+
assert (b.(0) == 1);
21+
assert (b.(1) == 2);
22+
assert (b.(2) == 3);
23+
24+
// Test on-heap copy-from-buf.
25+
auto c = ~[ 1, 2, 3, 4, 5 ];
26+
ptr = ivec::to_ptr(c);
27+
auto d = ~[];
28+
ivec::unsafe::copy_from_buf(d, ptr, 5u);
29+
assert (ivec::len(d) == 5u);
30+
assert (d.(0) == 1);
31+
assert (d.(1) == 2);
32+
assert (d.(2) == 3);
33+
assert (d.(3) == 4);
34+
assert (d.(4) == 5);
35+
}
36+
1337
fn main() {
1438
test_reserve_and_on_heap();
39+
test_unsafe_ptrs();
1540
}
1641

0 commit comments

Comments
 (0)