diff options
| author | Eric Holk <eric.holk@gmail.com> | 2012-07-23 13:50:12 -0700 |
|---|---|---|
| committer | Eric Holk <eric.holk@gmail.com> | 2012-07-25 12:12:25 -0700 |
| commit | c28af2625870b2117e73fc8bee83a1704cff7414 (patch) | |
| tree | 527e545ec40d478f69943a745d220f465190078c /src | |
| parent | 88877effa8661d20e285aa82a4a5015a4a4c871c (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.rs | 22 | ||||
| -rw-r--r-- | src/libsyntax/ext/pipes/liveness.rs | 3 | ||||
| -rw-r--r-- | src/libsyntax/ext/pipes/proto.rs | 46 | ||||
| -rw-r--r-- | src/test/run-pass/pipe-pingpong-bounded.rs | 10 |
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; |
