diff options
| author | bors <bors@rust-lang.org> | 2013-05-08 17:09:37 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2013-05-08 17:09:37 -0700 |
| commit | d82d9874a6f88e0afa021796e9efaba5b3670c31 (patch) | |
| tree | 4270207820c8eca6e33cf2bbf9f1bbcafe9d74a9 /src/libcore | |
| parent | 5a65f51d666855d7685850808cc06e49c3d21c72 (diff) | |
| parent | d20e63ab65f7ba28db36ae43379706ca9dba1ca5 (diff) | |
| download | rust-d82d9874a6f88e0afa021796e9efaba5b3670c31.tar.gz rust-d82d9874a6f88e0afa021796e9efaba5b3670c31.zip | |
auto merge of #6232 : pcwalton/rust/demuting, r=pcwalton
They're still parsed for bootstrapping purposes, but the qualifier is immediately dropped on the floor. r? @nikomatsakis
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/at_vec.rs | 8 | ||||
| -rw-r--r-- | src/libcore/cast.rs | 2 | ||||
| -rw-r--r-- | src/libcore/comm.rs | 234 | ||||
| -rw-r--r-- | src/libcore/flate.rs | 5 | ||||
| -rw-r--r-- | src/libcore/hash.rs | 214 | ||||
| -rw-r--r-- | src/libcore/hashmap.rs | 2 | ||||
| -rw-r--r-- | src/libcore/io.rs | 111 | ||||
| -rw-r--r-- | src/libcore/os.rs | 7 | ||||
| -rw-r--r-- | src/libcore/pipes.rs | 324 | ||||
| -rw-r--r-- | src/libcore/ptr.rs | 5 | ||||
| -rw-r--r-- | src/libcore/rand.rs | 220 | ||||
| -rw-r--r-- | src/libcore/rand/distributions.rs | 12 | ||||
| -rw-r--r-- | src/libcore/repr.rs | 59 | ||||
| -rw-r--r-- | src/libcore/rt/local_services.rs | 4 | ||||
| -rw-r--r-- | src/libcore/rt/uvll.rs | 26 | ||||
| -rw-r--r-- | src/libcore/stackwalk.rs | 2 | ||||
| -rw-r--r-- | src/libcore/task/mod.rs | 279 | ||||
| -rw-r--r-- | src/libcore/task/spawn.rs | 112 | ||||
| -rw-r--r-- | src/libcore/unstable.rs | 21 | ||||
| -rw-r--r-- | src/libcore/unstable/at_exit.rs | 7 | ||||
| -rw-r--r-- | src/libcore/unstable/intrinsics.rs | 4 | ||||
| -rw-r--r-- | src/libcore/unstable/weak_task.rs | 12 | ||||
| -rw-r--r-- | src/libcore/vec.rs | 12 |
23 files changed, 929 insertions, 753 deletions
diff --git a/src/libcore/at_vec.rs b/src/libcore/at_vec.rs index 9f59f1d8fe4..75dfe1e7806 100644 --- a/src/libcore/at_vec.rs +++ b/src/libcore/at_vec.rs @@ -29,9 +29,9 @@ pub mod rustrt { #[abi = "cdecl"] #[link_name = "rustrt"] pub extern { - pub unsafe fn vec_reserve_shared_actual(++t: *sys::TypeDesc, - ++v: **vec::raw::VecRepr, - ++n: libc::size_t); + pub unsafe fn vec_reserve_shared_actual(t: *sys::TypeDesc, + v: **vec::raw::VecRepr, + n: libc::size_t); } } @@ -60,7 +60,7 @@ pub fn capacity<T>(v: @[T]) -> uint { pub fn build_sized<A>(size: uint, builder: &fn(push: &fn(v: A))) -> @[A] { let mut vec: @[A] = @[]; unsafe { raw::reserve(&mut vec, size); } - builder(|+x| unsafe { raw::push(&mut vec, x) }); + builder(|x| unsafe { raw::push(&mut vec, x) }); return unsafe { transmute(vec) }; } diff --git a/src/libcore/cast.rs b/src/libcore/cast.rs index 96e1c3bd124..9b93cf68622 100644 --- a/src/libcore/cast.rs +++ b/src/libcore/cast.rs @@ -17,7 +17,7 @@ pub mod rusti { #[abi = "rust-intrinsic"] #[link_name = "rusti"] pub extern "rust-intrinsic" { - fn forget<T>(+x: T); + fn forget<T>(x: T); fn transmute<T,U>(e: T) -> U; } diff --git a/src/libcore/comm.rs b/src/libcore/comm.rs index d075ff08bb7..7eaa8535493 100644 --- a/src/libcore/comm.rs +++ b/src/libcore/comm.rs @@ -12,6 +12,7 @@ Message passing */ +use cast::{transmute, transmute_mut}; use cast; use either::{Either, Left, Right}; use kinds::Owned; @@ -118,13 +119,15 @@ pub mod streamp { } /// An endpoint that can send many messages. +#[unsafe_mut_field(endp)] pub struct Chan<T> { - mut endp: Option<streamp::client::Open<T>> + endp: Option<streamp::client::Open<T>> } /// An endpoint that can receive many messages. +#[unsafe_mut_field(endp)] pub struct Port<T> { - mut endp: Option<streamp::server::Open<T>>, + endp: Option<streamp::server::Open<T>>, } /** Creates a `(Port, Chan)` pair. @@ -135,30 +138,39 @@ These allow sending or receiving an unlimited number of messages. pub fn stream<T:Owned>() -> (Port<T>, Chan<T>) { let (c, s) = streamp::init(); - (Port { endp: Some(s) }, Chan { endp: Some(c) }) + (Port { + endp: Some(s) + }, Chan { + endp: Some(c) + }) } impl<T: Owned> GenericChan<T> for Chan<T> { #[inline(always)] fn send(&self, x: T) { - let mut endp = None; - endp <-> self.endp; - self.endp = Some( - streamp::client::data(endp.unwrap(), x)) + unsafe { + let mut endp = None; + let mut self_endp = transmute_mut(&self.endp); + endp <-> *self_endp; + *self_endp = Some(streamp::client::data(endp.unwrap(), x)) + } } } impl<T: Owned> GenericSmartChan<T> for Chan<T> { #[inline(always)] fn try_send(&self, x: T) -> bool { - let mut endp = None; - endp <-> self.endp; - match streamp::client::try_data(endp.unwrap(), x) { - Some(next) => { - self.endp = Some(next); - true + unsafe { + let mut endp = None; + let mut self_endp = transmute_mut(&self.endp); + endp <-> *self_endp; + match streamp::client::try_data(endp.unwrap(), x) { + Some(next) => { + *self_endp = Some(next); + true + } + None => false } - None => false } } } @@ -166,23 +178,29 @@ impl<T: Owned> GenericSmartChan<T> for Chan<T> { impl<T: Owned> GenericPort<T> for Port<T> { #[inline(always)] fn recv(&self) -> T { - let mut endp = None; - endp <-> self.endp; - let streamp::data(x, endp) = recv(endp.unwrap()); - self.endp = Some(endp); - x + unsafe { + let mut endp = None; + let mut self_endp = transmute_mut(&self.endp); + endp <-> *self_endp; + let streamp::data(x, endp) = recv(endp.unwrap()); + *self_endp = Some(endp); + x + } } #[inline(always)] fn try_recv(&self) -> Option<T> { - let mut endp = None; - endp <-> self.endp; - match try_recv(endp.unwrap()) { - Some(streamp::data(x, endp)) => { - self.endp = Some(endp); - Some(x) + unsafe { + let mut endp = None; + let mut self_endp = transmute_mut(&self.endp); + endp <-> *self_endp; + match try_recv(endp.unwrap()) { + Some(streamp::data(x, endp)) => { + *self_endp = Some(endp); + Some(x) + } + None => None } - None => None } } } @@ -190,22 +208,25 @@ impl<T: Owned> GenericPort<T> for Port<T> { impl<T: Owned> Peekable<T> for Port<T> { #[inline(always)] fn peek(&self) -> bool { - let mut endp = None; - endp <-> self.endp; - let peek = match &endp { - &Some(ref endp) => peek(endp), - &None => fail!(~"peeking empty stream") - }; - self.endp <-> endp; - peek + unsafe { + let mut endp = None; + let mut self_endp = transmute_mut(&self.endp); + endp <-> *self_endp; + let peek = match endp { + Some(ref mut endp) => peek(endp), + None => fail!(~"peeking empty stream") + }; + *self_endp <-> endp; + peek + } } } impl<T: Owned> Selectable for Port<T> { - fn header(&self) -> *PacketHeader { + fn header(&mut self) -> *mut PacketHeader { unsafe { match self.endp { - Some(ref endp) => endp.header(), + Some(ref mut endp) => endp.header(), None => fail!(~"peeking empty stream") } } @@ -213,12 +234,12 @@ impl<T: Owned> Selectable for Port<T> { } /// Treat many ports as one. +#[unsafe_mut_field(ports)] pub struct PortSet<T> { - mut ports: ~[Port<T>], + ports: ~[Port<T>], } pub impl<T: Owned> PortSet<T> { - fn new() -> PortSet<T> { PortSet { ports: ~[] @@ -226,7 +247,10 @@ pub impl<T: Owned> PortSet<T> { } fn add(&self, port: Port<T>) { - self.ports.push(port) + unsafe { + let self_ports = transmute_mut(&self.ports); + self_ports.push(port) + } } fn chan(&self) -> Chan<T> { @@ -238,25 +262,28 @@ pub impl<T: Owned> PortSet<T> { impl<T:Owned> GenericPort<T> for PortSet<T> { fn try_recv(&self) -> Option<T> { - let mut result = None; - // we have to swap the ports array so we aren't borrowing - // aliasable mutable memory. - let mut ports = ~[]; - ports <-> self.ports; - while result.is_none() && ports.len() > 0 { - let i = wait_many(ports); - match ports[i].try_recv() { - Some(m) => { - result = Some(m); - } - None => { - // Remove this port. - let _ = ports.swap_remove(i); + unsafe { + let mut self_ports = transmute_mut(&self.ports); + let mut result = None; + // we have to swap the ports array so we aren't borrowing + // aliasable mutable memory. + let mut ports = ~[]; + ports <-> *self_ports; + while result.is_none() && ports.len() > 0 { + let i = wait_many(ports); + match ports[i].try_recv() { + Some(m) => { + result = Some(m); + } + None => { + // Remove this port. + let _ = ports.swap_remove(i); + } } } + ports <-> *self_ports; + result } - ports <-> self.ports; - result } fn recv(&self) -> T { self.try_recv().expect("port_set: endpoints closed") @@ -268,10 +295,9 @@ impl<T: Owned> Peekable<T> for PortSet<T> { // It'd be nice to use self.port.each, but that version isn't // pure. for uint::range(0, vec::uniq_len(&const self.ports)) |i| { - // XXX: Botch pending demuting. - unsafe { - let port: &Port<T> = cast::transmute(&mut self.ports[i]); - if port.peek() { return true } + let port: &Port<T> = &self.ports[i]; + if port.peek() { + return true; } } false @@ -327,23 +353,20 @@ impl<T: Owned> ::clone::Clone for SharedChan<T> { #[allow(non_camel_case_types)] pub mod oneshot { priv use core::kinds::Owned; - use ptr::to_unsafe_ptr; + use ptr::to_mut_unsafe_ptr; pub fn init<T: Owned>() -> (client::Oneshot<T>, server::Oneshot<T>) { pub use core::pipes::HasBuffer; - let buffer = - ~::core::pipes::Buffer{ + let mut buffer = ~::core::pipes::Buffer { header: ::core::pipes::BufferHeader(), - data: __Buffer{ + data: __Buffer { Oneshot: ::core::pipes::mk_packet::<Oneshot<T>>() }, }; do ::core::pipes::entangle_buffer(buffer) |buffer, data| { - { - data.Oneshot.set_buffer(buffer); - to_unsafe_ptr(&data.Oneshot) - } + data.Oneshot.set_buffer(buffer); + to_mut_unsafe_ptr(&mut data.Oneshot) } } #[allow(non_camel_case_types)] @@ -497,48 +520,66 @@ pub fn try_send_one<T: Owned>(chan: ChanOne<T>, data: T) -> bool { /// Returns the index of an endpoint that is ready to receive. -pub fn selecti<T: Selectable>(endpoints: &[T]) -> uint { +pub fn selecti<T: Selectable>(endpoints: &mut [T]) -> uint { wait_many(endpoints) } /// Returns 0 or 1 depending on which endpoint is ready to receive -pub fn select2i<A: Selectable, B: Selectable>(a: &A, b: &B) -> - Either<(), ()> { - match wait_many([a.header(), b.header()]) { - 0 => Left(()), - 1 => Right(()), - _ => fail!(~"wait returned unexpected index") +pub fn select2i<A:Selectable, B:Selectable>(a: &mut A, b: &mut B) + -> Either<(), ()> { + let mut endpoints = [ a.header(), b.header() ]; + match wait_many(endpoints) { + 0 => Left(()), + 1 => Right(()), + _ => fail!(~"wait returned unexpected index"), } } /// Receive a message from one of two endpoints. pub trait Select2<T: Owned, U: Owned> { /// Receive a message or return `None` if a connection closes. - fn try_select(&self) -> Either<Option<T>, Option<U>>; + fn try_select(&mut self) -> Either<Option<T>, Option<U>>; /// Receive a message or fail if a connection closes. - fn select(&self) -> Either<T, U>; + fn select(&mut self) -> Either<T, U>; } -impl<T: Owned, U: Owned, - Left: Selectable + GenericPort<T>, - Right: Selectable + GenericPort<U>> - Select2<T, U> for (Left, Right) { - - fn select(&self) -> Either<T, U> { - match *self { - (ref lp, ref rp) => match select2i(lp, rp) { - Left(()) => Left (lp.recv()), - Right(()) => Right(rp.recv()) - } +impl<T:Owned, + U:Owned, + Left:Selectable + GenericPort<T>, + Right:Selectable + GenericPort<U>> + Select2<T, U> + for (Left, Right) { + fn select(&mut self) -> Either<T, U> { + // XXX: Bad borrow check workaround. + unsafe { + let this: &(Left, Right) = transmute(self); + match *this { + (ref lp, ref rp) => { + let lp: &mut Left = transmute(lp); + let rp: &mut Right = transmute(rp); + match select2i(lp, rp) { + Left(()) => Left(lp.recv()), + Right(()) => Right(rp.recv()), + } + } + } } } - fn try_select(&self) -> Either<Option<T>, Option<U>> { - match *self { - (ref lp, ref rp) => match select2i(lp, rp) { - Left(()) => Left (lp.try_recv()), - Right(()) => Right(rp.try_recv()) - } + fn try_select(&mut self) -> Either<Option<T>, Option<U>> { + // XXX: Bad borrow check workaround. + unsafe { + let this: &(Left, Right) = transmute(self); + match *this { + (ref lp, ref rp) => { + let lp: &mut Left = transmute(lp); + let rp: &mut Right = transmute(rp); + match select2i(lp, rp) { + Left(()) => Left (lp.try_recv()), + Right(()) => Right(rp.try_recv()), + } + } + } } } } @@ -555,9 +596,10 @@ mod test { c1.send(~"abc"); - match (p1, p2).select() { - Right(_) => fail!(), - _ => () + let mut tuple = (p1, p2); + match tuple.select() { + Right(_) => fail!(), + _ => (), } c2.send(123); diff --git a/src/libcore/flate.rs b/src/libcore/flate.rs index ba10f97e626..29d0eb422d5 100644 --- a/src/libcore/flate.rs +++ b/src/libcore/flate.rs @@ -84,10 +84,11 @@ pub fn inflate_bytes(bytes: &const [u8]) -> ~[u8] { #[test] #[allow(non_implicitly_copyable_typarams)] fn test_flate_round_trip() { - let r = rand::rng(); + let mut r = rand::rng(); let mut words = ~[]; for 20.times { - words.push(r.gen_bytes(r.gen_uint_range(1, 10))); + let range = r.gen_uint_range(1, 10); + words.push(r.gen_bytes(range)); } for 20.times { let mut in = ~[]; diff --git a/src/libcore/hash.rs b/src/libcore/hash.rs index ba1f8cebdb0..d535abf8ead 100644 --- a/src/libcore/hash.rs +++ b/src/libcore/hash.rs @@ -19,12 +19,16 @@ * CPRNG like rand::rng. */ -use io; -use io::Writer; +#[cfg(stage0)] +use cast; +use rt::io::Writer; use to_bytes::IterBytes; use uint; use vec; +// Alias `SipState` to `State`. +pub use State = hash::SipState; + /** * Types that can meaningfully be hashed should implement this. * @@ -65,20 +69,32 @@ impl<A:Hash> HashUtil for A { /// Streaming hash-functions should implement this. pub trait Streaming { - fn input(&self, (&const [u8])); + fn input(&mut self, &[u8]); // These can be refactored some when we have default methods. - fn result_bytes(&self) -> ~[u8]; - fn result_str(&self) -> ~str; - fn result_u64(&self) -> u64; - fn reset(&self); + fn result_bytes(&mut self) -> ~[u8]; + fn result_str(&mut self) -> ~str; + fn result_u64(&mut self) -> u64; + fn reset(&mut self); +} + +// XXX: Ugly workaround for bootstrapping. +#[cfg(stage0)] +fn transmute_for_stage0<'a>(bytes: &'a [const u8]) -> &'a [u8] { + unsafe { + cast::transmute(bytes) + } +} +#[cfg(not(stage0))] +fn transmute_for_stage0<'a>(bytes: &'a [u8]) -> &'a [u8] { + bytes } impl<A:IterBytes> Hash for A { #[inline(always)] fn hash_keyed(&self, k0: u64, k1: u64) -> u64 { - let s = &State(k0, k1); + let mut s = State::new(k0, k1); for self.iter_bytes(true) |bytes| { - s.input(bytes); + s.input(transmute_for_stage0(bytes)); } s.result_u64() } @@ -86,32 +102,56 @@ impl<A:IterBytes> Hash for A { fn hash_keyed_2<A: IterBytes, B: IterBytes>(a: &A, b: &B, k0: u64, k1: u64) -> u64 { - let s = &State(k0, k1); - for a.iter_bytes(true) |bytes| { s.input(bytes); } - for b.iter_bytes(true) |bytes| { s.input(bytes); } + let mut s = State::new(k0, k1); + for a.iter_bytes(true) |bytes| { + s.input(transmute_for_stage0(bytes)); + } + for b.iter_bytes(true) |bytes| { + s.input(transmute_for_stage0(bytes)); + } s.result_u64() } fn hash_keyed_3<A: IterBytes, B: IterBytes, C: IterBytes>(a: &A, b: &B, c: &C, k0: u64, k1: u64) -> u64 { - let s = &State(k0, k1); - for a.iter_bytes(true) |bytes| { s.input(bytes); } - for b.iter_bytes(true) |bytes| { s.input(bytes); } - for c.iter_bytes(true) |bytes| { s.input(bytes); } + let mut s = State::new(k0, k1); + for a.iter_bytes(true) |bytes| { + s.input(transmute_for_stage0(bytes)); + } + for b.iter_bytes(true) |bytes| { + s.input(transmute_for_stage0(bytes)); + } + for c.iter_bytes(true) |bytes| { + s.input(transmute_for_stage0(bytes)); + } s.result_u64() } fn hash_keyed_4<A: IterBytes, B: IterBytes, C: IterBytes, - D: IterBytes>(a: &A, b: &B, c: &C, d: &D, k0: u64, k1: u64) - -> u64 { - let s = &State(k0, k1); - for a.iter_bytes(true) |bytes| { s.input(bytes); } - for b.iter_bytes(true) |bytes| { s.input(bytes); } - for c.iter_bytes(true) |bytes| { s.input(bytes); } - for d.iter_bytes(true) |bytes| { s.input(bytes); } + D: IterBytes>( + a: &A, + b: &B, + c: &C, + d: &D, + k0: u64, + k1: u64) + -> u64 { + let mut s = State::new(k0, k1); + for a.iter_bytes(true) |bytes| { + s.input(transmute_for_stage0(bytes)); + } + for b.iter_bytes(true) |bytes| { + s.input(transmute_for_stage0(bytes)); + } + for c.iter_bytes(true) |bytes| { + s.input(transmute_for_stage0(bytes)); + } + for d.iter_bytes(true) |bytes| { + s.input(transmute_for_stage0(bytes)); + } s.result_u64() } @@ -119,58 +159,68 @@ fn hash_keyed_5<A: IterBytes, B: IterBytes, C: IterBytes, D: IterBytes, - E: IterBytes>(a: &A, b: &B, c: &C, d: &D, e: &E, - k0: u64, k1: u64) -> u64 { - let s = &State(k0, k1); - for a.iter_bytes(true) |bytes| { s.input(bytes); } - for b.iter_bytes(true) |bytes| { s.input(bytes); } - for c.iter_bytes(true) |bytes| { s.input(bytes); } - for d.iter_bytes(true) |bytes| { s.input(bytes); } - for e.iter_bytes(true) |bytes| { s.input(bytes); } + E: IterBytes>( + a: &A, + b: &B, + c: &C, + d: &D, + e: &E, + k0: u64, + k1: u64) + -> u64 { + let mut s = State::new(k0, k1); + for a.iter_bytes(true) |bytes| { + s.input(transmute_for_stage0(bytes)); + } + for b.iter_bytes(true) |bytes| { + s.input(transmute_for_stage0(bytes)); + } + for c.iter_bytes(true) |bytes| { + s.input(transmute_for_stage0(bytes)); + } + for d.iter_bytes(true) |bytes| { + s.input(transmute_for_stage0(bytes)); + } + for e.iter_bytes(true) |bytes| { + s.input(transmute_for_stage0(bytes)); + } s.result_u64() } -// Implement State as SipState - -pub type State = SipState; - -#[inline(always)] -pub fn State(k0: u64, k1: u64) -> State { - SipState(k0, k1) -} - #[inline(always)] pub fn default_state() -> State { - State(0,0) + State::new(0, 0) } struct SipState { k0: u64, k1: u64, - mut length: uint, // how many bytes we've processed - mut v0: u64, // hash state - mut v1: u64, - mut v2: u64, - mut v3: u64, - mut tail: [u8, ..8], // unprocessed bytes - mut ntail: uint, // how many bytes in tail are valid + length: uint, // how many bytes we've processed + v0: u64, // hash state + v1: u64, + v2: u64, + v3: u64, + tail: [u8, ..8], // unprocessed bytes + ntail: uint, // how many bytes in tail are valid } -#[inline(always)] -fn SipState(key0: u64, key1: u64) -> SipState { - let state = SipState { - k0 : key0, - k1 : key1, - mut length : 0u, - mut v0 : 0u64, - mut v1 : 0u64, - mut v2 : 0u64, - mut v3 : 0u64, - mut tail : [0u8,0,0,0,0,0,0,0], - mut ntail : 0u, - }; - (&state).reset(); - state +impl SipState { + #[inline(always)] + fn new(key0: u64, key1: u64) -> SipState { + let mut state = SipState { + k0: key0, + k1: key1, + length: 0, + v0: 0, + v1: 0, + v2: 0, + v3: 0, + tail: [ 0, 0, 0, 0, 0, 0, 0, 0 ], + ntail: 0, + }; + state.reset(); + state + } } // sadly, these macro definitions can't appear later, @@ -207,12 +257,10 @@ macro_rules! compress ( ) -impl io::Writer for SipState { - +impl Writer for SipState { // Methods for io::writer #[inline(always)] - fn write(&self, msg: &const [u8]) { - + fn write(&mut self, msg: &[u8]) { let length = msg.len(); self.length += length; @@ -272,29 +320,19 @@ impl io::Writer for SipState { self.ntail = left; } - fn seek(&self, _x: int, _s: io::SeekStyle) { - fail!(); - } - fn tell(&self) -> uint { - self.length - } - fn flush(&self) -> int { - 0 - } - fn get_type(&self) -> io::WriterType { - io::File + fn flush(&mut self) { + // No-op } } impl Streaming for SipState { - #[inline(always)] - fn input(&self, buf: &const [u8]) { + fn input(&mut self, buf: &[u8]) { self.write(buf); } #[inline(always)] - fn result_u64(&self) -> u64 { + fn result_u64(&mut self) -> u64 { let mut v0 = self.v0; let mut v1 = self.v1; let mut v2 = self.v2; @@ -324,7 +362,7 @@ impl Streaming for SipState { return (v0 ^ v1 ^ v2 ^ v3); } - fn result_bytes(&self) -> ~[u8] { + fn result_bytes(&mut self) -> ~[u8] { let h = self.result_u64(); ~[(h >> 0) as u8, (h >> 8) as u8, @@ -337,7 +375,7 @@ impl Streaming for SipState { ] } - fn result_str(&self) -> ~str { + fn result_str(&mut self) -> ~str { let r = self.result_bytes(); let mut s = ~""; for vec::each(r) |b| { @@ -347,7 +385,7 @@ impl Streaming for SipState { } #[inline(always)] - fn reset(&self) { + fn reset(&mut self) { self.length = 0; self.v0 = self.k0 ^ 0x736f6d6570736575; self.v1 = self.k1 ^ 0x646f72616e646f6d; @@ -435,10 +473,10 @@ mod tests { let k1 = 0x_0f_0e_0d_0c_0b_0a_09_08_u64; let mut buf : ~[u8] = ~[]; let mut t = 0; - let stream_inc = &State(k0,k1); - let stream_full = &State(k0,k1); + let mut stream_inc = SipState::new(k0, k1); + let mut stream_full = SipState::new(k0, k1); - fn to_hex_str(r: &[u8, ..8]) -> ~str { + fn to_hex_str(r: &[u8, ..8]) -> ~str { let mut s = ~""; for vec::each(*r) |b| { s += uint::to_str_radix(*b as uint, 16u); @@ -529,4 +567,4 @@ mod tests { val & !(0xff << (byte * 8)) } } -} \ No newline at end of file +} diff --git a/src/libcore/hashmap.rs b/src/libcore/hashmap.rs index b764fccf64c..8e0a185248e 100644 --- a/src/libcore/hashmap.rs +++ b/src/libcore/hashmap.rs @@ -56,7 +56,7 @@ fn resize_at(capacity: uint) -> uint { pub fn linear_map_with_capacity<K:Eq + Hash,V>( initial_capacity: uint) -> HashMap<K, V> { - let r = rand::task_rng(); + let mut r = rand::task_rng(); linear_map_with_capacity_and_keys(r.gen(), r.gen(), initial_capacity) } diff --git a/src/libcore/io.rs b/src/libcore/io.rs index 64b69a7928b..1bb754fc2be 100644 --- a/src/libcore/io.rs +++ b/src/libcore/io.rs @@ -983,36 +983,50 @@ pub fn file_reader(path: &Path) -> Result<@Reader, ~str> { // Byte readers pub struct BytesReader<'self> { bytes: &'self [u8], - mut pos: uint + pos: @mut uint } impl<'self> Reader for BytesReader<'self> { fn read(&self, bytes: &mut [u8], len: uint) -> uint { - let count = uint::min(len, self.bytes.len() - self.pos); + let count = uint::min(len, self.bytes.len() - *self.pos); - let view = vec::slice(self.bytes, self.pos, self.bytes.len()); + let view = vec::slice(self.bytes, *self.pos, self.bytes.len()); vec::bytes::copy_memory(bytes, view, count); - self.pos += count; + *self.pos += count; count } + fn read_byte(&self) -> int { - if self.pos == self.bytes.len() { return -1; } - let b = self.bytes[self.pos]; - self.pos += 1u; - return b as int; + if *self.pos == self.bytes.len() { + return -1; + } + + let b = self.bytes[*self.pos]; + *self.pos += 1u; + b as int + } + + fn eof(&self) -> bool { + *self.pos == self.bytes.len() } - fn eof(&self) -> bool { self.pos == self.bytes.len() } + fn seek(&self, offset: int, whence: SeekStyle) { - let pos = self.pos; - self.pos = seek_in_buf(offset, pos, self.bytes.len(), whence); + let pos = *self.pos; + *self.pos = seek_in_buf(offset, pos, self.bytes.len(), whence); + } + + fn tell(&self) -> uint { + *self.pos } - fn tell(&self) -> uint { self.pos } } -pub fn with_bytes_reader<t>(bytes: &[u8], f: &fn(@Reader) -> t) -> t { - f(@BytesReader { bytes: bytes, pos: 0u } as @Reader) +pub fn with_bytes_reader<T>(bytes: &[u8], f: &fn(@Reader) -> T) -> T { + f(@BytesReader { + bytes: bytes, + pos: @mut 0 + } as @Reader) } pub fn with_str_reader<T>(s: &str, f: &fn(@Reader) -> T) -> T { @@ -1498,49 +1512,70 @@ pub fn buffered_file_writer(path: &Path) -> Result<@Writer, ~str> { pub fn stdout() -> @Writer { fd_writer(libc::STDOUT_FILENO as c_int, false) } pub fn stderr() -> @Writer { fd_writer(libc::STDERR_FILENO as c_int, false) } -pub fn print(s: &str) { stdout().write_str(s); } -pub fn println(s: &str) { stdout().write_line(s); } +pub fn print(s: &str) { + stdout().write_str(s); +} + +pub fn println(s: &str) { + stdout().write_line(s); +} pub struct BytesWriter { - mut bytes: ~[u8], - mut pos: uint, + bytes: @mut ~[u8], + pos: @mut uint, } impl Writer for BytesWriter { fn write(&self, v: &[u8]) { let v_len = v.len(); - let bytes_len = vec::uniq_len(&const self.bytes); - let count = uint::max(bytes_len, self.pos + v_len); - vec::reserve(&mut self.bytes, count); + let bytes = &mut *self.bytes; + let count = uint::max(bytes.len(), *self.pos + v_len); + vec::reserve(bytes, count); unsafe { - vec::raw::set_len(&mut self.bytes, count); - let view = vec::mut_slice(self.bytes, self.pos, count); + // Silly stage0 borrow check workaround... + let casted: &mut ~[u8] = cast::transmute_copy(&bytes); + vec::raw::set_len(casted, count); + + let view = vec::mut_slice(*bytes, *self.pos, count); vec::bytes::copy_memory(view, v, v_len); } - self.pos += v_len; + *self.pos += v_len; } + fn seek(&self, offset: int, whence: SeekStyle) { - let pos = self.pos; - let len = vec::uniq_len(&const self.bytes); - self.pos = seek_in_buf(offset, pos, len, whence); + let pos = *self.pos; + let len = vec::uniq_len(&const *self.bytes); + *self.pos = seek_in_buf(offset, pos, len, whence); + } + + fn tell(&self) -> uint { + *self.pos + } + + fn flush(&self) -> int { + 0 + } + + fn get_type(&self) -> WriterType { + File } - fn tell(&self) -> uint { self.pos } - fn flush(&self) -> int { 0 } - fn get_type(&self) -> WriterType { File } } pub fn BytesWriter() -> BytesWriter { - BytesWriter { bytes: ~[], mut pos: 0u } + BytesWriter { + bytes: @mut ~[], + pos: @mut 0 + } } pub fn with_bytes_writer(f: &fn(@Writer)) -> ~[u8] { let wr = @BytesWriter(); f(wr as @Writer); - let @BytesWriter{bytes, _} = wr; - return bytes; + let @BytesWriter { bytes, _ } = wr; + copy *bytes } pub fn with_str_writer(f: &fn(@Writer)) -> ~str { @@ -1550,7 +1585,9 @@ pub fn with_str_writer(f: &fn(@Writer)) -> ~str { v.push(0); assert!(str::is_utf8(v)); - unsafe { ::cast::transmute(v) } + unsafe { + ::cast::transmute(v) + } } // Utility functions @@ -1849,15 +1886,15 @@ mod tests { fn bytes_buffer_overwrite() { let wr = BytesWriter(); wr.write(~[0u8, 1u8, 2u8, 3u8]); - assert!(wr.bytes == ~[0u8, 1u8, 2u8, 3u8]); + assert!(*wr.bytes == ~[0u8, 1u8, 2u8, 3u8]); wr.seek(-2, SeekCur); wr.write(~[4u8, 5u8, 6u8, 7u8]); - assert!(wr.bytes == ~[0u8, 1u8, 4u8, 5u8, 6u8, 7u8]); + assert!(*wr.bytes == ~[0u8, 1u8, 4u8, 5u8, 6u8, 7u8]); wr.seek(-2, SeekEnd); wr.write(~[8u8]); wr.seek(1, SeekSet); wr.write(~[9u8]); - assert!(wr.bytes == ~[0u8, 9u8, 4u8, 5u8, 8u8, 7u8]); + assert!(*wr.bytes == ~[0u8, 9u8, 4u8, 5u8, 8u8, 7u8]); } #[test] diff --git a/src/libcore/os.rs b/src/libcore/os.rs index 42c77a687e5..afb96414858 100644 --- a/src/libcore/os.rs +++ b/src/libcore/os.rs @@ -352,7 +352,10 @@ pub fn fsync_fd(fd: c_int, _l: io::fsync::Level) -> c_int { } } -pub struct Pipe { in: c_int, out: c_int } +pub struct Pipe { + in: c_int, + out: c_int +} #[cfg(unix)] pub fn pipe() -> Pipe { @@ -1432,7 +1435,7 @@ mod tests { } fn make_rand_name() -> ~str { - let rng = rand::rng(); + let mut rng = rand::rng(); let n = ~"TEST" + rng.gen_str(10u); assert!(getenv(n).is_none()); n diff --git a/src/libcore/pipes.rs b/src/libcore/pipes.rs index 19674900f90..8301254fbdd 100644 --- a/src/libcore/pipes.rs +++ b/src/libcore/pipes.rs @@ -111,7 +111,7 @@ enum State { pub struct BufferHeader { // Tracks whether this buffer needs to be freed. We can probably // get away with restricting it to 0 or 1, if we're careful. - mut ref_count: int, + ref_count: int, // We may want a drop, and to be careful about stringing this // thing along. @@ -130,12 +130,12 @@ pub struct Buffer<T> { } pub struct PacketHeader { - mut state: State, - mut blocked_task: *rust_task, + state: State, + blocked_task: *rust_task, // This is a transmute_copy of a ~buffer, that can also be cast // to a buffer_header if need be. - mut buffer: *libc::c_void, + buffer: *libc::c_void, } pub fn PacketHeader() -> PacketHeader { @@ -148,14 +148,14 @@ pub fn PacketHeader() -> PacketHeader { pub impl PacketHeader { // Returns the old state. - unsafe fn mark_blocked(&self, this: *rust_task) -> State { + unsafe fn mark_blocked(&mut self, this: *rust_task) -> State { rustrt::rust_task_ref(this); let old_task = swap_task(&mut self.blocked_task, this); assert!(old_task.is_null()); swap_state_acq(&mut self.state, Blocked) } - unsafe fn unblock(&self) { + unsafe fn unblock(&mut self) { let old_task = swap_task(&mut self.blocked_task, ptr::null()); if !old_task.is_null() { rustrt::rust_task_deref(old_task) @@ -169,13 +169,13 @@ pub impl PacketHeader { // unsafe because this can do weird things to the space/time // continuum. It ends making multiple unique pointers to the same - // thing. You'll proobably want to forget them when you're done. - unsafe fn buf_header(&self) -> ~BufferHeader { + // thing. You'll probably want to forget them when you're done. + unsafe fn buf_header(&mut self) -> ~BufferHeader { assert!(self.buffer.is_not_null()); transmute_copy(&self.buffer) } - fn set_buffer<T:Owned>(&self, b: ~Buffer<T>) { + fn set_buffer<T:Owned>(&mut self, b: ~Buffer<T>) { unsafe { self.buffer = transmute_copy(&b); } @@ -184,15 +184,15 @@ pub impl PacketHeader { pub struct Packet<T> { header: PacketHeader, - mut payload: Option<T>, + payload: Option<T>, } pub trait HasBuffer { - fn set_buffer(&self, b: *libc::c_void); + fn set_buffer(&mut self, b: *libc::c_void); } impl<T:Owned> HasBuffer for Packet<T> { - fn set_buffer(&self, b: *libc::c_void) { + fn set_buffer(&mut self, b: *libc::c_void) { self.header.buffer = b; } } @@ -204,7 +204,7 @@ pub fn mk_packet<T:Owned>() -> Packet<T> { } } fn unibuffer<T>() -> ~Buffer<Packet<T>> { - let b = ~Buffer { + let mut b = ~Buffer { header: BufferHeader(), data: Packet { header: PacketHeader(), @@ -218,22 +218,25 @@ fn unibuffer<T>() -> ~Buffer<Packet<T>> { b } -pub fn packet<T>() -> *Packet<T> { - let b = unibuffer(); - let p = ptr::to_unsafe_ptr(&(b.data)); +pub fn packet<T>() -> *mut Packet<T> { + let mut b = unibuffer(); + let p = ptr::to_mut_unsafe_ptr(&mut b.data); // We'll take over memory management from here. - unsafe { forget(b) } + unsafe { + forget(b); + } p } pub fn entangle_buffer<T:Owned,Tstart:Owned>( - buffer: ~Buffer<T>, - init: &fn(*libc::c_void, x: &T) -> *Packet<Tstart>) - -> (SendPacketBuffered<Tstart, T>, RecvPacketBuffered<Tstart, T>) -{ - let p = init(unsafe { transmute_copy(&buffer) }, &buffer.data); - unsafe { forget(buffer) } - (SendPacketBuffered(p), RecvPacketBuffered(p)) + mut buffer: ~Buffer<T>, + init: &fn(*libc::c_void, x: &mut T) -> *mut Packet<Tstart>) + -> (SendPacketBuffered<Tstart, T>, RecvPacketBuffered<Tstart, T>) { + unsafe { + let p = init(transmute_copy(&buffer), &mut buffer.data); + forget(buffer); + (SendPacketBuffered(p), RecvPacketBuffered(p)) + } } pub fn swap_task(dst: &mut *rust_task, src: *rust_task) -> *rust_task { @@ -292,7 +295,7 @@ fn swap_state_rel(dst: &mut State, src: State) -> State { } } -pub unsafe fn get_buffer<T>(p: *PacketHeader) -> ~Buffer<T> { +pub unsafe fn get_buffer<T>(p: *mut PacketHeader) -> ~Buffer<T> { transmute((*p).buf_header()) } @@ -306,10 +309,14 @@ struct BufferResource<T> { impl<T> Drop for BufferResource<T> { fn finalize(&self) { unsafe { - let b = move_it!(self.buffer); + let this: &mut BufferResource<T> = transmute(self); + + let mut b = move_it!(this.buffer); //let p = ptr::to_unsafe_ptr(*b); //error!("drop %?", p); - let old_count = intrinsics::atomic_xsub_rel(&mut b.header.ref_count, 1); + let old_count = intrinsics::atomic_xsub_rel( + &mut b.header.ref_count, + 1); //let old_count = atomic_xchng_rel(b.header.ref_count, 0); if old_count == 1 { // The new count is 0. @@ -323,10 +330,12 @@ impl<T> Drop for BufferResource<T> { } } -fn BufferResource<T>(b: ~Buffer<T>) -> BufferResource<T> { +fn BufferResource<T>(mut b: ~Buffer<T>) -> BufferResource<T> { //let p = ptr::to_unsafe_ptr(*b); //error!("take %?", p); - unsafe { intrinsics::atomic_xadd_acq(&mut b.header.ref_count, 1) }; + unsafe { + intrinsics::atomic_xadd_acq(&mut b.header.ref_count, 1); + } BufferResource { // tjc: ???? @@ -334,10 +343,12 @@ fn BufferResource<T>(b: ~Buffer<T>) -> BufferResource<T> { } } -pub fn send<T,Tbuffer>(p: SendPacketBuffered<T,Tbuffer>, payload: T) -> bool { +pub fn send<T,Tbuffer>(mut p: SendPacketBuffered<T,Tbuffer>, + payload: T) + -> bool { let header = p.header(); - let p_ = p.unwrap(); - let p = unsafe { &*p_ }; + let mut p_ = p.unwrap(); + let p = unsafe { &mut *p_ }; assert!(ptr::to_unsafe_ptr(&(p.header)) == header); assert!(p.payload.is_none()); p.payload = Some(payload); @@ -391,11 +402,12 @@ Returns `None` if the sender has closed the connection without sending a message, or `Some(T)` if a message was received. */ -pub fn try_recv<T:Owned,Tbuffer:Owned>(p: RecvPacketBuffered<T, Tbuffer>) - -> Option<T> -{ - let p_ = p.unwrap(); - let p = unsafe { &*p_ }; +pub fn try_recv<T:Owned,Tbuffer:Owned>(mut p: RecvPacketBuffered<T, Tbuffer>) + -> Option<T> { + let mut p_ = p.unwrap(); + let mut p = unsafe { + &mut *p_ + }; do (|| { try_recv_(p) @@ -412,7 +424,7 @@ pub fn try_recv<T:Owned,Tbuffer:Owned>(p: RecvPacketBuffered<T, Tbuffer>) } } -fn try_recv_<T:Owned>(p: &Packet<T>) -> Option<T> { +fn try_recv_<T:Owned>(p: &mut Packet<T>) -> Option<T> { // optimistic path match p.header.state { Full => { @@ -498,16 +510,20 @@ fn try_recv_<T:Owned>(p: &Packet<T>) -> Option<T> { } /// Returns true if messages are available. -pub fn peek<T:Owned,Tb:Owned>(p: &RecvPacketBuffered<T, Tb>) -> bool { - match unsafe {(*p.header()).state} { - Empty | Terminated => false, - Blocked => fail!(~"peeking on blocked packet"), - Full => true +pub fn peek<T:Owned,Tb:Owned>(p: &mut RecvPacketBuffered<T, Tb>) -> bool { + unsafe { + match (*p.header()).state { + Empty | Terminated => false, + Blocked => fail!(~"peeking on blocked packet"), + Full => true + } } } -fn sender_terminate<T:Owned>(p: *Packet<T>) { - let p = unsafe { &*p }; +fn sender_terminate<T:Owned>(p: *mut Packet<T>) { + let p = unsafe { + &mut *p + }; match swap_state_rel(&mut p.header.state, Terminated) { Empty => { // The receiver will eventually clean up. @@ -536,8 +552,10 @@ fn sender_terminate<T:Owned>(p: *Packet<T>) { } } -fn receiver_terminate<T:Owned>(p: *Packet<T>) { - let p = unsafe { &*p }; +fn receiver_terminate<T:Owned>(p: *mut Packet<T>) { + let p = unsafe { + &mut *p + }; match swap_state_rel(&mut p.header.state, Terminated) { Empty => { assert!(p.header.blocked_task.is_null()); @@ -569,8 +587,10 @@ that vector. The index points to an endpoint that has either been closed by the sender or has a message waiting to be received. */ -pub fn wait_many<T: Selectable>(pkts: &[T]) -> uint { - let this = unsafe { rustrt::rust_get_task() }; +pub fn wait_many<T: Selectable>(pkts: &mut [T]) -> uint { + let this = unsafe { + rustrt::rust_get_task() + }; unsafe { rustrt::task_clear_event_reject(this); @@ -578,19 +598,19 @@ pub fn wait_many<T: Selectable>(pkts: &[T]) -> uint { let mut data_avail = false; let mut ready_packet = pkts.len(); - for pkts.eachi |i, p| { + for vec::eachi_mut(pkts) |i, p| { unsafe { - let p = &*p.header(); + let p = &mut *p.header(); let old = p.mark_blocked(this); match old { - Full | Terminated => { - data_avail = true; - ready_packet = i; - (*p).state = old; - break; - } - Blocked => fail!(~"blocking on blocked packet"), - Empty => () + Full | Terminated => { + data_avail = true; + ready_packet = i; + (*p).state = old; + break; + } + Blocked => fail!(~"blocking on blocked packet"), + Empty => () } } } @@ -598,7 +618,14 @@ pub fn wait_many<T: Selectable>(pkts: &[T]) -> uint { while !data_avail { debug!("sleeping on %? packets", pkts.len()); let event = wait_event(this) as *PacketHeader; - let pos = vec::position(pkts, |p| p.header() == event); + + let mut pos = None; + for vec::eachi_mut(pkts) |i, p| { + if p.header() == event { + pos = Some(i); + break; + } + }; match pos { Some(i) => { @@ -609,11 +636,15 @@ pub fn wait_many<T: Selectable>(pkts: &[T]) -> uint { } } - debug!("%?", pkts[ready_packet]); + debug!("%?", &mut pkts[ready_packet]); - for pkts.each |p| { unsafe{ (*p.header()).unblock()} } + for vec::each_mut(pkts) |p| { + unsafe { + (*p.header()).unblock() + } + } - debug!("%?, %?", ready_packet, pkts[ready_packet]); + debug!("%?, %?", ready_packet, &mut pkts[ready_packet]); unsafe { assert!((*pkts[ready_packet].header()).state == Full @@ -629,65 +660,58 @@ message. */ pub type SendPacket<T> = SendPacketBuffered<T, Packet<T>>; -pub fn SendPacket<T>(p: *Packet<T>) -> SendPacket<T> { +pub fn SendPacket<T>(p: *mut Packet<T>) -> SendPacket<T> { SendPacketBuffered(p) } pub struct SendPacketBuffered<T, Tbuffer> { - mut p: Option<*Packet<T>>, - mut buffer: Option<BufferResource<Tbuffer>>, + p: Option<*mut Packet<T>>, + buffer: Option<BufferResource<Tbuffer>>, } #[unsafe_destructor] impl<T:Owned,Tbuffer:Owned> Drop for SendPacketBuffered<T,Tbuffer> { fn finalize(&self) { - //if self.p != none { - // debug!("drop send %?", option::get(self.p)); - //} - if self.p != None { - let mut p = None; - p <-> self.p; - sender_terminate(p.unwrap()) + unsafe { + let this: &mut SendPacketBuffered<T,Tbuffer> = transmute(self); + if this.p != None { + let mut p = None; + p <-> this.p; + sender_terminate(p.unwrap()) + } } - //unsafe { error!("send_drop: %?", - // if self.buffer == none { - // "none" - // } else { "some" }); } } } -pub fn SendPacketBuffered<T,Tbuffer>(p: *Packet<T>) - -> SendPacketBuffered<T, Tbuffer> { - //debug!("take send %?", p); +pub fn SendPacketBuffered<T,Tbuffer>(p: *mut Packet<T>) + -> SendPacketBuffered<T,Tbuffer> { SendPacketBuffered { p: Some(p), buffer: unsafe { - Some(BufferResource( - get_buffer(ptr::to_unsafe_ptr(&((*p).header))))) + Some(BufferResource(get_buffer(&mut (*p).header))) } } } pub impl<T,Tbuffer> SendPacketBuffered<T,Tbuffer> { - fn unwrap(&self) -> *Packet<T> { + fn unwrap(&mut self) -> *mut Packet<T> { let mut p = None; p <-> self.p; p.unwrap() } - fn header(&self) -> *PacketHeader { + fn header(&mut self) -> *mut PacketHeader { match self.p { - Some(packet) => unsafe { - let packet = &*packet; - let header = ptr::to_unsafe_ptr(&(packet.header)); - //forget(packet); - header - }, - None => fail!(~"packet already consumed") + Some(packet) => unsafe { + let packet = &mut *packet; + let header = ptr::to_mut_unsafe_ptr(&mut packet.header); + header + }, + None => fail!(~"packet already consumed") } } - fn reuse_buffer(&self) -> BufferResource<Tbuffer> { + fn reuse_buffer(&mut self) -> BufferResource<Tbuffer> { //error!("send reuse_buffer"); let mut tmp = None; tmp <-> self.buffer; @@ -699,41 +723,37 @@ pub impl<T,Tbuffer> SendPacketBuffered<T,Tbuffer> { /// message. pub type RecvPacket<T> = RecvPacketBuffered<T, Packet<T>>; -pub fn RecvPacket<T>(p: *Packet<T>) -> RecvPacket<T> { +pub fn RecvPacket<T>(p: *mut Packet<T>) -> RecvPacket<T> { RecvPacketBuffered(p) } + pub struct RecvPacketBuffered<T, Tbuffer> { - mut p: Option<*Packet<T>>, - mut buffer: Option<BufferResource<Tbuffer>>, + p: Option<*mut Packet<T>>, + buffer: Option<BufferResource<Tbuffer>>, } #[unsafe_destructor] impl<T:Owned,Tbuffer:Owned> Drop for RecvPacketBuffered<T,Tbuffer> { fn finalize(&self) { - //if self.p != none { - // debug!("drop recv %?", option::get(self.p)); - //} - if self.p != None { - let mut p = None; - p <-> self.p; - receiver_terminate(p.unwrap()) + unsafe { + let this: &mut RecvPacketBuffered<T,Tbuffer> = transmute(self); + if this.p != None { + let mut p = None; + p <-> this.p; + receiver_terminate(p.unwrap()) + } } - //unsafe { error!("recv_drop: %?", - // if self.buffer == none { - // "none" - // } else { "some" }); } } } pub impl<T:Owned,Tbuffer:Owned> RecvPacketBuffered<T, Tbuffer> { - fn unwrap(&self) -> *Packet<T> { + fn unwrap(&mut self) -> *mut Packet<T> { let mut p = None; p <-> self.p; p.unwrap() } - fn reuse_buffer(&self) -> BufferResource<Tbuffer> { - //error!("recv reuse_buffer"); + fn reuse_buffer(&mut self) -> BufferResource<Tbuffer> { let mut tmp = None; tmp <-> self.buffer; tmp.unwrap() @@ -741,27 +761,24 @@ pub impl<T:Owned,Tbuffer:Owned> RecvPacketBuffered<T, Tbuffer> { } impl<T:Owned,Tbuffer:Owned> Selectable for RecvPacketBuffered<T, Tbuffer> { - fn header(&self) -> *PacketHeader { + fn header(&mut self) -> *mut PacketHeader { match self.p { - Some(packet) => unsafe { - let packet = &*packet; - let header = ptr::to_unsafe_ptr(&(packet.header)); - //forget(packet); - header - }, - None => fail!(~"packet already consumed") + Some(packet) => unsafe { + let packet = &mut *packet; + let header = ptr::to_mut_unsafe_ptr(&mut packet.header); + header + }, + None => fail!(~"packet already consumed") } } } -pub fn RecvPacketBuffered<T,Tbuffer>(p: *Packet<T>) - -> RecvPacketBuffered<T,Tbuffer> { - //debug!("take recv %?", p); +pub fn RecvPacketBuffered<T,Tbuffer>(p: *mut Packet<T>) + -> RecvPacketBuffered<T,Tbuffer> { RecvPacketBuffered { p: Some(p), buffer: unsafe { - Some(BufferResource( - get_buffer(ptr::to_unsafe_ptr(&((*p).header))))) + Some(BufferResource(get_buffer(&mut (*p).header))) } } } @@ -800,51 +817,55 @@ this case, `select2` may return either `left` or `right`. */ pub fn select2<A:Owned,Ab:Owned,B:Owned,Bb:Owned>( - a: RecvPacketBuffered<A, Ab>, - b: RecvPacketBuffered<B, Bb>) + mut a: RecvPacketBuffered<A, Ab>, + mut b: RecvPacketBuffered<B, Bb>) -> Either<(Option<A>, RecvPacketBuffered<B, Bb>), - (RecvPacketBuffered<A, Ab>, Option<B>)> -{ - let i = wait_many([a.header(), b.header()]); - + (RecvPacketBuffered<A, Ab>, Option<B>)> { + let mut endpoints = [ a.header(), b.header() ]; + let i = wait_many(endpoints); match i { - 0 => Left((try_recv(a), b)), - 1 => Right((a, try_recv(b))), - _ => fail!(~"select2 return an invalid packet") + 0 => Left((try_recv(a), b)), + 1 => Right((a, try_recv(b))), + _ => fail!(~"select2 return an invalid packet") } } pub trait Selectable { - fn header(&self) -> *PacketHeader; + fn header(&mut self) -> *mut PacketHeader; } -impl Selectable for *PacketHeader { - fn header(&self) -> *PacketHeader { *self } +impl Selectable for *mut PacketHeader { + fn header(&mut self) -> *mut PacketHeader { *self } } /// Returns the index of an endpoint that is ready to receive. -pub fn selecti<T:Selectable>(endpoints: &[T]) -> uint { +pub fn selecti<T:Selectable>(endpoints: &mut [T]) -> uint { wait_many(endpoints) } /// Returns 0 or 1 depending on which endpoint is ready to receive -pub fn select2i<A:Selectable,B:Selectable>(a: &A, b: &B) -> - Either<(), ()> { - match wait_many([a.header(), b.header()]) { - 0 => Left(()), - 1 => Right(()), - _ => fail!(~"wait returned unexpected index") +pub fn select2i<A:Selectable,B:Selectable>(a: &mut A, b: &mut B) + -> Either<(), ()> { + let mut endpoints = [ a.header(), b.header() ]; + match wait_many(endpoints) { + 0 => Left(()), + 1 => Right(()), + _ => fail!(~"wait returned unexpected index") } } -/** Waits on a set of endpoints. Returns a message, its index, and a - list of the remaining endpoints. +/// Waits on a set of endpoints. Returns a message, its index, and a +/// list of the remaining endpoints. +pub fn select<T:Owned,Tb:Owned>(mut endpoints: ~[RecvPacketBuffered<T, Tb>]) + -> (uint, + Option<T>, + ~[RecvPacketBuffered<T, Tb>]) { + let mut endpoint_headers = ~[]; + for vec::each_mut(endpoints) |endpoint| { + endpoint_headers.push(endpoint.header()); + } -*/ -pub fn select<T:Owned,Tb:Owned>(endpoints: ~[RecvPacketBuffered<T, Tb>]) - -> (uint, Option<T>, ~[RecvPacketBuffered<T, Tb>]) -{ - let ready = wait_many(endpoints.map(|p| p.header())); + let ready = wait_many(endpoint_headers); let mut remaining = endpoints; let port = remaining.swap_remove(ready); let result = try_recv(port); @@ -873,9 +894,10 @@ mod test { c1.send(~"abc"); - match (p1, p2).select() { - Right(_) => fail!(), - _ => () + let mut tuple = (p1, p2); + match tuple.select() { + Right(_) => fail!(), + _ => (), } c2.send(123); diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 85e46a0feff..1a5ff39b305 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -336,7 +336,10 @@ pub mod ptr_tests { #[test] fn test() { unsafe { - struct Pair {mut fst: int, mut snd: int}; + struct Pair { + fst: int, + snd: int + }; let mut p = Pair {fst: 10, snd: 20}; let pptr: *mut Pair = &mut p; let iptr: *mut int = cast::transmute(pptr); diff --git a/src/libcore/rand.rs b/src/libcore/rand.rs index 80f69f067eb..f11840c95d5 100644 --- a/src/libcore/rand.rs +++ b/src/libcore/rand.rs @@ -55,12 +55,12 @@ pub mod distributions; /// A type that can be randomly generated using an Rng pub trait Rand { - fn rand<R: Rng>(rng: &R) -> Self; + fn rand<R: Rng>(rng: &mut R) -> Self; } impl Rand for int { #[inline] - fn rand<R: Rng>(rng: &R) -> int { + fn rand<R: Rng>(rng: &mut R) -> int { if int::bits == 32 { rng.next() as int } else { @@ -71,35 +71,35 @@ impl Rand for int { impl Rand for i8 { #[inline] - fn rand<R: Rng>(rng: &R) -> i8 { + fn rand<R: Rng>(rng: &mut R) -> i8 { rng.next() as i8 } } impl Rand for i16 { #[inline] - fn rand<R: Rng>(rng: &R) -> i16 { + fn rand<R: Rng>(rng: &mut R) -> i16 { rng.next() as i16 } } impl Rand for i32 { #[inline] - fn rand<R: Rng>(rng: &R) -> i32 { + fn rand<R: Rng>(rng: &mut R) -> i32 { rng.next() as i32 } } impl Rand for i64 { #[inline] - fn rand<R: Rng>(rng: &R) -> i64 { + fn rand<R: Rng>(rng: &mut R) -> i64 { (rng.next() as i64 << 32) | rng.next() as i64 } } impl Rand for uint { #[inline] - fn rand<R: Rng>(rng: &R) -> uint { + fn rand<R: Rng>(rng: &mut R) -> uint { if uint::bits == 32 { rng.next() as uint } else { @@ -110,42 +110,42 @@ impl Rand for uint { impl Rand for u8 { #[inline] - fn rand<R: Rng>(rng: &R) -> u8 { + fn rand<R: Rng>(rng: &mut R) -> u8 { rng.next() as u8 } } impl Rand for u16 { #[inline] - fn rand<R: Rng>(rng: &R) -> u16 { + fn rand<R: Rng>(rng: &mut R) -> u16 { rng.next() as u16 } } impl Rand for u32 { #[inline] - fn rand<R: Rng>(rng: &R) -> u32 { + fn rand<R: Rng>(rng: &mut R) -> u32 { rng.next() } } impl Rand for u64 { #[inline] - fn rand<R: Rng>(rng: &R) -> u64 { + fn rand<R: Rng>(rng: &mut R) -> u64 { (rng.next() as u64 << 32) | rng.next() as u64 } } impl Rand for float { #[inline] - fn rand<R: Rng>(rng: &R) -> float { + fn rand<R: Rng>(rng: &mut R) -> float { rng.gen::<f64>() as float } } impl Rand for f32 { #[inline] - fn rand<R: Rng>(rng: &R) -> f32 { + fn rand<R: Rng>(rng: &mut R) -> f32 { rng.gen::<f64>() as f32 } } @@ -153,7 +153,7 @@ impl Rand for f32 { static scale : f64 = (u32::max_value as f64) + 1.0f64; impl Rand for f64 { #[inline] - fn rand<R: Rng>(rng: &R) -> f64 { + fn rand<R: Rng>(rng: &mut R) -> f64 { let u1 = rng.next() as f64; let u2 = rng.next() as f64; let u3 = rng.next() as f64; @@ -164,14 +164,14 @@ impl Rand for f64 { impl Rand for char { #[inline] - fn rand<R: Rng>(rng: &R) -> char { + fn rand<R: Rng>(rng: &mut R) -> char { rng.next() as char } } impl Rand for bool { #[inline] - fn rand<R: Rng>(rng: &R) -> bool { + fn rand<R: Rng>(rng: &mut R) -> bool { rng.next() & 1u32 == 1u32 } } @@ -185,7 +185,7 @@ macro_rules! tuple_impl { > Rand for ( $( $tyvar ),* , ) { #[inline] - fn rand<R: Rng>(_rng: &R) -> ( $( $tyvar ),* , ) { + fn rand<R: Rng>(_rng: &mut R) -> ( $( $tyvar ),* , ) { ( // use the $tyvar's to get the appropriate number of // repeats (they're not actually needed) @@ -201,7 +201,7 @@ macro_rules! tuple_impl { impl Rand for () { #[inline] - fn rand<R: Rng>(_: &R) -> () { () } + fn rand<R: Rng>(_: &mut R) -> () { () } } tuple_impl!{A} tuple_impl!{A, B} @@ -216,7 +216,7 @@ tuple_impl!{A, B, C, D, E, F, G, H, I, J} impl<T:Rand> Rand for Option<T> { #[inline] - fn rand<R: Rng>(rng: &R) -> Option<T> { + fn rand<R: Rng>(rng: &mut R) -> Option<T> { if rng.gen() { Some(rng.gen()) } else { @@ -227,12 +227,12 @@ impl<T:Rand> Rand for Option<T> { impl<T: Rand> Rand for ~T { #[inline] - fn rand<R: Rng>(rng: &R) -> ~T { ~rng.gen() } + fn rand<R: Rng>(rng: &mut R) -> ~T { ~rng.gen() } } impl<T: Rand> Rand for @T { #[inline] - fn rand<R: Rng>(rng: &R) -> @T { @rng.gen() } + fn rand<R: Rng>(rng: &mut R) -> @T { @rng.gen() } } #[abi = "cdecl"] @@ -248,7 +248,7 @@ pub mod rustrt { /// A random number generator pub trait Rng { /// Return the next random integer - pub fn next(&self) -> u32; + pub fn next(&mut self) -> u32; } /// A value with a particular weight compared to other values @@ -259,21 +259,21 @@ pub struct Weighted<T> { pub trait RngUtil { /// Return a random value of a Rand type - fn gen<T:Rand>(&self) -> T; + fn gen<T:Rand>(&mut self) -> T; /** * Return a int randomly chosen from the range [start, end), * failing if start >= end */ - fn gen_int_range(&self, start: int, end: int) -> int; + fn gen_int_range(&mut self, start: int, end: int) -> int; /** * Return a uint randomly chosen from the range [start, end), * failing if start >= end */ - fn gen_uint_range(&self, start: uint, end: uint) -> uint; + fn gen_uint_range(&mut self, start: uint, end: uint) -> uint; /** * Return a char randomly chosen from chars, failing if chars is empty */ - fn gen_char_from(&self, chars: &str) -> char; + fn gen_char_from(&mut self, chars: &str) -> char; /** * Return a bool with a 1 in n chance of true * @@ -289,7 +289,7 @@ pub trait RngUtil { * } * ~~~ */ - fn gen_weighted_bool(&self, n: uint) -> bool; + fn gen_weighted_bool(&mut self, n: uint) -> bool; /** * Return a random string of the specified length composed of A-Z,a-z,0-9 * @@ -305,7 +305,7 @@ pub trait RngUtil { * } * ~~~ */ - fn gen_str(&self, len: uint) -> ~str; + fn gen_str(&mut self, len: uint) -> ~str; /** * Return a random byte string of the specified length * @@ -321,7 +321,7 @@ pub trait RngUtil { * } * ~~~ */ - fn gen_bytes(&self, len: uint) -> ~[u8]; + fn gen_bytes(&mut self, len: uint) -> ~[u8]; /** * Choose an item randomly, failing if values is empty * @@ -337,9 +337,9 @@ pub trait RngUtil { * } * ~~~ */ - fn choose<T:Copy>(&self, values: &[T]) -> T; + fn choose<T:Copy>(&mut self, values: &[T]) -> T; /// Choose Some(item) randomly, returning None if values is empty - fn choose_option<T:Copy>(&self, values: &[T]) -> Option<T>; + fn choose_option<T:Copy>(&mut self, values: &[T]) -> Option<T>; /** * Choose an item respecting the relative weights, failing if the sum of * the weights is 0 @@ -359,7 +359,7 @@ pub trait RngUtil { * } * ~~~ */ - fn choose_weighted<T:Copy>(&self, v : &[Weighted<T>]) -> T; + fn choose_weighted<T:Copy>(&mut self, v : &[Weighted<T>]) -> T; /** * Choose Some(item) respecting the relative weights, returning none if * the sum of the weights is 0 @@ -379,7 +379,8 @@ pub trait RngUtil { * } * ~~~ */ - fn choose_weighted_option<T:Copy>(&self, v: &[Weighted<T>]) -> Option<T>; + fn choose_weighted_option<T:Copy>(&mut self, v: &[Weighted<T>]) + -> Option<T>; /** * Return a vec containing copies of the items, in order, where * the weight of the item determines how many copies there are @@ -399,7 +400,7 @@ pub trait RngUtil { * } * ~~~ */ - fn weighted_vec<T:Copy>(&self, v: &[Weighted<T>]) -> ~[T]; + fn weighted_vec<T:Copy>(&mut self, v: &[Weighted<T>]) -> ~[T]; /** * Shuffle a vec * @@ -415,7 +416,7 @@ pub trait RngUtil { * } * ~~~ */ - fn shuffle<T:Copy>(&self, values: &[T]) -> ~[T]; + fn shuffle<T:Copy>(&mut self, values: &[T]) -> ~[T]; /** * Shuffle a mutable vec in place * @@ -435,14 +436,14 @@ pub trait RngUtil { * } * ~~~ */ - fn shuffle_mut<T>(&self, values: &mut [T]); + fn shuffle_mut<T>(&mut self, values: &mut [T]); } /// Extension methods for random number generators impl<R: Rng> RngUtil for R { /// Return a random value for a Rand type #[inline(always)] - fn gen<T: Rand>(&self) -> T { + fn gen<T: Rand>(&mut self) -> T { Rand::rand(self) } @@ -450,7 +451,7 @@ impl<R: Rng> RngUtil for R { * Return an int randomly chosen from the range [start, end), * failing if start >= end */ - fn gen_int_range(&self, start: int, end: int) -> int { + fn gen_int_range(&mut self, start: int, end: int) -> int { assert!(start < end); start + int::abs(self.gen::<int>() % (end - start)) } @@ -459,7 +460,7 @@ impl<R: Rng> RngUtil for R { * Return a uint randomly chosen from the range [start, end), * failing if start >= end */ - fn gen_uint_range(&self, start: uint, end: uint) -> uint { + fn gen_uint_range(&mut self, start: uint, end: uint) -> uint { assert!(start < end); start + (self.gen::<uint>() % (end - start)) } @@ -467,7 +468,7 @@ impl<R: Rng> RngUtil for R { /** * Return a char randomly chosen from chars, failing if chars is empty */ - fn gen_char_from(&self, chars: &str) -> char { + fn gen_char_from(&mut self, chars: &str) -> char { assert!(!chars.is_empty()); let mut cs = ~[]; for str::each_char(chars) |c| { cs.push(c) } @@ -475,7 +476,7 @@ impl<R: Rng> RngUtil for R { } /// Return a bool with a 1-in-n chance of true - fn gen_weighted_bool(&self, n: uint) -> bool { + fn gen_weighted_bool(&mut self, n: uint) -> bool { if n == 0u { true } else { @@ -486,7 +487,7 @@ impl<R: Rng> RngUtil for R { /** * Return a random string of the specified length composed of A-Z,a-z,0-9 */ - fn gen_str(&self, len: uint) -> ~str { + fn gen_str(&mut self, len: uint) -> ~str { let charset = ~"ABCDEFGHIJKLMNOPQRSTUVWXYZ\ abcdefghijklmnopqrstuvwxyz\ 0123456789"; @@ -500,19 +501,19 @@ impl<R: Rng> RngUtil for R { } /// Return a random byte string of the specified length - fn gen_bytes(&self, len: uint) -> ~[u8] { + fn gen_bytes(&mut self, len: uint) -> ~[u8] { do vec::from_fn(len) |_i| { self.gen() } } /// Choose an item randomly, failing if values is empty - fn choose<T:Copy>(&self, values: &[T]) -> T { + fn choose<T:Copy>(&mut self, values: &[T]) -> T { self.choose_option(values).get() } /// Choose Some(item) randomly, returning None if values is empty - fn choose_option<T:Copy>(&self, values: &[T]) -> Option<T> { + fn choose_option<T:Copy>(&mut self, values: &[T]) -> Option<T> { if values.is_empty() { None } else { @@ -523,7 +524,7 @@ impl<R: Rng> RngUtil for R { * Choose an item respecting the relative weights, failing if the sum of * the weights is 0 */ - fn choose_weighted<T:Copy>(&self, v : &[Weighted<T>]) -> T { + fn choose_weighted<T:Copy>(&mut self, v: &[Weighted<T>]) -> T { self.choose_weighted_option(v).get() } @@ -531,7 +532,8 @@ impl<R: Rng> RngUtil for R { * Choose Some(item) respecting the relative weights, returning none if * the sum of the weights is 0 */ - fn choose_weighted_option<T:Copy>(&self, v: &[Weighted<T>]) -> Option<T> { + fn choose_weighted_option<T:Copy>(&mut self, v: &[Weighted<T>]) + -> Option<T> { let mut total = 0u; for v.each |item| { total += item.weight; @@ -554,7 +556,7 @@ impl<R: Rng> RngUtil for R { * Return a vec containing copies of the items, in order, where * the weight of the item determines how many copies there are */ - fn weighted_vec<T:Copy>(&self, v: &[Weighted<T>]) -> ~[T] { + fn weighted_vec<T:Copy>(&mut self, v: &[Weighted<T>]) -> ~[T] { let mut r = ~[]; for v.each |item| { for uint::range(0u, item.weight) |_i| { @@ -565,14 +567,14 @@ impl<R: Rng> RngUtil for R { } /// Shuffle a vec - fn shuffle<T:Copy>(&self, values: &[T]) -> ~[T] { + fn shuffle<T:Copy>(&mut self, values: &[T]) -> ~[T] { let mut m = vec::from_slice(values); self.shuffle_mut(m); m } /// Shuffle a mutable vec in place - fn shuffle_mut<T>(&self, values: &mut [T]) { + fn shuffle_mut<T>(&mut self, values: &mut [T]) { let mut i = values.len(); while i >= 2u { // invariant: elements with index >= i have been locked in place. @@ -594,12 +596,12 @@ static RAND_SIZE: u32 = 1 << RAND_SIZE_LEN; /// A random number generator that uses the [ISAAC /// algorithm](http://en.wikipedia.org/wiki/ISAAC_%28cipher%29). pub struct IsaacRng { - priv mut cnt: u32, - priv mut rsl: [u32, .. RAND_SIZE], - priv mut mem: [u32, .. RAND_SIZE], - priv mut a: u32, - priv mut b: u32, - priv mut c: u32 + priv cnt: u32, + priv rsl: [u32, .. RAND_SIZE], + priv mem: [u32, .. RAND_SIZE], + priv a: u32, + priv b: u32, + priv c: u32 } pub impl IsaacRng { @@ -647,7 +649,7 @@ pub impl IsaacRng { /// Initialises `self`. If `use_rsl` is true, then use the current value /// of `rsl` as a seed, otherwise construct one algorithmically (not /// randomly). - priv fn init(&self, use_rsl: bool) { + priv fn init(&mut self, use_rsl: bool) { macro_rules! init_mut_many ( ($( $var:ident ),* = $val:expr ) => { let mut $( $var = $val ),*; @@ -705,16 +707,16 @@ pub impl IsaacRng { /// Refills the output buffer (`self.rsl`) #[inline] - priv fn isaac(&self) { + priv fn isaac(&mut self) { self.c += 1; // abbreviations let mut a = self.a, b = self.b + self.c; - let mem = &mut self.mem; - let rsl = &mut self.rsl; static midpoint: uint = RAND_SIZE as uint / 2; - macro_rules! ind (($x:expr) => { mem[($x >> 2) & (RAND_SIZE - 1)] }); + macro_rules! ind (($x:expr) => { + self.mem[($x >> 2) & (RAND_SIZE - 1)] + }); macro_rules! rngstep( ($j:expr, $shift:expr) => {{ let base = base + $j; @@ -724,13 +726,13 @@ pub impl IsaacRng { a << $shift as uint }; - let x = mem[base + mr_offset]; - a = (a ^ mix) + mem[base + m2_offset]; + let x = self.mem[base + mr_offset]; + a = (a ^ mix) + self.mem[base + m2_offset]; let y = ind!(x) + a + b; - mem[base + mr_offset] = y; + self.mem[base + mr_offset] = y; b = ind!(y >> RAND_SIZE_LEN) + x; - rsl[base + mr_offset] = b; + self.rsl[base + mr_offset] = b; }} ); @@ -751,7 +753,7 @@ pub impl IsaacRng { impl Rng for IsaacRng { #[inline(always)] - fn next(&self) -> u32 { + fn next(&mut self) -> u32 { if self.cnt == 0 { // make some more numbers self.isaac(); @@ -765,15 +767,15 @@ impl Rng for IsaacRng { /// generator](http://en.wikipedia.org/wiki/Xorshift). Not suitable for /// cryptographic purposes. pub struct XorShiftRng { - priv mut x: u32, - priv mut y: u32, - priv mut z: u32, - priv mut w: u32, + priv x: u32, + priv y: u32, + priv z: u32, + priv w: u32, } impl Rng for XorShiftRng { #[inline] - pub fn next(&self) -> u32 { + pub fn next(&mut self) -> u32 { let x = self.x; let t = x ^ (x << 11); self.x = self.y; @@ -789,7 +791,10 @@ pub impl XorShiftRng { /// Create an xor shift random number generator with a default seed. fn new() -> XorShiftRng { // constants taken from http://en.wikipedia.org/wiki/Xorshift - XorShiftRng::new_seeded(123456789u32, 362436069u32, 521288629u32, 88675123u32) + XorShiftRng::new_seeded(123456789u32, + 362436069u32, + 521288629u32, + 88675123u32) } /** @@ -798,7 +803,12 @@ pub impl XorShiftRng { * all other generators constructed with the same seed. */ fn new_seeded(x: u32, y: u32, z: u32, w: u32) -> XorShiftRng { - XorShiftRng { x: x, y: y, z: z, w: w } + XorShiftRng { + x: x, + y: y, + z: z, + w: w, + } } } @@ -815,7 +825,7 @@ pub fn seed() -> ~[u8] { } // used to make space in TLS for a random number generator -fn tls_rng_state(_v: @IsaacRng) {} +fn tls_rng_state(_v: @@mut IsaacRng) {} /** * Gives back a lazily initialized task-local random number generator, @@ -823,15 +833,15 @@ fn tls_rng_state(_v: @IsaacRng) {} * `task_rng().gen::<int>()`. */ #[inline] -pub fn task_rng() -> @IsaacRng { - let r : Option<@IsaacRng>; +pub fn task_rng() -> @@mut IsaacRng { + let r : Option<@@mut IsaacRng>; unsafe { r = task::local_data::local_data_get(tls_rng_state); } match r { None => { unsafe { - let rng = @IsaacRng::new_seeded(seed()); + let rng = @@mut IsaacRng::new_seeded(seed()); task::local_data::local_data_set(tls_rng_state, rng); rng } @@ -841,9 +851,13 @@ pub fn task_rng() -> @IsaacRng { } // Allow direct chaining with `task_rng` -impl<R: Rng> Rng for @R { +impl<R: Rng> Rng for @@mut R { #[inline(always)] - fn next(&self) -> u32 { (**self).next() } + fn next(&mut self) -> u32 { + match *self { + @@ref mut r => r.next() + } + } } /** @@ -852,7 +866,9 @@ impl<R: Rng> Rng for @R { */ #[inline] pub fn random<T: Rand>() -> T { - (*task_rng()).gen() + match *task_rng() { + @ref mut r => r.gen() + } } #[cfg(test)] @@ -863,8 +879,8 @@ mod tests { #[test] fn test_rng_seeded() { let seed = seed(); - let ra = IsaacRng::new_seeded(seed); - let rb = IsaacRng::new_seeded(seed); + let mut ra = IsaacRng::new_seeded(seed); + let mut rb = IsaacRng::new_seeded(seed); assert!(ra.gen_str(100u) == rb.gen_str(100u)); } @@ -872,15 +888,15 @@ mod tests { fn test_rng_seeded_custom_seed() { // much shorter than generated seeds which are 1024 bytes let seed = [2u8, 32u8, 4u8, 32u8, 51u8]; - let ra = IsaacRng::new_seeded(seed); - let rb = IsaacRng::new_seeded(seed); + let mut ra = IsaacRng::new_seeded(seed); + let mut rb = IsaacRng::new_seeded(seed); assert!(ra.gen_str(100u) == rb.gen_str(100u)); } #[test] fn test_rng_seeded_custom_seed2() { let seed = [2u8, 32u8, 4u8, 32u8, 51u8]; - let ra = IsaacRng::new_seeded(seed); + let mut ra = IsaacRng::new_seeded(seed); // Regression test that isaac is actually using the above vector let r = ra.next(); error!("%?", r); @@ -890,7 +906,7 @@ mod tests { #[test] fn test_gen_int_range() { - let r = rng(); + let mut r = rng(); let a = r.gen_int_range(-3, 42); assert!(a >= -3 && a < 42); assert!(r.gen_int_range(0, 1) == 0); @@ -901,12 +917,13 @@ mod tests { #[should_fail] #[ignore(cfg(windows))] fn test_gen_int_from_fail() { - rng().gen_int_range(5, -2); + let mut r = rng(); + r.gen_int_range(5, -2); } #[test] fn test_gen_uint_range() { - let r = rng(); + let mut r = rng(); let a = r.gen_uint_range(3u, 42u); assert!(a >= 3u && a < 42u); assert!(r.gen_uint_range(0u, 1u) == 0u); @@ -917,12 +934,13 @@ mod tests { #[should_fail] #[ignore(cfg(windows))] fn test_gen_uint_range_fail() { - rng().gen_uint_range(5u, 2u); + let mut r = rng(); + r.gen_uint_range(5u, 2u); } #[test] fn test_gen_float() { - let r = rng(); + let mut r = rng(); let a = r.gen::<float>(); let b = r.gen::<float>(); debug!((a, b)); @@ -930,14 +948,14 @@ mod tests { #[test] fn test_gen_weighted_bool() { - let r = rng(); + let mut r = rng(); assert!(r.gen_weighted_bool(0u) == true); assert!(r.gen_weighted_bool(1u) == true); } #[test] fn test_gen_str() { - let r = rng(); + let mut r = rng(); debug!(r.gen_str(10u)); debug!(r.gen_str(10u)); debug!(r.gen_str(10u)); @@ -948,7 +966,7 @@ mod tests { #[test] fn test_gen_bytes() { - let r = rng(); + let mut r = rng(); assert!(r.gen_bytes(0u).len() == 0u); assert!(r.gen_bytes(10u).len() == 10u); assert!(r.gen_bytes(16u).len() == 16u); @@ -956,13 +974,13 @@ mod tests { #[test] fn test_choose() { - let r = rng(); + let mut r = rng(); assert!(r.choose([1, 1, 1]) == 1); } #[test] fn test_choose_option() { - let r = rng(); + let mut r = rng(); let x: Option<int> = r.choose_option([]); assert!(x.is_none()); assert!(r.choose_option([1, 1, 1]) == Some(1)); @@ -970,7 +988,7 @@ mod tests { #[test] fn test_choose_weighted() { - let r = rng(); + let mut r = rng(); assert!(r.choose_weighted(~[ Weighted { weight: 1u, item: 42 }, ]) == 42); @@ -982,7 +1000,7 @@ mod tests { #[test] fn test_choose_weighted_option() { - let r = rng(); + let mut r = rng(); assert!(r.choose_weighted_option(~[ Weighted { weight: 1u, item: 42 }, ]) == Some(42)); @@ -996,7 +1014,7 @@ mod tests { #[test] fn test_weighted_vec() { - let r = rng(); + let mut r = rng(); let empty: ~[int] = ~[]; assert!(r.weighted_vec(~[]) == empty); assert!(r.weighted_vec(~[ @@ -1008,7 +1026,7 @@ mod tests { #[test] fn test_shuffle() { - let r = rng(); + let mut r = rng(); let empty: ~[int] = ~[]; assert!(r.shuffle(~[]) == empty); assert!(r.shuffle(~[1, 1, 1]) == ~[1, 1, 1]); @@ -1016,7 +1034,7 @@ mod tests { #[test] fn test_task_rng() { - let r = task_rng(); + let mut r = task_rng(); r.gen::<int>(); assert!(r.shuffle(~[1, 1, 1]) == ~[1, 1, 1]); assert!(r.gen_uint_range(0u, 1u) == 0u); @@ -1063,7 +1081,7 @@ mod tests { let rt_rng = do vec::as_imm_buf(seed) |p, sz| { rustrt::rand_new_seeded(p, sz as size_t) }; - let rng = IsaacRng::new_seeded(seed); + let mut rng = IsaacRng::new_seeded(seed); for 10000.times { assert_eq!(rng.next(), rustrt::rand_next(rt_rng)); diff --git a/src/libcore/rand/distributions.rs b/src/libcore/rand/distributions.rs index a644f60db69..72cff5111e7 100644 --- a/src/libcore/rand/distributions.rs +++ b/src/libcore/rand/distributions.rs @@ -27,13 +27,13 @@ mod ziggurat_tables; // inlining should mean there is no performance penalty for this #[inline(always)] -fn ziggurat<R:Rng>(rng: &R, +fn ziggurat<R:Rng>(rng: &mut R, center_u: bool, X: ziggurat_tables::ZigTable, F: ziggurat_tables::ZigTable, F_DIFF: ziggurat_tables::ZigTable, pdf: &'static fn(f64) -> f64, // probability density function - zero_case: &'static fn(&R, f64) -> f64) -> f64 { + zero_case: &'static fn(&mut R, f64) -> f64) -> f64 { loop { let u = if center_u {2.0 * rng.gen() - 1.0} else {rng.gen()}; let i: uint = rng.gen::<uint>() & 0xff; @@ -76,13 +76,13 @@ fn ziggurat<R:Rng>(rng: &R, pub struct StandardNormal(f64); impl Rand for StandardNormal { - fn rand<R:Rng>(rng: &R) -> StandardNormal { + fn rand<R:Rng>(rng: &mut R) -> StandardNormal { #[inline(always)] fn pdf(x: f64) -> f64 { f64::exp((-x*x/2.0) as f64) as f64 } #[inline(always)] - fn zero_case<R:Rng>(rng: &R, u: f64) -> f64 { + fn zero_case<R:Rng>(rng: &mut R, u: f64) -> f64 { // compute a random number in the tail by hand // strange initial conditions, because the loop is not @@ -130,13 +130,13 @@ pub struct Exp1(f64); // This could be done via `-f64::ln(rng.gen::<f64>())` but that is slower. impl Rand for Exp1 { #[inline] - fn rand<R:Rng>(rng: &R) -> Exp1 { + fn rand<R:Rng>(rng: &mut R) -> Exp1 { #[inline(always)] fn pdf(x: f64) -> f64 { f64::exp(-x) } #[inline(always)] - fn zero_case<R:Rng>(rng: &R, _u: f64) -> f64 { + fn zero_case<R:Rng>(rng: &mut R, _u: f64) -> f64 { ziggurat_tables::ZIG_EXP_R - f64::ln(rng.gen()) } diff --git a/src/libcore/repr.rs b/src/libcore/repr.rs index 3d525993259..a645a7e8680 100644 --- a/src/libcore/repr.rs +++ b/src/libcore/repr.rs @@ -144,28 +144,30 @@ enum VariantState { } pub struct ReprVisitor { - mut ptr: *c_void, - mut ptr_stk: ~[*c_void], - mut var_stk: ~[VariantState], + ptr: @mut *c_void, + ptr_stk: @mut ~[*c_void], + var_stk: @mut ~[VariantState], writer: @Writer } pub fn ReprVisitor(ptr: *c_void, writer: @Writer) -> ReprVisitor { - ReprVisitor { ptr: ptr, - ptr_stk: ~[], - var_stk: ~[], - writer: writer } + ReprVisitor { + ptr: @mut ptr, + ptr_stk: @mut ~[], + var_stk: @mut ~[], + writer: writer, + } } impl MovePtr for ReprVisitor { #[inline(always)] fn move_ptr(&self, adjustment: &fn(*c_void) -> *c_void) { - self.ptr = adjustment(self.ptr); + *self.ptr = adjustment(*self.ptr); } fn push_ptr(&self) { - self.ptr_stk.push(self.ptr); + self.ptr_stk.push(*self.ptr); } fn pop_ptr(&self) { - self.ptr = self.ptr_stk.pop(); + *self.ptr = self.ptr_stk.pop(); } } @@ -176,14 +178,14 @@ pub impl ReprVisitor { #[inline(always)] fn get<T>(&self, f: &fn(&T)) -> bool { unsafe { - f(transmute::<*c_void,&T>(copy self.ptr)); + f(transmute::<*c_void,&T>(*self.ptr)); } true } #[inline(always)] fn visit_inner(&self, inner: *TyDesc) -> bool { - self.visit_ptr_inner(self.ptr, inner) + self.visit_ptr_inner(*self.ptr, inner) } #[inline(always)] @@ -446,11 +448,16 @@ impl TyVisitor for ReprVisitor { true } - fn visit_enter_enum(&self, _n_variants: uint, + fn visit_enter_enum(&self, + _n_variants: uint, get_disr: extern unsafe fn(ptr: *Opaque) -> int, - _sz: uint, _align: uint) -> bool { - let disr = unsafe { get_disr(transmute(self.ptr)) }; - self.var_stk.push(SearchingFor(disr)); + _sz: uint, + _align: uint) -> bool { + let var_stk: &mut ~[VariantState] = self.var_stk; + let disr = unsafe { + get_disr(transmute(*self.ptr)) + }; + var_stk.push(SearchingFor(disr)); true } @@ -482,8 +489,12 @@ impl TyVisitor for ReprVisitor { true } - fn visit_enum_variant_field(&self, i: uint, _offset: uint, inner: *TyDesc) -> bool { - match self.var_stk[vec::uniq_len(&const self.var_stk) - 1] { + fn visit_enum_variant_field(&self, + i: uint, + _offset: uint, + inner: *TyDesc) + -> bool { + match self.var_stk[vec::uniq_len(&const *self.var_stk) - 1] { Matched => { if i != 0 { self.writer.write_str(", "); @@ -501,7 +512,7 @@ impl TyVisitor for ReprVisitor { _disr_val: int, n_fields: uint, _name: &str) -> bool { - match self.var_stk[vec::uniq_len(&const self.var_stk) - 1] { + match self.var_stk[vec::uniq_len(&const *self.var_stk) - 1] { Matched => { if n_fields > 0 { self.writer.write_char(')'); @@ -512,10 +523,14 @@ impl TyVisitor for ReprVisitor { true } - fn visit_leave_enum(&self, _n_variants: uint, + fn visit_leave_enum(&self, + _n_variants: uint, _get_disr: extern unsafe fn(ptr: *Opaque) -> int, - _sz: uint, _align: uint) -> bool { - match self.var_stk.pop() { + _sz: uint, + _align: uint) + -> bool { + let var_stk: &mut ~[VariantState] = self.var_stk; + match var_stk.pop() { SearchingFor(*) => fail!(~"enum value matched no variant"), _ => true } diff --git a/src/libcore/rt/local_services.rs b/src/libcore/rt/local_services.rs index b83e1d24648..5ca7a72e84e 100644 --- a/src/libcore/rt/local_services.rs +++ b/src/libcore/rt/local_services.rs @@ -225,8 +225,8 @@ mod test { fn rng() { do run_in_newsched_task() { use rand::{rng, Rng}; - let r = rng(); + let mut r = rng(); let _ = r.next(); } } -} \ No newline at end of file +} diff --git a/src/libcore/rt/uvll.rs b/src/libcore/rt/uvll.rs index 3eb7f8006b9..4bff3bff7d3 100644 --- a/src/libcore/rt/uvll.rs +++ b/src/libcore/rt/uvll.rs @@ -393,24 +393,26 @@ extern { // FIXME ref #2064 fn rust_uv_tcp_connect(connect_ptr: *uv_connect_t, tcp_handle_ptr: *uv_tcp_t, - ++after_cb: *u8, - ++addr: *sockaddr_in) -> c_int; + after_cb: *u8, + addr: *sockaddr_in) -> c_int; // FIXME ref #2064 - fn rust_uv_tcp_bind(tcp_server: *uv_tcp_t, ++addr: *sockaddr_in) -> c_int; + fn rust_uv_tcp_bind(tcp_server: *uv_tcp_t, addr: *sockaddr_in) -> c_int; // FIXME ref #2064 fn rust_uv_tcp_connect6(connect_ptr: *uv_connect_t, tcp_handle_ptr: *uv_tcp_t, - ++after_cb: *u8, - ++addr: *sockaddr_in6) -> c_int; + after_cb: *u8, + addr: *sockaddr_in6) -> c_int; // FIXME ref #2064 - fn rust_uv_tcp_bind6(tcp_server: *uv_tcp_t, ++addr: *sockaddr_in6) -> c_int; - fn rust_uv_tcp_getpeername(tcp_handle_ptr: *uv_tcp_t, ++name: *sockaddr_in) -> c_int; - fn rust_uv_tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t, ++name: *sockaddr_in6) ->c_int; + fn rust_uv_tcp_bind6(tcp_server: *uv_tcp_t, addr: *sockaddr_in6) -> c_int; + fn rust_uv_tcp_getpeername(tcp_handle_ptr: *uv_tcp_t, + name: *sockaddr_in) -> c_int; + fn rust_uv_tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t, + name: *sockaddr_in6) ->c_int; fn rust_uv_listen(stream: *c_void, backlog: c_int, cb: *u8) -> c_int; fn rust_uv_accept(server: *c_void, client: *c_void) -> c_int; fn rust_uv_write(req: *c_void, stream: *c_void, - ++buf_in: *uv_buf_t, + buf_in: *uv_buf_t, buf_cnt: c_int, cb: *u8) -> c_int; fn rust_uv_read_start(stream: *c_void, @@ -426,7 +428,7 @@ extern { fn rust_uv_timer_stop(handle: *uv_timer_t) -> c_int; fn rust_uv_malloc_buf_base_of(sug_size: size_t) -> *u8; - fn rust_uv_free_base_of_buf(++buf: uv_buf_t); + fn rust_uv_free_base_of_buf(buf: uv_buf_t); fn rust_uv_get_stream_handle_from_connect_req(connect_req: *uv_connect_t) -> *uv_stream_t; fn rust_uv_get_stream_handle_from_write_req(write_req: *uv_write_t) -> *uv_stream_t; fn rust_uv_get_loop_for_uv_handle(handle: *c_void) -> *c_void; @@ -436,6 +438,6 @@ extern { fn rust_uv_set_data_for_uv_handle(handle: *c_void, data: *c_void); fn rust_uv_get_data_for_req(req: *c_void) -> *c_void; fn rust_uv_set_data_for_req(req: *c_void, data: *c_void); - fn rust_uv_get_base_from_buf(++buf: uv_buf_t) -> *u8; - fn rust_uv_get_len_from_buf(++buf: uv_buf_t) -> size_t; + fn rust_uv_get_base_from_buf(buf: uv_buf_t) -> *u8; + fn rust_uv_get_len_from_buf(buf: uv_buf_t) -> size_t; } diff --git a/src/libcore/stackwalk.rs b/src/libcore/stackwalk.rs index 24237694502..1958b5b9d80 100644 --- a/src/libcore/stackwalk.rs +++ b/src/libcore/stackwalk.rs @@ -81,6 +81,6 @@ fn frame_address(f: &fn(x: *u8)) { pub mod rusti { #[abi = "rust-intrinsic"] pub extern "rust-intrinsic" { - pub fn frame_address(+f: &once fn(x: *u8)); + pub fn frame_address(f: &once fn(x: *u8)); } } diff --git a/src/libcore/task/mod.rs b/src/libcore/task/mod.rs index fd695c16ea7..e58aa14572b 100644 --- a/src/libcore/task/mod.rs +++ b/src/libcore/task/mod.rs @@ -156,7 +156,7 @@ pub struct SchedOpts { pub struct TaskOpts { linked: bool, supervised: bool, - mut notify_chan: Option<Chan<TaskResult>>, + notify_chan: Option<Chan<TaskResult>>, sched: SchedOpts } @@ -176,9 +176,9 @@ pub struct TaskOpts { // FIXME (#3724): Replace the 'consumed' bit with move mode on self pub struct TaskBuilder { opts: TaskOpts, - mut gen_body: Option<~fn(v: ~fn()) -> ~fn()>, + gen_body: Option<~fn(v: ~fn()) -> ~fn()>, can_not_copy: Option<util::NonCopyable>, - mut consumed: bool, + consumed: bool, } /** @@ -191,13 +191,13 @@ pub fn task() -> TaskBuilder { opts: default_task_opts(), gen_body: None, can_not_copy: None, - mut consumed: false, + consumed: false, } } #[doc(hidden)] // FIXME #3538 priv impl TaskBuilder { - fn consume(&self) -> TaskBuilder { + fn consume(&mut self) -> TaskBuilder { if self.consumed { fail!(~"Cannot copy a task_builder"); // Fake move mode on self } @@ -219,57 +219,25 @@ priv impl TaskBuilder { } pub impl TaskBuilder { - /** - * Decouple the child task's failure from the parent's. If either fails, - * the other will not be killed. - */ - fn unlinked(&self) -> TaskBuilder { - let notify_chan = replace(&mut self.opts.notify_chan, None); - TaskBuilder { - opts: TaskOpts { - linked: false, - supervised: self.opts.supervised, - notify_chan: notify_chan, - sched: self.opts.sched - }, - can_not_copy: None, - .. self.consume() - } + /// Decouple the child task's failure from the parent's. If either fails, + /// the other will not be killed. + fn unlinked(&mut self) { + self.opts.linked = false; } - /** - * Unidirectionally link the child task's failure with the parent's. The - * child's failure will not kill the parent, but the parent's will kill - * the child. - */ - fn supervised(&self) -> TaskBuilder { - let notify_chan = replace(&mut self.opts.notify_chan, None); - TaskBuilder { - opts: TaskOpts { - linked: false, - supervised: true, - notify_chan: notify_chan, - sched: self.opts.sched - }, - can_not_copy: None, - .. self.consume() - } + + /// Unidirectionally link the child task's failure with the parent's. The + /// child's failure will not kill the parent, but the parent's will kill + /// the child. + fn supervised(&mut self) { + self.opts.supervised = true; + self.opts.linked = false; } - /** - * Link the child task's and parent task's failures. If either fails, the - * other will be killed. - */ - fn linked(&self) -> TaskBuilder { - let notify_chan = replace(&mut self.opts.notify_chan, None); - TaskBuilder { - opts: TaskOpts { - linked: true, - supervised: false, - notify_chan: notify_chan, - sched: self.opts.sched - }, - can_not_copy: None, - .. self.consume() - } + + /// Link the child task's and parent task's failures. If either fails, the + /// other will be killed. + fn linked(&mut self) { + self.opts.linked = true; + self.opts.supervised = false; } /** @@ -289,7 +257,7 @@ pub impl TaskBuilder { * # Failure * Fails if a future_result was already set for this task. */ - fn future_result(&self, blk: &fn(v: Port<TaskResult>)) -> TaskBuilder { + fn future_result(&mut self, blk: &fn(v: Port<TaskResult>)) { // FIXME (#3725): Once linked failure and notification are // handled in the library, I can imagine implementing this by just // registering an arbitrary number of task::on_exit handlers and @@ -305,30 +273,12 @@ pub impl TaskBuilder { blk(notify_pipe_po); // Reconfigure self to use a notify channel. - TaskBuilder { - opts: TaskOpts { - linked: self.opts.linked, - supervised: self.opts.supervised, - notify_chan: Some(notify_pipe_ch), - sched: self.opts.sched - }, - can_not_copy: None, - .. self.consume() - } + self.opts.notify_chan = Some(notify_pipe_ch); } + /// Configure a custom scheduler mode for the task. - fn sched_mode(&self, mode: SchedMode) -> TaskBuilder { - let notify_chan = replace(&mut self.opts.notify_chan, None); - TaskBuilder { - opts: TaskOpts { - linked: self.opts.linked, - supervised: self.opts.supervised, - notify_chan: notify_chan, - sched: SchedOpts { mode: mode, foreign_stack_size: None} - }, - can_not_copy: None, - .. self.consume() - } + fn sched_mode(&mut self, mode: SchedMode) { + self.opts.sched.mode = mode; } /** @@ -343,7 +293,7 @@ pub impl TaskBuilder { * generator by applying the task body which results from the * existing body generator to the new body generator. */ - fn add_wrapper(&self, wrapper: ~fn(v: ~fn()) -> ~fn()) -> TaskBuilder { + fn add_wrapper(&mut self, wrapper: ~fn(v: ~fn()) -> ~fn()) { let prev_gen_body = replace(&mut self.gen_body, None); let prev_gen_body = match prev_gen_body { Some(gen) => gen, @@ -360,18 +310,7 @@ pub impl TaskBuilder { }; f }; - let notify_chan = replace(&mut self.opts.notify_chan, None); - TaskBuilder { - opts: TaskOpts { - linked: self.opts.linked, - supervised: self.opts.supervised, - notify_chan: notify_chan, - sched: self.opts.sched - }, - gen_body: Some(next_gen_body), - can_not_copy: None, - .. self.consume() - } + self.gen_body = Some(next_gen_body); } /** @@ -386,7 +325,7 @@ pub impl TaskBuilder { * When spawning into a new scheduler, the number of threads requested * must be greater than zero. */ - fn spawn(&self, f: ~fn()) { + fn spawn(&mut self, f: ~fn()) { let gen_body = replace(&mut self.gen_body, None); let notify_chan = replace(&mut self.opts.notify_chan, None); let x = self.consume(); @@ -406,8 +345,9 @@ pub impl TaskBuilder { }; spawn::spawn_raw(opts, f); } + /// Runs a task, while transfering ownership of one argument to the child. - fn spawn_with<A:Owned>(&self, arg: A, f: ~fn(v: A)) { + fn spawn_with<A:Owned>(&mut self, arg: A, f: ~fn(v: A)) { let arg = Cell(arg); do self.spawn { f(arg.take()); @@ -427,16 +367,16 @@ pub impl TaskBuilder { * # Failure * Fails if a future_result was already set for this task. */ - fn try<T:Owned>(&self, f: ~fn() -> T) -> Result<T,()> { + fn try<T:Owned>(&mut self, f: ~fn() -> T) -> Result<T,()> { let (po, ch) = stream::<T>(); let mut result = None; - let fr_task_builder = self.future_result(|+r| { - result = Some(r); - }); - do fr_task_builder.spawn || { + self.future_result(|r| { result = Some(r); }); + + do self.spawn { ch.send(f()); } + match result.unwrap().recv() { Success => result::Ok(po.recv()), Failure => result::Err(()) @@ -468,26 +408,23 @@ pub fn default_task_opts() -> TaskOpts { /* Spawn convenience functions */ +/// Creates and executes a new child task +/// +/// Sets up a new task with its own call stack and schedules it to run +/// the provided unique closure. +/// +/// This function is equivalent to `task().spawn(f)`. pub fn spawn(f: ~fn()) { - /*! - * Creates and executes a new child task - * - * Sets up a new task with its own call stack and schedules it to run - * the provided unique closure. - * - * This function is equivalent to `task().spawn(f)`. - */ - - task().spawn(f) + let mut task = task(); + task.spawn(f) } +/// Creates a child task unlinked from the current one. If either this +/// task or the child task fails, the other will not be killed. pub fn spawn_unlinked(f: ~fn()) { - /*! - * Creates a child task unlinked from the current one. If either this - * task or the child task fails, the other will not be killed. - */ - - task().unlinked().spawn(f) + let mut task = task(); + task.unlinked(); + task.spawn(f) } pub fn spawn_supervised(f: ~fn()) { @@ -497,7 +434,9 @@ pub fn spawn_supervised(f: ~fn()) { * the child will be killed. */ - task().supervised().spawn(f) + let mut task = task(); + task.supervised(); + task.spawn(f) } pub fn spawn_with<A:Owned>(arg: A, f: ~fn(v: A)) { @@ -511,7 +450,8 @@ pub fn spawn_with<A:Owned>(arg: A, f: ~fn(v: A)) { * This function is equivalent to `task().spawn_with(arg, f)`. */ - task().spawn_with(arg, f) + let mut task = task(); + task.spawn_with(arg, f) } pub fn spawn_sched(mode: SchedMode, f: ~fn()) { @@ -527,7 +467,9 @@ pub fn spawn_sched(mode: SchedMode, f: ~fn()) { * greater than zero. */ - task().sched_mode(mode).spawn(f) + let mut task = task(); + task.sched_mode(mode); + task.spawn(f) } pub fn try<T:Owned>(f: ~fn() -> T) -> Result<T,()> { @@ -538,7 +480,9 @@ pub fn try<T:Owned>(f: ~fn() -> T) -> Result<T,()> { * This is equivalent to task().supervised().try. */ - task().supervised().try(f) + let mut task = task(); + task.supervised(); + task.try(f) } @@ -653,12 +597,13 @@ pub unsafe fn atomically<U>(f: &fn() -> U) -> U { #[test] #[should_fail] #[ignore(cfg(windows))] fn test_cant_dup_task_builder() { - let b = task().unlinked(); - do b.spawn { } + let mut builder = task(); + builder.unlinked(); + do builder.spawn {} // FIXME(#3724): For now, this is a -runtime- failure, because we haven't // got move mode on self. When 3724 is fixed, this test should fail to // compile instead, and should go in tests/compile-fail. - do b.spawn { } // b should have been consumed by the previous call + do builder.spawn {} // b should have been consumed by the previous call } // The following 8 tests test the following 2^3 combinations: @@ -701,43 +646,31 @@ fn test_spawn_unlinked_sup_fail_down() { #[test] #[should_fail] #[ignore(cfg(windows))] fn test_spawn_linked_sup_fail_up() { // child fails; parent fails let (po, _ch) = stream::<()>(); + // Unidirectional "parenting" shouldn't override bidirectional linked. // We have to cheat with opts - the interface doesn't support them because // they don't make sense (redundant with task().supervised()). - let opts = { - let mut opts = default_task_opts(); - opts.linked = true; - opts.supervised = true; - opts - }; + let mut b0 = task(); + b0.opts.linked = true; + b0.opts.supervised = true; - let b0 = task(); - let b1 = TaskBuilder { - opts: opts, - can_not_copy: None, - .. b0 - }; - do b1.spawn { fail!(); } + do b0.spawn { + fail!(); + } po.recv(); // We should get punted awake } #[test] #[should_fail] #[ignore(cfg(windows))] fn test_spawn_linked_sup_fail_down() { // parent fails; child fails // We have to cheat with opts - the interface doesn't support them because // they don't make sense (redundant with task().supervised()). - let opts = { - let mut opts = default_task_opts(); - opts.linked = true; - opts.supervised = true; - opts - }; - - let b0 = task(); - let b1 = TaskBuilder { - opts: opts, - can_not_copy: None, - .. b0 - }; - do b1.spawn { loop { task::yield(); } } + let mut b0 = task(); + b0.opts.linked = true; + b0.opts.supervised = true; + do b0.spawn { + loop { + task::yield(); + } + } fail!(); // *both* mechanisms would be wrong if this didn't kill the child } #[test] #[should_fail] #[ignore(cfg(windows))] @@ -756,7 +689,13 @@ fn test_spawn_linked_unsup_fail_down() { // parent fails; child fails #[test] #[should_fail] #[ignore(cfg(windows))] fn test_spawn_linked_unsup_default_opts() { // parent fails; child fails // Make sure the above test is the same as this one. - do task().linked().spawn { loop { task::yield(); } } + let mut builder = task(); + builder.linked(); + do builder.spawn { + loop { + task::yield(); + } + } fail!(); } @@ -814,7 +753,8 @@ fn test_spawn_linked_sup_propagate_sibling() { #[test] fn test_run_basic() { let (po, ch) = stream::<()>(); - do task().spawn { + let mut builder = task(); + do builder.spawn { ch.send(()); } po.recv(); @@ -822,24 +762,24 @@ fn test_run_basic() { #[cfg(test)] struct Wrapper { - mut f: Option<Chan<()>> + f: Option<Chan<()>> } #[test] fn test_add_wrapper() { let (po, ch) = stream::<()>(); - let b0 = task(); - let ch = Wrapper { f: Some(ch) }; - let b1 = do b0.add_wrapper |body| { - let ch = Wrapper { f: Some(ch.f.swap_unwrap()) }; + let mut b0 = task(); + let ch = Cell(ch); + do b0.add_wrapper |body| { + let ch = Cell(ch.take()); let result: ~fn() = || { - let ch = ch.f.swap_unwrap(); + let mut ch = ch.take(); body(); ch.send(()); }; result }; - do b1.spawn { } + do b0.spawn { } po.recv(); } @@ -847,12 +787,16 @@ fn test_add_wrapper() { #[ignore(cfg(windows))] fn test_future_result() { let mut result = None; - do task().future_result(|+r| { result = Some(r); }).spawn { } + let mut builder = task(); + builder.future_result(|r| result = Some(r)); + do builder.spawn {} assert!(result.unwrap().recv() == Success); result = None; - do task().future_result(|+r| - { result = Some(r); }).unlinked().spawn { + let mut builder = task(); + builder.future_result(|r| result = Some(r)); + builder.unlinked(); + do builder.spawn { fail!(); } assert!(result.unwrap().recv() == Failure); @@ -860,7 +804,9 @@ fn test_future_result() { #[test] #[should_fail] #[ignore(cfg(windows))] fn test_back_to_the_future_result() { - let _ = task().future_result(util::ignore).future_result(util::ignore); + let mut builder = task(); + builder.future_result(util::ignore); + builder.future_result(util::ignore); } #[test] @@ -922,12 +868,12 @@ fn test_spawn_sched_childs_on_default_sched() { // Assuming tests run on the default scheduler let default_id = unsafe { rt::rust_get_sched_id() }; - let ch = Wrapper { f: Some(ch) }; + let ch = Cell(ch); do spawn_sched(SingleThreaded) { let parent_sched_id = unsafe { rt::rust_get_sched_id() }; - let ch = Wrapper { f: Some(ch.f.swap_unwrap()) }; + let ch = Cell(ch.take()); do spawn { - let ch = ch.f.swap_unwrap(); + let ch = ch.take(); let child_sched_id = unsafe { rt::rust_get_sched_id() }; assert!(parent_sched_id != child_sched_id); assert!(child_sched_id == default_id); @@ -1035,7 +981,8 @@ fn test_avoid_copying_the_body_spawn() { #[test] fn test_avoid_copying_the_body_task_spawn() { do avoid_copying_the_body |f| { - do task().spawn || { + let mut builder = task(); + do builder.spawn || { f(); } } @@ -1062,7 +1009,9 @@ fn test_avoid_copying_the_body_unlinked() { #[test] fn test_platform_thread() { let (po, ch) = stream(); - do task().sched_mode(PlatformThread).spawn { + let mut builder = task(); + builder.sched_mode(PlatformThread); + do builder.spawn { ch.send(()); } po.recv(); diff --git a/src/libcore/task/spawn.rs b/src/libcore/task/spawn.rs index 267250b3642..19c417dfdfc 100644 --- a/src/libcore/task/spawn.rs +++ b/src/libcore/task/spawn.rs @@ -72,6 +72,7 @@ #[doc(hidden)]; // FIXME #3538 +use cast::transmute; use cast; use cell::Cell; use container::Map; @@ -117,10 +118,10 @@ pub fn taskset_each(tasks: &TaskSet, blk: &fn(v: *rust_task) -> bool) { struct TaskGroupData { // All tasks which might kill this group. When this is empty, the group // can be "GC"ed (i.e., its link in the ancestor list can be removed). - mut members: TaskSet, + members: TaskSet, // All tasks unidirectionally supervised by (directly or transitively) // tasks in this group. - mut descendants: TaskSet, + descendants: TaskSet, } type TaskGroupArc = unstable::Exclusive<Option<TaskGroupData>>; @@ -145,11 +146,11 @@ struct AncestorNode { // Hence we assert that this counter monotonically decreases as we // approach the tail of the list. // FIXME(#3068): Make the generation counter togglable with #[cfg(debug)]. - generation: uint, - // Should really be an immutable non-option. This way appeases borrowck. - mut parent_group: Option<TaskGroupArc>, + generation: uint, + // Should really be a non-option. This way appeases borrowck. + parent_group: Option<TaskGroupArc>, // Recursive rest of the list. - mut ancestors: AncestorList, + ancestors: AncestorList, } struct AncestorList(Option<unstable::Exclusive<AncestorNode>>); @@ -301,22 +302,26 @@ fn each_ancestor(list: &mut AncestorList, // One of these per task. struct TCB { - me: *rust_task, + me: *rust_task, // List of tasks with whose fates this one's is intertwined. - tasks: TaskGroupArc, // 'none' means the group has failed. + tasks: TaskGroupArc, // 'none' means the group has failed. // Lists of tasks who will kill us if they fail, but whom we won't kill. - mut ancestors: AncestorList, - is_main: bool, - notifier: Option<AutoNotify>, + ancestors: AncestorList, + is_main: bool, + notifier: Option<AutoNotify>, } impl Drop for TCB { // Runs on task exit. fn finalize(&self) { unsafe { + let this: &mut TCB = transmute(self); + // If we are failing, the whole taskgroup needs to die. if rt::rust_task_is_unwinding(self.me) { - for self.notifier.each |x| { x.failed = true; } + for this.notifier.each_mut |x| { + x.failed = true; + } // Take everybody down with us. do access_group(&self.tasks) |tg| { kill_taskgroup(tg, self.me, self.is_main); @@ -331,16 +336,21 @@ impl Drop for TCB { // with our own taskgroup, so long as both happen before we die. // We remove ourself from every ancestor we can, so no cleanup; no // break. - for each_ancestor(&mut self.ancestors, None) |ancestor_group| { + for each_ancestor(&mut this.ancestors, None) |ancestor_group| { leave_taskgroup(ancestor_group, self.me, false); }; } } } -fn TCB(me: *rust_task, tasks: TaskGroupArc, ancestors: AncestorList, - is_main: bool, notifier: Option<AutoNotify>) -> TCB { - for notifier.each |x| { x.failed = false; } +fn TCB(me: *rust_task, + tasks: TaskGroupArc, + ancestors: AncestorList, + is_main: bool, + mut notifier: Option<AutoNotify>) -> TCB { + for notifier.each_mut |x| { + x.failed = false; + } TCB { me: me, @@ -353,7 +363,7 @@ fn TCB(me: *rust_task, tasks: TaskGroupArc, ancestors: AncestorList, struct AutoNotify { notify_chan: Chan<TaskResult>, - mut failed: bool, + failed: bool, } impl Drop for AutoNotify { @@ -375,9 +385,12 @@ fn enlist_in_taskgroup(state: TaskGroupInner, me: *rust_task, let newstate = util::replace(&mut *state, None); // If 'None', the group was failing. Can't enlist. if newstate.is_some() { - let group = newstate.unwrap(); - taskset_insert(if is_member { &mut group.members } - else { &mut group.descendants }, me); + let mut group = newstate.unwrap(); + taskset_insert(if is_member { + &mut group.members + } else { + &mut group.descendants + }, me); *state = Some(group); true } else { @@ -391,9 +404,12 @@ fn leave_taskgroup(state: TaskGroupInner, me: *rust_task, let newstate = util::replace(&mut *state, None); // If 'None', already failing and we've already gotten a kill signal. if newstate.is_some() { - let group = newstate.unwrap(); - taskset_remove(if is_member { &mut group.members } - else { &mut group.descendants }, me); + let mut group = newstate.unwrap(); + taskset_remove(if is_member { + &mut group.members + } else { + &mut group.descendants + }, me); *state = Some(group); } } @@ -451,23 +467,30 @@ fn gen_child_taskgroup(linked: bool, supervised: bool) /*##################################################################* * Step 1. Get spawner's taskgroup info. *##################################################################*/ - let spawner_group = match local_get(OldHandle(spawner), taskgroup_key!()) { - None => { - // Main task, doing first spawn ever. Lazily initialise here. - let mut members = new_taskset(); - taskset_insert(&mut members, spawner); - let tasks = unstable::exclusive(Some(TaskGroupData { - members: members, - descendants: new_taskset(), - })); - // Main task/group has no ancestors, no notifier, etc. - let group = - @TCB(spawner, tasks, AncestorList(None), true, None); - local_set(OldHandle(spawner), taskgroup_key!(), group); - group - } - Some(group) => group - }; + let mut spawner_group: @@mut TCB = + match local_get(OldHandle(spawner), taskgroup_key!()) { + None => { + // Main task, doing first spawn ever. Lazily initialise + // here. + let mut members = new_taskset(); + taskset_insert(&mut members, spawner); + let tasks = unstable::exclusive(Some(TaskGroupData { + members: members, + descendants: new_taskset(), + })); + // Main task/group has no ancestors, no notifier, etc. + let group = @@mut TCB(spawner, + tasks, + AncestorList(None), + true, + None); + local_set(OldHandle(spawner), taskgroup_key!(), group); + group + } + Some(group) => group + }; + let spawner_group: &mut TCB = *spawner_group; + /*##################################################################* * Step 2. Process spawn options for child. *##################################################################*/ @@ -557,7 +580,7 @@ fn spawn_raw_newsched(_opts: TaskOpts, f: ~fn()) { sched.schedule_new_task(task); } -fn spawn_raw_oldsched(opts: TaskOpts, f: ~fn()) { +fn spawn_raw_oldsched(mut opts: TaskOpts, f: ~fn()) { let (child_tg, ancestors, is_main) = gen_child_taskgroup(opts.linked, opts.supervised); @@ -624,8 +647,11 @@ fn spawn_raw_oldsched(opts: TaskOpts, f: ~fn()) { }; if enlist_many(child, &child_arc, &mut ancestors) { - let group = @TCB(child, child_arc, ancestors, - is_main, notifier); + let group = @@mut TCB(child, + child_arc, + ancestors, + is_main, + notifier); unsafe { local_set(OldHandle(child), taskgroup_key!(), group); } diff --git a/src/libcore/unstable.rs b/src/libcore/unstable.rs index 0b96e649178..7f42507bfd5 100644 --- a/src/libcore/unstable.rs +++ b/src/libcore/unstable.rs @@ -235,17 +235,30 @@ pub impl LittleLock { } } -struct ExData<T> { lock: LittleLock, failed: bool, data: T, } +struct ExData<T> { + lock: LittleLock, + failed: bool, + data: T, +} + /** * An arc over mutable data that is protected by a lock. For library use only. */ -pub struct Exclusive<T> { x: SharedMutableState<ExData<T>> } +pub struct Exclusive<T> { + x: SharedMutableState<ExData<T>> +} pub fn exclusive<T:Owned>(user_data: T) -> Exclusive<T> { let data = ExData { - lock: LittleLock(), failed: false, data: user_data + lock: LittleLock(), + failed: false, + data: user_data }; - Exclusive { x: unsafe { shared_mutable_state(data) } } + Exclusive { + x: unsafe { + shared_mutable_state(data) + } + } } impl<T:Owned> Clone for Exclusive<T> { diff --git a/src/libcore/unstable/at_exit.rs b/src/libcore/unstable/at_exit.rs index bc4ec620aa8..39c930d415f 100644 --- a/src/libcore/unstable/at_exit.rs +++ b/src/libcore/unstable/at_exit.rs @@ -62,14 +62,17 @@ fn exit_runner(exit_fns: *ExitFunctions) { // give us ownership of the array of functions let mut exit_fns_vec = unsafe { vec::from_buf(start, count as uint) }; // Let's not make any promises about execution order - rand::rng().shuffle_mut(exit_fns_vec); + let mut rng = rand::rng(); + rng.shuffle_mut(exit_fns_vec); debug!("running %u exit functions", exit_fns_vec.len()); while !exit_fns_vec.is_empty() { match exit_fns_vec.pop() { ~f => { - task::task().supervised().spawn(f); + let mut task = task::task(); + task.supervised(); + task.spawn(f); } } } diff --git a/src/libcore/unstable/intrinsics.rs b/src/libcore/unstable/intrinsics.rs index 65cfc6ec1fe..363dbb84c1c 100644 --- a/src/libcore/unstable/intrinsics.rs +++ b/src/libcore/unstable/intrinsics.rs @@ -34,8 +34,8 @@ pub extern "rust-intrinsic" { pub fn size_of<T>() -> uint; - pub fn move_val<T>(dst: &mut T, +src: T); - pub fn move_val_init<T>(dst: &mut T, +src: T); + pub fn move_val<T>(dst: &mut T, src: T); + pub fn move_val_init<T>(dst: &mut T, src: T); pub fn min_align_of<T>() -> uint; pub fn pref_align_of<T>() -> uint; diff --git a/src/libcore/unstable/weak_task.rs b/src/libcore/unstable/weak_task.rs index 6edbdcb51b0..8670bcfcd9a 100644 --- a/src/libcore/unstable/weak_task.rs +++ b/src/libcore/unstable/weak_task.rs @@ -72,7 +72,9 @@ fn create_global_service() -> ~WeakTaskService { let chan = SharedChan::new(chan); let chan_clone = chan.clone(); - do task().unlinked().spawn { + let mut task = task(); + task.unlinked(); + do task.spawn { debug!("running global weak task service"); let port = Cell(port.take()); do (|| { @@ -189,12 +191,14 @@ fn test_select_stream_and_oneshot() { use comm::select2i; use either::{Left, Right}; - let (port, chan) = stream(); + let mut (port, chan) = stream(); + let port = Cell(port); let (waitport, waitchan) = stream(); do spawn { unsafe { - do weaken_task |signal| { - match select2i(&port, &signal) { + do weaken_task |mut signal| { + let mut port = port.take(); + match select2i(&mut port, &mut signal) { Left(*) => (), Right(*) => fail!() } diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index 947146dee0e..36acbdf4b56 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -42,13 +42,13 @@ pub mod rustrt { // These names are terrible. reserve_shared applies // to ~[] and reserve_shared_actual applies to @[]. #[fast_ffi] - unsafe fn vec_reserve_shared(++t: *sys::TypeDesc, - ++v: **raw::VecRepr, - ++n: libc::size_t); + unsafe fn vec_reserve_shared(t: *sys::TypeDesc, + v: **raw::VecRepr, + n: libc::size_t); #[fast_ffi] - unsafe fn vec_reserve_shared_actual(++t: *sys::TypeDesc, - ++v: **raw::VecRepr, - ++n: libc::size_t); + unsafe fn vec_reserve_shared_actual(t: *sys::TypeDesc, + v: **raw::VecRepr, + n: libc::size_t); } } |
