rustc: Implement conversions from interior vector data to unsafe pointers and vice-versa
This commit is contained in:
@@ -12,6 +12,8 @@ native "rust-intrinsic" mod rusti {
|
|||||||
native "rust" mod rustrt {
|
native "rust" mod rustrt {
|
||||||
fn ivec_reserve[T](&mutable T[] v, uint n);
|
fn ivec_reserve[T](&mutable T[] v, uint n);
|
||||||
fn ivec_on_heap[T](&T[] v) -> bool;
|
fn ivec_on_heap[T](&T[] v) -> bool;
|
||||||
|
fn ivec_to_ptr[T](&T[] v) -> *T;
|
||||||
|
fn ivec_copy_from_buf[T](&mutable T[] v, *T ptr, uint count);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reserves space for `n` elements in the given vector.
|
/// Reserves space for `n` elements in the given vector.
|
||||||
@@ -23,3 +25,17 @@ fn on_heap[T](&T[] v) -> bool {
|
|||||||
ret rustrt::ivec_on_heap(v);
|
ret rustrt::ivec_on_heap(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn to_ptr[T](&T[] v) -> *T {
|
||||||
|
ret rustrt::ivec_to_ptr(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn len[T](&T[] v) -> uint {
|
||||||
|
ret rusti::ivec_len(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
mod unsafe {
|
||||||
|
fn copy_from_buf[T](&mutable T[] v, *T ptr, uint count) {
|
||||||
|
ret rustrt::ivec_copy_from_buf(v, ptr, count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -616,6 +616,43 @@ ivec_on_heap(rust_task *task, type_desc *ty, rust_ivec *v)
|
|||||||
return !v->fill && v->payload.ptr;
|
return !v->fill && v->payload.ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an unsafe pointer to the data part of an interior vector.
|
||||||
|
*/
|
||||||
|
extern "C" void *
|
||||||
|
ivec_to_ptr(rust_task *task, type_desc *ty, rust_ivec *v)
|
||||||
|
{
|
||||||
|
return v->fill ? v->payload.data : v->payload.ptr->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies elements in an unsafe buffer to the given interior vector. The
|
||||||
|
* vector must have size zero.
|
||||||
|
*/
|
||||||
|
extern "C" void
|
||||||
|
ivec_copy_from_buf(rust_task *task, type_desc *ty, rust_ivec *v, void *ptr,
|
||||||
|
size_t count)
|
||||||
|
{
|
||||||
|
if (v->fill || (v->payload.ptr && v->payload.ptr->fill)) {
|
||||||
|
task->fail(1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ivec_reserve(task, ty, v, count);
|
||||||
|
|
||||||
|
size_t new_size = count * ty->size;
|
||||||
|
if (v->fill) {
|
||||||
|
// On stack.
|
||||||
|
memmove(v->payload.data, ptr, new_size);
|
||||||
|
v->fill = new_size;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// On heap.
|
||||||
|
memmove(v->payload.ptr->data, ptr, new_size);
|
||||||
|
v->payload.ptr->fill = new_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Local Variables:
|
// Local Variables:
|
||||||
|
|||||||
@@ -9,8 +9,10 @@ debug_trap
|
|||||||
debug_tydesc
|
debug_tydesc
|
||||||
do_gc
|
do_gc
|
||||||
get_time
|
get_time
|
||||||
|
ivec_copy_from_buf
|
||||||
ivec_on_heap
|
ivec_on_heap
|
||||||
ivec_reserve
|
ivec_reserve
|
||||||
|
ivec_to_ptr
|
||||||
last_os_error
|
last_os_error
|
||||||
rand_free
|
rand_free
|
||||||
rand_new
|
rand_new
|
||||||
|
|||||||
@@ -10,7 +10,32 @@ fn test_reserve_and_on_heap() {
|
|||||||
assert (ivec::on_heap(v));
|
assert (ivec::on_heap(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn test_unsafe_ptrs() {
|
||||||
test_reserve_and_on_heap();
|
// Test on-stack copy-from-buf.
|
||||||
|
auto a = ~[ 1, 2, 3 ];
|
||||||
|
auto ptr = ivec::to_ptr(a);
|
||||||
|
auto b = ~[];
|
||||||
|
ivec::unsafe::copy_from_buf(b, ptr, 3u);
|
||||||
|
assert (ivec::len(b) == 3u);
|
||||||
|
assert (b.(0) == 1);
|
||||||
|
assert (b.(1) == 2);
|
||||||
|
assert (b.(2) == 3);
|
||||||
|
|
||||||
|
// Test on-heap copy-from-buf.
|
||||||
|
auto c = ~[ 1, 2, 3, 4, 5 ];
|
||||||
|
ptr = ivec::to_ptr(c);
|
||||||
|
auto d = ~[];
|
||||||
|
ivec::unsafe::copy_from_buf(d, ptr, 5u);
|
||||||
|
assert (ivec::len(d) == 5u);
|
||||||
|
assert (d.(0) == 1);
|
||||||
|
assert (d.(1) == 2);
|
||||||
|
assert (d.(2) == 3);
|
||||||
|
assert (d.(3) == 4);
|
||||||
|
assert (d.(4) == 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
test_reserve_and_on_heap();
|
||||||
|
test_unsafe_ptrs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user