about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorEric Holk <eric.holk@gmail.com>2012-07-23 13:50:12 -0700
committerEric Holk <eric.holk@gmail.com>2012-07-25 12:12:25 -0700
commitc28af2625870b2117e73fc8bee83a1704cff7414 (patch)
tree527e545ec40d478f69943a745d220f465190078c /src
parent88877effa8661d20e285aa82a4a5015a4a4c871c (diff)
Refactor the bounded pingpong example to avoid needing to generate unsafe code.
Took some steps towards bounded codegen.
Diffstat (limited to 'src')
-rw-r--r--src/libcore/pipes.rs22
-rw-r--r--src/libsyntax/ext/pipes/liveness.rs3
-rw-r--r--src/libsyntax/ext/pipes/proto.rs46
-rw-r--r--src/test/run-pass/pipe-pingpong-bounded.rs10
4 files changed, 55 insertions, 26 deletions
diff --git a/src/libcore/pipes.rs b/src/libcore/pipes.rs
index 3bb2467f3df..82b2d31a0be 100644
--- a/src/libcore/pipes.rs
+++ b/src/libcore/pipes.rs
@@ -8,7 +8,7 @@ import arc::methods;
 // Things used by code generated by the pipe compiler.
 export entangle, get_buffer, drop_buffer;
 export send_packet_buffered, recv_packet_buffered;
-export mk_packet;
+export mk_packet, entangle_buffer, has_buffer;
 
 // export these so we can find them in the buffer_resource
 // destructor. This is probably another metadata bug.
@@ -151,6 +151,16 @@ type packet<T: send> = {
     mut payload: option<T>,
 };
 
+trait has_buffer {
+    fn set_buffer(b: *libc::c_void);
+}
+
+impl methods<T: send> of has_buffer for packet<T> {
+    fn set_buffer(b: *libc::c_void) {
+        self.header.buffer = b;
+    }
+}
+
 fn mk_packet<T: send>() -> packet<T> {
     {
         header: packet_header(),
@@ -182,6 +192,16 @@ fn packet<T: send>() -> *packet<T> {
     p
 }
 
+fn entangle_buffer<T: send, Tstart: send>(
+    -buffer: ~buffer<T>,
+    init: fn(*libc::c_void, x: &T) -> *packet<Tstart>)
+    -> (send_packet_buffered<Tstart, T>, recv_packet_buffered<Tstart, T>)
+{
+    let p = init(unsafe { reinterpret_cast(buffer) }, &buffer.data);
+    unsafe { forget(buffer) }
+    (send_packet_buffered(p), recv_packet_buffered(p))
+}
+
 #[abi = "rust-intrinsic"]
 extern mod rusti {
     fn atomic_xchng(&dst: int, src: int) -> int;
diff --git a/src/libsyntax/ext/pipes/liveness.rs b/src/libsyntax/ext/pipes/liveness.rs
index 4f803992520..d8467e36c84 100644
--- a/src/libsyntax/ext/pipes/liveness.rs
+++ b/src/libsyntax/ext/pipes/liveness.rs
@@ -84,8 +84,11 @@ fn analyze(proto: protocol, _cx: ext_ctxt) {
         //                    involving these states: %s",
         //                   *proto.name,
         //                   states));
+
+        proto.bounded = some(false);
     }
     else {
         #debug("protocol %s is bounded. yay!", *proto.name);
+        proto.bounded = some(true);
     }
 }
\ No newline at end of file
diff --git a/src/libsyntax/ext/pipes/proto.rs b/src/libsyntax/ext/pipes/proto.rs
index e9070c79b55..8a535e85188 100644
--- a/src/libsyntax/ext/pipes/proto.rs
+++ b/src/libsyntax/ext/pipes/proto.rs
@@ -98,23 +98,23 @@ impl methods for state {
     }
 }
 
-enum protocol {
-    protocol_(@{
-        name: ident,
-        states: dvec<state>,
-    }),
-}
+type protocol = @protocol_;
 
-fn protocol(name: ident) -> protocol {
-    protocol_(@{name: name, states: dvec()})
-}
+fn protocol(name: ident) -> protocol { @protocol_(name) }
 
-impl methods for protocol {
-    fn add_state(name: ident, dir: direction) -> state {
-        self.add_state_poly(name, dir, ~[])
+class protocol_ {
+    let name: ident;
+    let states: dvec<state>;
+
+    let mut bounded: option<bool>;
+
+    new(name: ident) {
+        self.name = name;
+        self.states = dvec();
+        self.bounded = none;
     }
 
-    /// Get or create a state.
+    /// Get a state.
     fn get_state(name: ident) -> state {
         self.states.find(|i| i.name == name).get()
     }
@@ -125,6 +125,20 @@ impl methods for protocol {
         self.states.find(|i| i.name == name) != none
     }
 
+    fn filename() -> ~str {
+        ~"proto://" + *self.name
+    }
+
+    fn num_states() -> uint { self.states.len() }
+
+    fn is_bounded() -> bool { self.bounded.get() }
+}
+
+impl methods for protocol {
+    fn add_state(name: ident, dir: direction) -> state {
+        self.add_state_poly(name, dir, ~[])
+    }
+
     fn add_state_poly(name: ident, dir: direction,
                       +ty_params: ~[ast::ty_param]) -> state {
         let messages = dvec();
@@ -141,12 +155,6 @@ impl methods for protocol {
         self.states.push(state);
         state
     }
-
-    fn filename() -> ~str {
-        ~"proto://" + *self.name
-    }
-
-    fn num_states() -> uint { self.states.len() }
 }
 
 trait visitor<Tproto, Tstate, Tmessage> {
diff --git a/src/test/run-pass/pipe-pingpong-bounded.rs b/src/test/run-pass/pipe-pingpong-bounded.rs
index bad605b8929..c8b0dc3006a 100644
--- a/src/test/run-pass/pipe-pingpong-bounded.rs
+++ b/src/test/run-pass/pipe-pingpong-bounded.rs
@@ -22,13 +22,11 @@ mod pingpong {
                 pong: mk_packet::<pong>()
             }
         };
-        unsafe {
-            buffer.data.ping.header.set_buffer(buffer);
-            buffer.data.pong.header.set_buffer(buffer);
+        do pipes::entangle_buffer(buffer) |buffer, data| {
+            data.ping.set_buffer(buffer);
+            data.pong.set_buffer(buffer);
+            ptr::addr_of(data.ping)
         }
-        let client = send_packet_buffered(ptr::addr_of(buffer.data.ping));
-        let server = recv_packet_buffered(ptr::addr_of(buffer.data.ping));
-        (client, server)
     }
     enum ping = server::pong;
     enum pong = client::ping;