about summary refs log tree commit diff
path: root/src/lib
diff options
context:
space:
mode:
authorJoshua Wise <joshua@joshuawise.com>2011-11-23 05:15:04 -0500
committerNiko Matsakis <niko@alum.mit.edu>2011-11-28 10:41:45 -0800
commitc2eb084b4c273682b06fcaf285399ec9bf6fd0cb (patch)
tree465149197b7152119fc09556d9866aa7c1ca1c69 /src/lib
parent9aa6e5750ef31d5ccc2c7edd184aaa3f7372ea00 (diff)
downloadrust-c2eb084b4c273682b06fcaf285399ec9bf6fd0cb.tar.gz
rust-c2eb084b4c273682b06fcaf285399ec9bf6fd0cb.zip
Add c_vec library to std.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/c_vec.rs98
-rw-r--r--src/lib/std.rc3
2 files changed, 100 insertions, 1 deletions
diff --git a/src/lib/c_vec.rs b/src/lib/c_vec.rs
new file mode 100644
index 00000000000..3b94c54f373
--- /dev/null
+++ b/src/lib/c_vec.rs
@@ -0,0 +1,98 @@
+/*
+Module: c_vec
+
+Library to interface with chunks of memory allocated in C.
+
+It is often desirable to safely interface with memory allocated from C,
+encapsulating the unsafety into allocation and destruction time.  Indeed,
+allocating memory externally is currently the only way to give Rust shared
+mutable state with C programs that keep their own references; vectors are
+unsuitable because they could be reallocated or moved at any time, and
+importing C memory into a vector takes a one-time snapshot of the memory.
+
+This module simplifies the usage of such external blocks of memory.  Memory
+is encapsulated into an opaque object after creation; the lifecycle of the
+memory can be optionally managed by Rust, if an appropriate destructor
+closure is provided.  Safety is ensured by bounds-checking accesses, which
+are marshalled through get and set functions.
+
+There are three unsafe functions: the two introduction forms, and the
+pointer elimination form.  The introduction forms are unsafe for the obvious
+reason (they act on a pointer that cannot be checked inside the method), but
+the elimination form is somewhat more subtle in its unsafety.  By using a
+pointer taken from a c_vec::t without keeping a reference to the c_vec::t
+itself around, the c_vec could be garbage collected, and the memory within
+could be destroyed.  There are legitimate uses for the pointer elimination
+form -- for instance, to pass memory back into C -- but great care must be
+taken to ensure that a reference to the c_vec::t is still held if needed.
+
+ */
+
+export t;
+export create, create_with_dtor;
+export get, set;
+export size;
+export ptr;
+
+/*
+ Type: t
+
+ The type representing a native chunk of memory.  Wrapped in a tag for
+ opacity; FIXME #818 when it is possible to have truly opaque types, this
+ should be revisited.
+ */
+
+tag t<T> {
+    t({ base: *T, size: uint, rsrc: @dtor_res});
+}
+
+resource dtor_res(dtor: option::t<fn@()>) {
+    alt dtor {
+      option::none. { }
+      option::some(f) { f(); }
+    }
+}
+
+/*
+ Section: Introduction forms
+ */
+
+unsafe fn create<T>(base: *T, size: uint) -> t<T> {
+    ret t({base: base,
+           size: size,
+           rsrc: @dtor_res(option::none)
+          });
+}
+
+unsafe fn create_with_dtor<T>(base: *T, size: uint, dtor: fn@()) -> t<T> {
+    ret t({base: base,
+           size: size,
+           rsrc: @dtor_res(option::some(dtor))
+          });
+}
+
+/*
+ Section: Operations
+ */
+
+fn get<copy T>(t: t<T>, ofs: uint) -> T {
+    assert ofs < (*t).size;
+    ret unsafe { *ptr::offset((*t).base, ofs) };
+}
+
+fn set<copy T>(t: t<T>, ofs: uint, v: T) {
+    assert ofs < (*t).size;
+    unsafe { *(ptr::offset((*t).base, ofs) as *mutable T) = v };
+}
+
+/*
+ Section: Elimination forms
+ */
+
+fn size<T>(t: t<T>) -> uint {
+    ret (*t).size;
+}
+
+unsafe fn ptr<T>(t: t<T>) -> *T {
+    ret (*t).base;
+}
diff --git a/src/lib/std.rc b/src/lib/std.rc
index 342e3fe394d..555828f79c3 100644
--- a/src/lib/std.rc
+++ b/src/lib/std.rc
@@ -10,7 +10,7 @@
 export box, char, float, int, str, ptr;
 export uint, u8, u32, u64, vec, bool;
 export comm, fs, io, net, run, sys, task;
-export ctypes, either, option, result, four, tri, util;
+export c_vec, ctypes, either, option, result, four, tri, util;
 export bitv, deque, fun_treemap, list, map, smallintmap, sort, treemap, ufind;
 export rope;
 export math, math_f32, math_f64;
@@ -50,6 +50,7 @@ mod task;
 
 // Utility modules
 
+mod c_vec;
 mod ctypes;
 mod cmath; /* unexported */
 mod either;