]> git.lizzy.rs Git - rust.git/commitdiff
Refactor the bounded pingpong example to avoid needing to generate unsafe code.
authorEric Holk <eric.holk@gmail.com>
Mon, 23 Jul 2012 20:50:12 +0000 (13:50 -0700)
committerEric Holk <eric.holk@gmail.com>
Wed, 25 Jul 2012 19:12:25 +0000 (12:12 -0700)
Took some steps towards bounded codegen.

src/libcore/pipes.rs
src/libsyntax/ext/pipes/liveness.rs
src/libsyntax/ext/pipes/proto.rs
src/test/run-pass/pipe-pingpong-bounded.rs

index 3bb2467f3df4cc66f905b8bccc3f5dadde8db84d..82b2d31a0be6072a06a6d073b8c1ac9602c224eb 100644 (file)
@@ -8,7 +8,7 @@
 // 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 @@ fn set_buffer<T: send>(b: ~buffer<T>) unsafe {
     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;
index 4f80399252021b1287bf76d6c7996518d6200927..d8467e36c84e2b9e7579deaa0d2816c0eac3b0b9 100644 (file)
@@ -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
index e9070c79b558ffdbee52b1190712ddb4ab543569..8a535e85188872621e0aa250a62a71049a40103e 100644 (file)
@@ -98,23 +98,23 @@ fn reachable(f: fn(state) -> bool) {
     }
 }
 
-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 @@ fn has_state(name: ident) -> bool {
         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 @@ fn add_state_poly(name: ident, dir: direction,
         self.states.push(state);
         state
     }
-
-    fn filename() -> ~str {
-        ~"proto://" + *self.name
-    }
-
-    fn num_states() -> uint { self.states.len() }
 }
 
 trait visitor<Tproto, Tstate, Tmessage> {
index bad605b8929e3bfbafa960de8455bf8c217285ce..c8b0dc3006a70bfb25844926cb5e1d838973dc16 100644 (file)
@@ -22,13 +22,11 @@ fn init() -> (client::ping, server::ping) {
                 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;