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
This commit is contained in:
commit
d82d9874a6
164 changed files with 1596 additions and 1338 deletions
|
@ -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) };
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 = ~[];
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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!()
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -263,7 +263,7 @@ pub fn under(n: uint, it: &fn(uint)) {
|
|||
while i < n { it(i); i += 1u; }
|
||||
}
|
||||
|
||||
pub fn as_str(f: @fn(+x: @io::Writer)) -> ~str {
|
||||
pub fn as_str(f: @fn(x: @io::Writer)) -> ~str {
|
||||
io::with_str_writer(f)
|
||||
}
|
||||
|
||||
|
|
|
@ -22,9 +22,9 @@ use util::ppaux;
|
|||
|
||||
use core::hash::Streaming;
|
||||
use core::hash;
|
||||
use core::io::WriterUtil;
|
||||
use core::libc::{c_int, c_uint};
|
||||
use core::os::consts::{macos, freebsd, linux, android, win32};
|
||||
use core::rt::io::Writer;
|
||||
use core::run;
|
||||
use syntax::ast;
|
||||
use syntax::ast_map::{path, path_mod, path_name};
|
||||
|
@ -41,6 +41,11 @@ pub enum output_type {
|
|||
output_type_exe,
|
||||
}
|
||||
|
||||
fn write_string<W:Writer>(writer: &mut W, string: &str) {
|
||||
let buffer = str::as_bytes_slice(string);
|
||||
writer.write(buffer);
|
||||
}
|
||||
|
||||
pub fn llvm_err(sess: Session, msg: ~str) -> ! {
|
||||
unsafe {
|
||||
let cstr = llvm::LLVMRustGetLastError();
|
||||
|
@ -458,9 +463,11 @@ pub mod write {
|
|||
*
|
||||
*/
|
||||
|
||||
pub fn build_link_meta(sess: Session, c: &ast::crate, output: &Path,
|
||||
symbol_hasher: &hash::State) -> LinkMeta {
|
||||
|
||||
pub fn build_link_meta(sess: Session,
|
||||
c: &ast::crate,
|
||||
output: &Path,
|
||||
symbol_hasher: &mut hash::State)
|
||||
-> LinkMeta {
|
||||
struct ProvidedMetas {
|
||||
name: Option<@str>,
|
||||
vers: Option<@str>,
|
||||
|
@ -498,7 +505,7 @@ pub fn build_link_meta(sess: Session, c: &ast::crate, output: &Path,
|
|||
}
|
||||
|
||||
// This calculates CMH as defined above
|
||||
fn crate_meta_extras_hash(symbol_hasher: &hash::State,
|
||||
fn crate_meta_extras_hash(symbol_hasher: &mut hash::State,
|
||||
cmh_items: ~[@ast::meta_item],
|
||||
dep_hashes: ~[~str]) -> @str {
|
||||
fn len_and_str(s: &str) -> ~str {
|
||||
|
@ -511,17 +518,17 @@ pub fn build_link_meta(sess: Session, c: &ast::crate, output: &Path,
|
|||
|
||||
let cmh_items = attr::sort_meta_items(cmh_items);
|
||||
|
||||
fn hash(symbol_hasher: &hash::State, m: &@ast::meta_item) {
|
||||
fn hash(symbol_hasher: &mut hash::State, m: &@ast::meta_item) {
|
||||
match m.node {
|
||||
ast::meta_name_value(key, value) => {
|
||||
symbol_hasher.write_str(len_and_str(*key));
|
||||
symbol_hasher.write_str(len_and_str_lit(value));
|
||||
write_string(symbol_hasher, len_and_str(*key));
|
||||
write_string(symbol_hasher, len_and_str_lit(value));
|
||||
}
|
||||
ast::meta_word(name) => {
|
||||
symbol_hasher.write_str(len_and_str(*name));
|
||||
write_string(symbol_hasher, len_and_str(*name));
|
||||
}
|
||||
ast::meta_list(name, ref mis) => {
|
||||
symbol_hasher.write_str(len_and_str(*name));
|
||||
write_string(symbol_hasher, len_and_str(*name));
|
||||
for mis.each |m_| {
|
||||
hash(symbol_hasher, m_);
|
||||
}
|
||||
|
@ -535,7 +542,7 @@ pub fn build_link_meta(sess: Session, c: &ast::crate, output: &Path,
|
|||
}
|
||||
|
||||
for dep_hashes.each |dh| {
|
||||
symbol_hasher.write_str(len_and_str(*dh));
|
||||
write_string(symbol_hasher, len_and_str(*dh));
|
||||
}
|
||||
|
||||
// tjc: allocation is unfortunate; need to change core::hash
|
||||
|
@ -596,23 +603,26 @@ pub fn build_link_meta(sess: Session, c: &ast::crate, output: &Path,
|
|||
}
|
||||
}
|
||||
|
||||
pub fn truncated_hash_result(symbol_hasher: &hash::State) -> ~str {
|
||||
pub fn truncated_hash_result(symbol_hasher: &mut hash::State) -> ~str {
|
||||
symbol_hasher.result_str()
|
||||
}
|
||||
|
||||
|
||||
// This calculates STH for a symbol, as defined above
|
||||
pub fn symbol_hash(tcx: ty::ctxt, symbol_hasher: &hash::State, t: ty::t,
|
||||
link_meta: LinkMeta) -> @str {
|
||||
pub fn symbol_hash(tcx: ty::ctxt,
|
||||
symbol_hasher: &mut hash::State,
|
||||
t: ty::t,
|
||||
link_meta: LinkMeta)
|
||||
-> @str {
|
||||
// NB: do *not* use abbrevs here as we want the symbol names
|
||||
// to be independent of one another in the crate.
|
||||
|
||||
symbol_hasher.reset();
|
||||
symbol_hasher.write_str(link_meta.name);
|
||||
symbol_hasher.write_str(~"-");
|
||||
symbol_hasher.write_str(link_meta.extras_hash);
|
||||
symbol_hasher.write_str(~"-");
|
||||
symbol_hasher.write_str(encoder::encoded_ty(tcx, t));
|
||||
write_string(symbol_hasher, link_meta.name);
|
||||
write_string(symbol_hasher, ~"-");
|
||||
write_string(symbol_hasher, link_meta.extras_hash);
|
||||
write_string(symbol_hasher, ~"-");
|
||||
write_string(symbol_hasher, encoder::encoded_ty(tcx, t));
|
||||
let mut hash = truncated_hash_result(symbol_hasher);
|
||||
// Prefix with _ so that it never blends into adjacent digits
|
||||
str::unshift_char(&mut hash, '_');
|
||||
|
|
|
@ -34,9 +34,9 @@ pub fn declare_upcalls(targ_cfg: @session::config,
|
|||
fn nothrow(f: ValueRef) -> ValueRef {
|
||||
base::set_no_unwind(f); f
|
||||
}
|
||||
let d: &fn(+a: ~str, +b: ~[TypeRef], +c: TypeRef) -> ValueRef =
|
||||
let d: &fn(a: ~str, b: ~[TypeRef], c: TypeRef) -> ValueRef =
|
||||
|a,b,c| decl(llmod, ~"upcall_", a, b, c);
|
||||
let dv: &fn(+a: ~str, +b: ~[TypeRef]) -> ValueRef =
|
||||
let dv: &fn(a: ~str, b: ~[TypeRef]) -> ValueRef =
|
||||
|a,b| decl(llmod, ~"upcall_", a, b, T_void());
|
||||
|
||||
let int_t = T_int(targ_cfg);
|
||||
|
|
|
@ -132,7 +132,7 @@ pub mod intrinsic {
|
|||
#[abi = "rust-intrinsic"]
|
||||
pub extern "rust-intrinsic" {
|
||||
pub fn get_tydesc<T>() -> *();
|
||||
pub fn visit_tydesc(++td: *TyDesc, ++tv: @TyVisitor);
|
||||
pub fn visit_tydesc(td: *TyDesc, tv: @TyVisitor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1561,12 +1561,18 @@ pub mod llvm {
|
|||
Name: *c_char) -> ValueRef;
|
||||
|
||||
/* Atomic Operations */
|
||||
pub unsafe fn LLVMBuildAtomicCmpXchg(B: BuilderRef, LHS: ValueRef,
|
||||
CMP: ValueRef, RHS: ValueRef,
|
||||
++Order: AtomicOrdering) -> ValueRef;
|
||||
pub unsafe fn LLVMBuildAtomicRMW(B: BuilderRef, ++Op: AtomicBinOp,
|
||||
LHS: ValueRef, RHS: ValueRef,
|
||||
++Order: AtomicOrdering) -> ValueRef;
|
||||
pub unsafe fn LLVMBuildAtomicCmpXchg(B: BuilderRef,
|
||||
LHS: ValueRef,
|
||||
CMP: ValueRef,
|
||||
RHS: ValueRef,
|
||||
Order: AtomicOrdering)
|
||||
-> ValueRef;
|
||||
pub unsafe fn LLVMBuildAtomicRMW(B: BuilderRef,
|
||||
Op: AtomicBinOp,
|
||||
LHS: ValueRef,
|
||||
RHS: ValueRef,
|
||||
Order: AtomicOrdering)
|
||||
-> ValueRef;
|
||||
|
||||
/* Selected entries from the downcasts. */
|
||||
#[fast_ffi]
|
||||
|
|
|
@ -204,18 +204,6 @@ fn each_reexport(d: ebml::Doc, f: &fn(ebml::Doc) -> bool) {
|
|||
}
|
||||
}
|
||||
|
||||
fn field_mutability(d: ebml::Doc) -> ast::struct_mutability {
|
||||
// Use maybe_get_doc in case it's a method
|
||||
reader::maybe_get_doc(d, tag_struct_mut).map_default(
|
||||
ast::struct_immutable,
|
||||
|d| {
|
||||
match reader::doc_as_u8(*d) as char {
|
||||
'm' => ast::struct_mutable,
|
||||
_ => ast::struct_immutable
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn variant_disr_val(d: ebml::Doc) -> Option<int> {
|
||||
do reader::maybe_get_doc(d, tag_disr_val).chain |val_doc| {
|
||||
int::parse_bytes(reader::doc_data(val_doc), 10u)
|
||||
|
@ -923,12 +911,10 @@ pub fn get_struct_fields(intr: @ident_interner, cdata: cmd, id: ast::node_id)
|
|||
if f == PublicField || f == PrivateField || f == InheritedField {
|
||||
let name = item_name(intr, an_item);
|
||||
let did = item_def_id(an_item, cdata);
|
||||
let mt = field_mutability(an_item);
|
||||
result.push(ty::field_ty {
|
||||
ident: name,
|
||||
id: did, vis:
|
||||
struct_field_family_to_visibility(f),
|
||||
mutability: mt,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -938,7 +924,6 @@ pub fn get_struct_fields(intr: @ident_interner, cdata: cmd, id: ast::node_id)
|
|||
ident: special_idents::unnamed_field,
|
||||
id: did,
|
||||
vis: ast::inherited,
|
||||
mutability: ast::struct_immutable,
|
||||
});
|
||||
}
|
||||
result
|
||||
|
|
|
@ -119,16 +119,6 @@ fn encode_region_param(ecx: @EncodeContext,
|
|||
}
|
||||
}
|
||||
|
||||
fn encode_mutability(ebml_w: &mut writer::Encoder, mt: struct_mutability) {
|
||||
ebml_w.start_tag(tag_struct_mut);
|
||||
let val = match mt {
|
||||
struct_immutable => 'a',
|
||||
struct_mutable => 'm'
|
||||
};
|
||||
ebml_w.writer.write(&[val as u8]);
|
||||
ebml_w.end_tag();
|
||||
}
|
||||
|
||||
struct entry<T> {
|
||||
val: T,
|
||||
pos: uint
|
||||
|
@ -518,13 +508,9 @@ fn encode_info_for_struct(ecx: @EncodeContext,
|
|||
/* We encode both private and public fields -- need to include
|
||||
private fields to get the offsets right */
|
||||
for fields.each |field| {
|
||||
let (nm, mt, vis) = match field.node.kind {
|
||||
named_field(nm, mt, vis) => (nm, mt, vis),
|
||||
unnamed_field => (
|
||||
special_idents::unnamed_field,
|
||||
struct_immutable,
|
||||
inherited
|
||||
)
|
||||
let (nm, vis) = match field.node.kind {
|
||||
named_field(nm, vis) => (nm, vis),
|
||||
unnamed_field => (special_idents::unnamed_field, inherited)
|
||||
};
|
||||
|
||||
let id = field.node.id;
|
||||
|
@ -537,7 +523,6 @@ fn encode_info_for_struct(ecx: @EncodeContext,
|
|||
encode_name(ecx, ebml_w, nm);
|
||||
encode_path(ecx, ebml_w, path, ast_map::path_name(nm));
|
||||
encode_type(ecx, ebml_w, node_id_to_type(tcx, id));
|
||||
encode_mutability(ebml_w, mt);
|
||||
encode_def_id(ebml_w, local_def(id));
|
||||
ebml_w.end_tag();
|
||||
}
|
||||
|
@ -828,7 +813,7 @@ fn encode_info_for_item(ecx: @EncodeContext,
|
|||
needs to know*/
|
||||
for struct_def.fields.each |f| {
|
||||
match f.node.kind {
|
||||
named_field(ident, _, vis) => {
|
||||
named_field(ident, vis) => {
|
||||
ebml_w.start_tag(tag_item_field);
|
||||
encode_struct_field_family(ebml_w, vis);
|
||||
encode_name(ecx, ebml_w, ident);
|
||||
|
@ -1372,41 +1357,40 @@ pub fn encode_metadata(parms: EncodeParams, crate: &crate) -> ~[u8] {
|
|||
|
||||
encode_hash(&mut ebml_w, ecx.link_meta.extras_hash);
|
||||
|
||||
let mut i = wr.pos;
|
||||
let mut i = *wr.pos;
|
||||
let crate_attrs = synthesize_crate_attrs(ecx, crate);
|
||||
encode_attributes(&mut ebml_w, crate_attrs);
|
||||
ecx.stats.attr_bytes = wr.pos - i;
|
||||
ecx.stats.attr_bytes = *wr.pos - i;
|
||||
|
||||
i = wr.pos;
|
||||
i = *wr.pos;
|
||||
encode_crate_deps(ecx, &mut ebml_w, ecx.cstore);
|
||||
ecx.stats.dep_bytes = wr.pos - i;
|
||||
ecx.stats.dep_bytes = *wr.pos - i;
|
||||
|
||||
// Encode the language items.
|
||||
i = wr.pos;
|
||||
i = *wr.pos;
|
||||
encode_lang_items(ecx, &mut ebml_w);
|
||||
ecx.stats.lang_item_bytes = wr.pos - i;
|
||||
ecx.stats.lang_item_bytes = *wr.pos - i;
|
||||
|
||||
// Encode the link args.
|
||||
i = wr.pos;
|
||||
i = *wr.pos;
|
||||
encode_link_args(ecx, &mut ebml_w);
|
||||
ecx.stats.link_args_bytes = wr.pos - i;
|
||||
ecx.stats.link_args_bytes = *wr.pos - i;
|
||||
|
||||
// Encode and index the items.
|
||||
ebml_w.start_tag(tag_items);
|
||||
i = wr.pos;
|
||||
i = *wr.pos;
|
||||
let items_index = encode_info_for_items(ecx, &mut ebml_w, crate);
|
||||
ecx.stats.item_bytes = wr.pos - i;
|
||||
ecx.stats.item_bytes = *wr.pos - i;
|
||||
|
||||
i = wr.pos;
|
||||
i = *wr.pos;
|
||||
let items_buckets = create_index(items_index);
|
||||
encode_index(&mut ebml_w, items_buckets, write_int);
|
||||
ecx.stats.index_bytes = wr.pos - i;
|
||||
ecx.stats.index_bytes = *wr.pos - i;
|
||||
ebml_w.end_tag();
|
||||
|
||||
ecx.stats.total_bytes = wr.pos;
|
||||
ecx.stats.total_bytes = *wr.pos;
|
||||
|
||||
if (tcx.sess.meta_stats()) {
|
||||
|
||||
do wr.bytes.each |e| {
|
||||
if *e == 0 {
|
||||
ecx.stats.zero_bytes += 1;
|
||||
|
@ -1438,9 +1422,11 @@ pub fn encode_metadata(parms: EncodeParams, crate: &crate) -> ~[u8] {
|
|||
//
|
||||
// vec::from_slice(metadata_encoding_version) +
|
||||
|
||||
let writer_bytes: &mut ~[u8] = wr.bytes;
|
||||
|
||||
(do str::as_bytes(&~"rust\x00\x00\x00\x01") |bytes| {
|
||||
vec::slice(*bytes, 0, 8).to_vec()
|
||||
}) + flate::deflate_bytes(wr.bytes)
|
||||
}) + flate::deflate_bytes(*writer_bytes)
|
||||
}
|
||||
|
||||
// Get the encoded string for a type
|
||||
|
|
|
@ -1237,7 +1237,7 @@ fn test_simplification() {
|
|||
let ext_cx = mk_ctxt();
|
||||
let item_in = ast::ii_item(quote_item!(
|
||||
fn new_int_alist<B:Copy>() -> alist<int, B> {
|
||||
fn eq_int(&&a: int, &&b: int) -> bool { a == b }
|
||||
fn eq_int(a: int, b: int) -> bool { a == b }
|
||||
return alist {eq_fn: eq_int, data: ~[]};
|
||||
}
|
||||
).get());
|
||||
|
|
|
@ -56,7 +56,6 @@ pub enum lint {
|
|||
non_camel_case_types,
|
||||
type_limits,
|
||||
default_methods,
|
||||
deprecated_mutable_fields,
|
||||
unused_unsafe,
|
||||
|
||||
managed_heap_memory,
|
||||
|
@ -197,13 +196,6 @@ static lint_table: &'static [(&'static str, LintSpec)] = &[
|
|||
default: deny
|
||||
}),
|
||||
|
||||
("deprecated_mutable_fields",
|
||||
LintSpec {
|
||||
lint: deprecated_mutable_fields,
|
||||
desc: "deprecated mutable fields in structures",
|
||||
default: deny
|
||||
}),
|
||||
|
||||
("unused_unsafe",
|
||||
LintSpec {
|
||||
lint: unused_unsafe,
|
||||
|
@ -455,7 +447,6 @@ fn check_item(i: @ast::item, cx: ty::ctxt) {
|
|||
check_item_heap(cx, i);
|
||||
check_item_type_limits(cx, i);
|
||||
check_item_default_methods(cx, i);
|
||||
check_item_deprecated_mutable_fields(cx, i);
|
||||
check_item_unused_unsafe(cx, i);
|
||||
check_item_unused_mut(cx, i);
|
||||
}
|
||||
|
@ -640,28 +631,7 @@ fn check_item_default_methods(cx: ty::ctxt, item: @ast::item) {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_item_deprecated_mutable_fields(cx: ty::ctxt, item: @ast::item) {
|
||||
match item.node {
|
||||
ast::item_struct(struct_def, _) => {
|
||||
for struct_def.fields.each |field| {
|
||||
match field.node.kind {
|
||||
ast::named_field(_, ast::struct_mutable, _) => {
|
||||
cx.sess.span_lint(deprecated_mutable_fields,
|
||||
item.id,
|
||||
item.id,
|
||||
field.span,
|
||||
"mutable fields are deprecated");
|
||||
}
|
||||
ast::named_field(*) | ast::unnamed_field => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_item_ctypes(cx: ty::ctxt, it: @ast::item) {
|
||||
|
||||
fn check_foreign_fn(cx: ty::ctxt, fn_id: ast::node_id,
|
||||
decl: &ast::fn_decl) {
|
||||
let tys = vec::map(decl.inputs, |a| a.ty );
|
||||
|
|
|
@ -581,17 +581,7 @@ pub impl mem_categorization_ctxt {
|
|||
f_name: ast::ident,
|
||||
f_ty: ty::t,
|
||||
field_id: ast::node_id) -> cmt {
|
||||
let f_mutbl = match field_mutbl(self.tcx, base_cmt.ty,
|
||||
f_name, field_id) {
|
||||
Some(f_mutbl) => f_mutbl,
|
||||
None => {
|
||||
self.tcx.sess.span_bug(
|
||||
node.span(),
|
||||
fmt!("Cannot find field `%s` in type `%s`",
|
||||
*self.tcx.sess.str_of(f_name),
|
||||
ty_to_str(self.tcx, base_cmt.ty)));
|
||||
}
|
||||
};
|
||||
let f_mutbl = m_imm;
|
||||
let m = self.inherited_mutability(base_cmt.mutbl, f_mutbl);
|
||||
let f_interior = interior_field(f_name, f_mutbl);
|
||||
@cmt_ {
|
||||
|
@ -968,11 +958,7 @@ pub fn field_mutbl(tcx: ty::ctxt,
|
|||
ty::ty_struct(did, _) => {
|
||||
for ty::lookup_struct_fields(tcx, did).each |fld| {
|
||||
if fld.ident == f_name {
|
||||
let m = match fld.mutability {
|
||||
ast::struct_mutable => ast::m_mutbl,
|
||||
ast::struct_immutable => ast::m_imm
|
||||
};
|
||||
return Some(m);
|
||||
return Some(ast::m_imm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -981,11 +967,7 @@ pub fn field_mutbl(tcx: ty::ctxt,
|
|||
ast::def_variant(_, variant_id) => {
|
||||
for ty::lookup_struct_fields(tcx, variant_id).each |fld| {
|
||||
if fld.ident == f_name {
|
||||
let m = match fld.mutability {
|
||||
ast::struct_mutable => ast::m_mutbl,
|
||||
ast::struct_immutable => ast::m_imm
|
||||
};
|
||||
return Some(m);
|
||||
return Some(ast::m_imm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -894,17 +894,7 @@ pub fn determine_rp_in_struct_field(
|
|||
cm: @ast::struct_field,
|
||||
cx: @mut DetermineRpCtxt,
|
||||
visitor: visit::vt<@mut DetermineRpCtxt>) {
|
||||
match cm.node.kind {
|
||||
ast::named_field(_, ast::struct_mutable, _) => {
|
||||
do cx.with_ambient_variance(rv_invariant) {
|
||||
visit::visit_struct_field(cm, cx, visitor);
|
||||
}
|
||||
}
|
||||
ast::named_field(_, ast::struct_immutable, _) |
|
||||
ast::unnamed_field => {
|
||||
visit::visit_struct_field(cm, cx, visitor);
|
||||
}
|
||||
}
|
||||
visit::visit_struct_field(cm, cx, visitor);
|
||||
}
|
||||
|
||||
pub fn determine_rp_in_crate(sess: Session,
|
||||
|
|
|
@ -4667,7 +4667,7 @@ pub impl Resolver {
|
|||
for vec::each(class_def.fields) |field| {
|
||||
match field.node.kind {
|
||||
unnamed_field => {},
|
||||
named_field(ident, _, _) => {
|
||||
named_field(ident, _) => {
|
||||
if str::eq_slice(*this.session.str_of(ident),
|
||||
name) {
|
||||
return true
|
||||
|
|
|
@ -4718,7 +4718,7 @@ pub impl Resolver {
|
|||
for vec::each(class_def.fields) |field| {
|
||||
match field.node.kind {
|
||||
unnamed_field => {},
|
||||
named_field(ident, _, _) => {
|
||||
named_field(ident, _) => {
|
||||
if str::eq_slice(*this.session.str_of(ident),
|
||||
name) {
|
||||
return true
|
||||
|
|
|
@ -2987,9 +2987,8 @@ pub fn trans_crate(sess: session::Session,
|
|||
emap2: resolve::ExportMap2,
|
||||
maps: astencode::Maps) -> (ModuleRef, LinkMeta) {
|
||||
|
||||
let symbol_hasher = @hash::default_state();
|
||||
let link_meta =
|
||||
link::build_link_meta(sess, crate, output, symbol_hasher);
|
||||
let symbol_hasher = @mut hash::default_state();
|
||||
let link_meta = link::build_link_meta(sess, crate, output, symbol_hasher);
|
||||
let reachable = reachable::find_reachable(
|
||||
&crate.node.module,
|
||||
emap2,
|
||||
|
|
|
@ -207,7 +207,7 @@ pub struct CrateContext {
|
|||
adt_reprs: @mut HashMap<ty::t, @adt::Repr>,
|
||||
names: namegen,
|
||||
next_addrspace: addrspace_gen,
|
||||
symbol_hasher: @hash::State,
|
||||
symbol_hasher: @mut hash::State,
|
||||
type_hashcodes: @mut HashMap<ty::t, @str>,
|
||||
type_short_names: @mut HashMap<ty::t, ~str>,
|
||||
all_llvm_symbols: @mut HashSet<@~str>,
|
||||
|
|
|
@ -120,14 +120,14 @@ lvalues are *never* stored by value.
|
|||
*/
|
||||
|
||||
use back::abi;
|
||||
use lib;
|
||||
use lib::llvm::{ValueRef, TypeRef, llvm};
|
||||
use lib;
|
||||
use metadata::csearch;
|
||||
use middle::trans::_match;
|
||||
use middle::trans::adt;
|
||||
use middle::trans::asm;
|
||||
use middle::trans::base;
|
||||
use middle::trans::base::*;
|
||||
use middle::trans::base;
|
||||
use middle::trans::build::*;
|
||||
use middle::trans::callee::DoAutorefArg;
|
||||
use middle::trans::callee;
|
||||
|
@ -142,8 +142,10 @@ use middle::trans::machine;
|
|||
use middle::trans::meth;
|
||||
use middle::trans::tvec;
|
||||
use middle::trans::type_of;
|
||||
use middle::ty::struct_fields;
|
||||
use middle::ty::{AutoDerefRef, AutoAddEnv};
|
||||
use middle::ty::{AutoPtr, AutoBorrowVec, AutoBorrowVecRef, AutoBorrowFn};
|
||||
use middle::ty;
|
||||
use middle::ty::struct_mutable_fields;
|
||||
use middle::ty::{AutoPtr, AutoBorrowVec, AutoBorrowVecRef, AutoBorrowFn,
|
||||
AutoDerefRef, AutoAddEnv, AutoUnsafe};
|
||||
use util::common::indenter;
|
||||
|
@ -1107,7 +1109,7 @@ pub fn with_field_tys<R>(tcx: ty::ctxt,
|
|||
op: &fn(int, (&[ty::field])) -> R) -> R {
|
||||
match ty::get(ty).sty {
|
||||
ty::ty_struct(did, ref substs) => {
|
||||
op(0, struct_mutable_fields(tcx, did, substs))
|
||||
op(0, struct_fields(tcx, did, substs))
|
||||
}
|
||||
|
||||
ty::ty_enum(_, ref substs) => {
|
||||
|
@ -1124,8 +1126,8 @@ pub fn with_field_tys<R>(tcx: ty::ctxt,
|
|||
ast::def_variant(enum_id, variant_id) => {
|
||||
let variant_info = ty::enum_variant_with_id(
|
||||
tcx, enum_id, variant_id);
|
||||
op(variant_info.disr_val, struct_mutable_fields(
|
||||
tcx, variant_id, substs))
|
||||
op(variant_info.disr_val,
|
||||
struct_fields(tcx, variant_id, substs))
|
||||
}
|
||||
_ => {
|
||||
tcx.sess.bug(~"resolve didn't map this expr to a \
|
||||
|
|
|
@ -496,9 +496,7 @@ pub fn trans_struct_drop(bcx: block,
|
|||
Call(bcx, dtor_addr, args);
|
||||
|
||||
// Drop the fields
|
||||
let field_tys =
|
||||
ty::struct_mutable_fields(bcx.tcx(), class_did,
|
||||
substs);
|
||||
let field_tys = ty::struct_fields(bcx.tcx(), class_did, substs);
|
||||
for vec::eachi(field_tys) |i, fld| {
|
||||
let llfld_a = adt::trans_field_ptr(bcx, repr, v0, 0, i);
|
||||
bcx = drop_ty(bcx, llfld_a, fld.mt.ty);
|
||||
|
|
|
@ -106,10 +106,9 @@ pub enum SelfMode {
|
|||
}
|
||||
|
||||
pub struct field_ty {
|
||||
ident: ident,
|
||||
id: def_id,
|
||||
vis: ast::visibility,
|
||||
mutability: ast::struct_mutability,
|
||||
ident: ident,
|
||||
id: def_id,
|
||||
vis: ast::visibility,
|
||||
}
|
||||
|
||||
// Contains information needed to resolve types and (in the future) look up
|
||||
|
@ -4027,12 +4026,11 @@ pub fn lookup_struct_field(cx: ctxt,
|
|||
fn struct_field_tys(fields: &[@struct_field]) -> ~[field_ty] {
|
||||
do fields.map |field| {
|
||||
match field.node.kind {
|
||||
named_field(ident, mutability, visibility) => {
|
||||
named_field(ident, visibility) => {
|
||||
field_ty {
|
||||
ident: ident,
|
||||
id: ast_util::local_def(field.node.id),
|
||||
vis: visibility,
|
||||
mutability: mutability,
|
||||
}
|
||||
}
|
||||
unnamed_field => {
|
||||
|
@ -4041,51 +4039,22 @@ fn struct_field_tys(fields: &[@struct_field]) -> ~[field_ty] {
|
|||
syntax::parse::token::special_idents::unnamed_field,
|
||||
id: ast_util::local_def(field.node.id),
|
||||
vis: ast::public,
|
||||
mutability: ast::struct_immutable,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return a list of fields corresponding to the struct's items
|
||||
// (as if the struct was a record). trans uses this
|
||||
// Takes a list of substs with which to instantiate field types
|
||||
// Keep in mind that this function reports that all fields are
|
||||
// mutable, regardless of how they were declared. It's meant to
|
||||
// be used in trans.
|
||||
pub fn struct_mutable_fields(cx: ctxt,
|
||||
did: ast::def_id,
|
||||
substs: &substs)
|
||||
-> ~[field] {
|
||||
struct_item_fields(cx, did, substs, |_mt| m_mutbl)
|
||||
}
|
||||
|
||||
// Same as struct_mutable_fields, but doesn't change
|
||||
// mutability.
|
||||
pub fn struct_fields(cx: ctxt,
|
||||
did: ast::def_id,
|
||||
substs: &substs)
|
||||
-> ~[field] {
|
||||
struct_item_fields(cx, did, substs, |mt| match mt {
|
||||
struct_mutable => m_mutbl,
|
||||
struct_immutable => m_imm })
|
||||
}
|
||||
|
||||
|
||||
fn struct_item_fields(cx:ctxt,
|
||||
did: ast::def_id,
|
||||
substs: &substs,
|
||||
frob_mutability: &fn(struct_mutability) -> mutability)
|
||||
-> ~[field] {
|
||||
// Returns a list of fields corresponding to the struct's items. trans uses
|
||||
// this. Takes a list of substs with which to instantiate field types.
|
||||
pub fn struct_fields(cx: ctxt, did: ast::def_id, substs: &substs)
|
||||
-> ~[field] {
|
||||
do lookup_struct_fields(cx, did).map |f| {
|
||||
// consider all instance vars mut, because the
|
||||
// constructor may mutate all vars
|
||||
field {
|
||||
ident: f.ident,
|
||||
ident: f.ident,
|
||||
mt: mt {
|
||||
ty: lookup_field_type(cx, did, f.id, substs),
|
||||
mutbl: frob_mutability(f.mutability)
|
||||
mutbl: m_imm
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ use syntax;
|
|||
* there. */
|
||||
macro_rules! interner_key (
|
||||
() => (cast::transmute::<(uint, uint),
|
||||
&fn(+v: @@syntax::parse::token::ident_interner)>((-3 as uint, 0u)))
|
||||
&fn(v: @@syntax::parse::token::ident_interner)>((-3 as uint, 0u)))
|
||||
)
|
||||
|
||||
// Hack; rather than thread an interner through everywhere, rely on
|
||||
|
@ -274,7 +274,7 @@ fn structdoc_from_struct(
|
|||
item: itemdoc,
|
||||
fields: do struct_def.fields.map |field| {
|
||||
match field.node.kind {
|
||||
ast::named_field(ident, _, _) => to_str(ident),
|
||||
ast::named_field(ident, _) => to_str(ident),
|
||||
ast::unnamed_field => ~"(unnamed)",
|
||||
}
|
||||
},
|
||||
|
|
|
@ -26,8 +26,8 @@ pub type Writer = ~fn(v: WriteInstr);
|
|||
pub type WriterFactory = ~fn(page: doc::Page) -> Writer;
|
||||
|
||||
pub trait WriterUtils {
|
||||
fn put_str(&self, +str: ~str);
|
||||
fn put_line(&self, +str: ~str);
|
||||
fn put_str(&self, str: ~str);
|
||||
fn put_line(&self, str: ~str);
|
||||
fn put_done(&self);
|
||||
}
|
||||
|
||||
|
@ -230,6 +230,7 @@ pub fn future_writer_factory(
|
|||
let markdown_ch = markdown_ch.clone();
|
||||
do task::spawn || {
|
||||
let (writer, future) = future_writer();
|
||||
let mut future = future;
|
||||
writer_ch.send(writer);
|
||||
let s = future.get();
|
||||
markdown_ch.send((copy page, s));
|
||||
|
|
|
@ -17,7 +17,7 @@ use time;
|
|||
/// A single operation on the document model
|
||||
pub struct Pass {
|
||||
name: ~str,
|
||||
f: @fn(srv: astsrv::Srv, +doc: doc::Doc) -> doc::Doc
|
||||
f: @fn(srv: astsrv::Srv, doc: doc::Doc) -> doc::Doc
|
||||
}
|
||||
|
||||
pub fn run_passes(
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
use core::*;
|
||||
use core::cmp::Ord;
|
||||
use core::hash::Streaming;
|
||||
use core::rt::io::Writer;
|
||||
use rustc::driver::{driver, session};
|
||||
use rustc::driver::session::{lib_crate, unknown_crate};
|
||||
use rustc::metadata::filesearch;
|
||||
|
@ -367,9 +368,9 @@ pub fn error(msg: ~str) {
|
|||
}
|
||||
|
||||
pub fn hash(data: ~str) -> ~str {
|
||||
let hasher = &hash::default_state();
|
||||
|
||||
hasher.write_str(data);
|
||||
let mut hasher = hash::default_state();
|
||||
let buffer = str::as_bytes_slice(data);
|
||||
hasher.write(buffer);
|
||||
hasher.result_str()
|
||||
}
|
||||
|
||||
|
|
|
@ -673,8 +673,9 @@ mod tests {
|
|||
let mut children = ~[];
|
||||
for 5.times {
|
||||
let arc3 = (*arc).clone();
|
||||
do task::task().future_result(|+r| children.push(r)).spawn
|
||||
|| {
|
||||
let mut builder = task::task();
|
||||
builder.future_result(|r| children.push(r));
|
||||
do builder.spawn {
|
||||
do arc3.read |num| {
|
||||
assert!(*num >= 0);
|
||||
}
|
||||
|
@ -682,11 +683,15 @@ mod tests {
|
|||
}
|
||||
|
||||
// Wait for children to pass their asserts
|
||||
for vec::each(children) |r| { r.recv(); }
|
||||
for vec::each(children) |r| {
|
||||
r.recv();
|
||||
}
|
||||
|
||||
// Wait for writer to finish
|
||||
p.recv();
|
||||
do arc.read |num| { assert!(*num == 10); }
|
||||
do arc.read |num| {
|
||||
assert!(*num == 10);
|
||||
}
|
||||
}
|
||||
#[test]
|
||||
fn test_rw_downgrade() {
|
||||
|
|
|
@ -47,7 +47,7 @@ use core::vec;
|
|||
pub mod rusti {
|
||||
#[abi = "rust-intrinsic"]
|
||||
pub extern "rust-intrinsic" {
|
||||
fn move_val_init<T>(dst: &mut T, +src: T);
|
||||
fn move_val_init<T>(dst: &mut T, src: T);
|
||||
fn needs_drop<T>() -> bool;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1426,7 +1426,7 @@ mod tests {
|
|||
|
||||
#[bench]
|
||||
fn bench_uint_small(b: &mut BenchHarness) {
|
||||
let r = rng();
|
||||
let mut r = rng();
|
||||
let mut bitv = 0 as uint;
|
||||
do b.iter {
|
||||
bitv |= (1 << ((r.next() as uint) % uint::bits));
|
||||
|
@ -1435,7 +1435,7 @@ mod tests {
|
|||
|
||||
#[bench]
|
||||
fn bench_small_bitv_small(b: &mut BenchHarness) {
|
||||
let r = rng();
|
||||
let mut r = rng();
|
||||
let mut bitv = SmallBitv::new(uint::bits);
|
||||
do b.iter {
|
||||
bitv.set((r.next() as uint) % uint::bits, true);
|
||||
|
@ -1444,7 +1444,7 @@ mod tests {
|
|||
|
||||
#[bench]
|
||||
fn bench_big_bitv_small(b: &mut BenchHarness) {
|
||||
let r = rng();
|
||||
let mut r = rng();
|
||||
let mut bitv = BigBitv::new(~[0]);
|
||||
do b.iter {
|
||||
bitv.set((r.next() as uint) % uint::bits, true);
|
||||
|
@ -1453,7 +1453,7 @@ mod tests {
|
|||
|
||||
#[bench]
|
||||
fn bench_big_bitv_big(b: &mut BenchHarness) {
|
||||
let r = rng();
|
||||
let mut r = rng();
|
||||
let mut storage = ~[];
|
||||
storage.grow(bench_bits / uint::bits, &0);
|
||||
let mut bitv = BigBitv::new(storage);
|
||||
|
@ -1464,7 +1464,7 @@ mod tests {
|
|||
|
||||
#[bench]
|
||||
fn bench_bitv_big(b: &mut BenchHarness) {
|
||||
let r = rng();
|
||||
let mut r = rng();
|
||||
let mut bitv = Bitv::new(bench_bits, false);
|
||||
do b.iter {
|
||||
bitv.set((r.next() as uint) % bench_bits, true);
|
||||
|
@ -1473,7 +1473,7 @@ mod tests {
|
|||
|
||||
#[bench]
|
||||
fn bench_bitv_small(b: &mut BenchHarness) {
|
||||
let r = rng();
|
||||
let mut r = rng();
|
||||
let mut bitv = Bitv::new(uint::bits, false);
|
||||
do b.iter {
|
||||
bitv.set((r.next() as uint) % uint::bits, true);
|
||||
|
@ -1482,7 +1482,7 @@ mod tests {
|
|||
|
||||
#[bench]
|
||||
fn bench_bitv_set_small(b: &mut BenchHarness) {
|
||||
let r = rng();
|
||||
let mut r = rng();
|
||||
let mut bitv = BitvSet::new();
|
||||
do b.iter {
|
||||
bitv.insert((r.next() as uint) % uint::bits);
|
||||
|
@ -1491,7 +1491,7 @@ mod tests {
|
|||
|
||||
#[bench]
|
||||
fn bench_bitv_set_big(b: &mut BenchHarness) {
|
||||
let r = rng();
|
||||
let mut r = rng();
|
||||
let mut bitv = BitvSet::new();
|
||||
do b.iter {
|
||||
bitv.insert((r.next() as uint) % bench_bits);
|
||||
|
|
|
@ -72,7 +72,7 @@ impl<T:Owned,U:Owned> Peekable<U> for DuplexStream<T, U> {
|
|||
}
|
||||
|
||||
impl<T:Owned,U:Owned> Selectable for DuplexStream<T, U> {
|
||||
fn header(&self) -> *pipes::PacketHeader {
|
||||
fn header(&mut self) -> *mut pipes::PacketHeader {
|
||||
self.port.header()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -600,11 +600,18 @@ pub mod writer {
|
|||
use core::vec;
|
||||
|
||||
// ebml writing
|
||||
#[cfg(stage0)]
|
||||
pub struct Encoder {
|
||||
writer: @io::Writer,
|
||||
priv mut size_positions: ~[uint],
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))]
|
||||
pub struct Encoder {
|
||||
writer: @io::Writer,
|
||||
priv size_positions: ~[uint],
|
||||
}
|
||||
|
||||
fn write_sized_vuint(w: @io::Writer, n: uint, size: uint) {
|
||||
match size {
|
||||
1u => w.write(&[0x80u8 | (n as u8)]),
|
||||
|
@ -625,9 +632,22 @@ pub mod writer {
|
|||
fail!(fmt!("vint to write too big: %?", n));
|
||||
}
|
||||
|
||||
#[cfg(stage0)]
|
||||
pub fn Encoder(w: @io::Writer) -> Encoder {
|
||||
let size_positions: ~[uint] = ~[];
|
||||
Encoder { writer: w, mut size_positions: size_positions }
|
||||
Encoder {
|
||||
writer: w,
|
||||
mut size_positions: size_positions
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))]
|
||||
pub fn Encoder(w: @io::Writer) -> Encoder {
|
||||
let size_positions: ~[uint] = ~[];
|
||||
Encoder {
|
||||
writer: w,
|
||||
size_positions: size_positions
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME (#2741): Provide a function to write the standard ebml header.
|
||||
|
|
|
@ -145,7 +145,7 @@ struct FileInput_ {
|
|||
// "self.fi." -> "self." and renaming FileInput_. Documentation above
|
||||
// will likely have to be updated to use `let mut in = ...`.
|
||||
pub struct FileInput {
|
||||
priv mut fi: FileInput_
|
||||
priv fi: @mut FileInput_
|
||||
}
|
||||
|
||||
impl FileInput {
|
||||
|
@ -170,7 +170,7 @@ impl FileInput {
|
|||
pub fn from_vec_raw(files: ~[Option<Path>])
|
||||
-> FileInput {
|
||||
FileInput{
|
||||
fi: FileInput_ {
|
||||
fi: @mut FileInput_ {
|
||||
files: files,
|
||||
current_reader: None,
|
||||
state: FileInputState {
|
||||
|
|
|
@ -558,9 +558,11 @@ pub mod bytepipes {
|
|||
}
|
||||
}
|
||||
|
||||
// XXX: Remove `@mut` when this module is ported to the new I/O traits,
|
||||
// which use `&mut self` properly.
|
||||
pub struct PipeBytePort {
|
||||
port: comm::Port<~[u8]>,
|
||||
mut buf: ~[u8]
|
||||
buf: @mut ~[u8]
|
||||
}
|
||||
|
||||
pub struct PipeByteChan {
|
||||
|
@ -569,13 +571,13 @@ pub mod bytepipes {
|
|||
|
||||
impl BytePort for PipeBytePort {
|
||||
fn try_recv(&self, count: uint) -> Option<~[u8]> {
|
||||
if vec::uniq_len(&const self.buf) >= count {
|
||||
let mut bytes = ::core::util::replace(&mut self.buf, ~[]);
|
||||
self.buf = bytes.slice(count, bytes.len()).to_owned();
|
||||
if vec::uniq_len(&const *self.buf) >= count {
|
||||
let mut bytes = ::core::util::replace(&mut *self.buf, ~[]);
|
||||
*self.buf = bytes.slice(count, bytes.len()).to_owned();
|
||||
bytes.truncate(count);
|
||||
return Some(bytes);
|
||||
} else if vec::uniq_len(&const self.buf) > 0 {
|
||||
let mut bytes = ::core::util::replace(&mut self.buf, ~[]);
|
||||
} else if vec::uniq_len(&const *self.buf) > 0 {
|
||||
let mut bytes = ::core::util::replace(&mut *self.buf, ~[]);
|
||||
assert!(count > bytes.len());
|
||||
match self.try_recv(count - bytes.len()) {
|
||||
Some(rest) => {
|
||||
|
@ -584,11 +586,11 @@ pub mod bytepipes {
|
|||
}
|
||||
None => return None
|
||||
}
|
||||
} else if vec::uniq_len(&const self.buf) == 0 {
|
||||
} else if vec::uniq_len(&const *self.buf) == 0 {
|
||||
match self.port.try_recv() {
|
||||
Some(buf) => {
|
||||
assert!(!buf.is_empty());
|
||||
self.buf = buf;
|
||||
*self.buf = buf;
|
||||
return self.try_recv(count);
|
||||
}
|
||||
None => return None
|
||||
|
@ -609,7 +611,7 @@ pub mod bytepipes {
|
|||
fn new(p: Port<~[u8]>) -> PipeBytePort {
|
||||
PipeBytePort {
|
||||
port: p,
|
||||
buf: ~[]
|
||||
buf: @mut ~[]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -643,7 +645,7 @@ mod test {
|
|||
|
||||
chan.send(10);
|
||||
|
||||
let bytes = copy chan.byte_chan.writer.bytes;
|
||||
let bytes = copy *chan.byte_chan.writer.bytes;
|
||||
|
||||
let reader = BufReader::new(bytes);
|
||||
let port = serial::reader_port(reader);
|
||||
|
@ -690,7 +692,7 @@ mod test {
|
|||
|
||||
chan.send(10);
|
||||
|
||||
let bytes = copy chan.byte_chan.writer.bytes;
|
||||
let bytes = copy *chan.byte_chan.writer.bytes;
|
||||
|
||||
let reader = BufReader::new(bytes);
|
||||
let port = pod::reader_port(reader);
|
||||
|
@ -926,7 +928,7 @@ mod test {
|
|||
test_try_recv_none3(pipe_port_loader);
|
||||
}
|
||||
|
||||
fn test_try_recv_none4<P:BytePort>(+loader: PortLoader<P>) {
|
||||
fn test_try_recv_none4<P:BytePort>(loader: PortLoader<P>) {
|
||||
assert!(do task::try || {
|
||||
static CONTINUE: [u8, ..4] = [0xAA, 0xBB, 0xCC, 0xDD];
|
||||
// The control word is followed by a valid length,
|
||||
|
|
|
@ -28,10 +28,17 @@ use core::pipes::recv;
|
|||
use core::task;
|
||||
|
||||
#[doc = "The future type"]
|
||||
#[cfg(stage0)]
|
||||
pub struct Future<A> {
|
||||
priv mut state: FutureState<A>,
|
||||
}
|
||||
|
||||
#[doc = "The future type"]
|
||||
#[cfg(not(stage0))]
|
||||
pub struct Future<A> {
|
||||
priv state: FutureState<A>,
|
||||
}
|
||||
|
||||
// FIXME(#2829) -- futures should not be copyable, because they close
|
||||
// over ~fn's that have pipes and so forth within!
|
||||
#[unsafe_destructor]
|
||||
|
@ -47,13 +54,14 @@ priv enum FutureState<A> {
|
|||
|
||||
/// Methods on the `future` type
|
||||
pub impl<A:Copy> Future<A> {
|
||||
fn get(&self) -> A {
|
||||
fn get(&mut self) -> A {
|
||||
//! Get the value of the future
|
||||
*(self.get_ref())
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<A> Future<A> {
|
||||
#[cfg(stage0)]
|
||||
fn get_ref<'a>(&'a self) -> &'a A {
|
||||
/*!
|
||||
* Executes the future's closure and then returns a borrowed
|
||||
|
@ -61,19 +69,53 @@ pub impl<A> Future<A> {
|
|||
* the future.
|
||||
*/
|
||||
unsafe {
|
||||
match self.state {
|
||||
Forced(ref mut v) => { return cast::transmute(v); }
|
||||
Evaluating => fail!(~"Recursive forcing of future!"),
|
||||
Pending(_) => {}
|
||||
{
|
||||
match self.state {
|
||||
Forced(ref mut v) => { return cast::transmute(v); }
|
||||
Evaluating => fail!(~"Recursive forcing of future!"),
|
||||
Pending(_) => {}
|
||||
}
|
||||
}
|
||||
{
|
||||
let mut state = Evaluating;
|
||||
self.state <-> state;
|
||||
match state {
|
||||
Forced(_) | Evaluating => fail!(~"Logic error."),
|
||||
Pending(f) => {
|
||||
self.state = Forced(f());
|
||||
cast::transmute(self.get_ref())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut state = Evaluating;
|
||||
self.state <-> state;
|
||||
match state {
|
||||
Forced(_) | Evaluating => fail!(~"Logic error."),
|
||||
Pending(f) => {
|
||||
self.state = Forced(f());
|
||||
self.get_ref()
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
#[cfg(stage3)]
|
||||
fn get_ref<'a>(&'a mut self) -> &'a A {
|
||||
/*!
|
||||
* Executes the future's closure and then returns a borrowed
|
||||
* pointer to the result. The borrowed pointer lasts as long as
|
||||
* the future.
|
||||
*/
|
||||
unsafe {
|
||||
{
|
||||
match self.state {
|
||||
Forced(ref mut v) => { return cast::transmute(v); }
|
||||
Evaluating => fail!(~"Recursive forcing of future!"),
|
||||
Pending(_) => {}
|
||||
}
|
||||
}
|
||||
{
|
||||
let mut state = Evaluating;
|
||||
self.state <-> state;
|
||||
match state {
|
||||
Forced(_) | Evaluating => fail!(~"Logic error."),
|
||||
Pending(f) => {
|
||||
self.state = Forced(f());
|
||||
cast::transmute(self.get_ref())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -142,15 +184,15 @@ pub fn spawn<A:Owned>(blk: ~fn() -> A) -> Future<A> {
|
|||
#[allow(non_implicitly_copyable_typarams)]
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
|
||||
use future::*;
|
||||
|
||||
use core::cell::Cell;
|
||||
use core::comm::{oneshot, send_one};
|
||||
use core::task;
|
||||
|
||||
#[test]
|
||||
fn test_from_value() {
|
||||
let f = from_value(~"snail");
|
||||
let mut f = from_value(~"snail");
|
||||
assert!(f.get() == ~"snail");
|
||||
}
|
||||
|
||||
|
@ -158,31 +200,31 @@ mod test {
|
|||
fn test_from_port() {
|
||||
let (po, ch) = oneshot();
|
||||
send_one(ch, ~"whale");
|
||||
let f = from_port(po);
|
||||
let mut f = from_port(po);
|
||||
assert!(f.get() == ~"whale");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_fn() {
|
||||
let f = from_fn(|| ~"brail");
|
||||
let mut f = from_fn(|| ~"brail");
|
||||
assert!(f.get() == ~"brail");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_interface_get() {
|
||||
let f = from_value(~"fail");
|
||||
let mut f = from_value(~"fail");
|
||||
assert!(f.get() == ~"fail");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_ref_method() {
|
||||
let f = from_value(22);
|
||||
let mut f = from_value(22);
|
||||
assert!(*f.get_ref() == 22);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_spawn() {
|
||||
let f = spawn(|| ~"bale");
|
||||
let mut f = spawn(|| ~"bale");
|
||||
assert!(f.get() == ~"bale");
|
||||
}
|
||||
|
||||
|
@ -190,15 +232,16 @@ mod test {
|
|||
#[should_fail]
|
||||
#[ignore(cfg(target_os = "win32"))]
|
||||
fn test_futurefail() {
|
||||
let f = spawn(|| fail!());
|
||||
let mut f = spawn(|| fail!());
|
||||
let _x: ~str = f.get();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sendable_future() {
|
||||
let expected = ~"schlorf";
|
||||
let f = do spawn { copy expected };
|
||||
do task::spawn || {
|
||||
let f = Cell(do spawn { copy expected });
|
||||
do task::spawn {
|
||||
let mut f = f.take();
|
||||
let actual = f.get();
|
||||
assert!(actual == expected);
|
||||
}
|
||||
|
|
|
@ -13,14 +13,14 @@ use core::io;
|
|||
|
||||
pub struct BufReader {
|
||||
buf: ~[u8],
|
||||
mut pos: uint
|
||||
pos: @mut uint
|
||||
}
|
||||
|
||||
pub impl BufReader {
|
||||
pub fn new(v: ~[u8]) -> BufReader {
|
||||
BufReader {
|
||||
buf: v,
|
||||
pos: 0
|
||||
pos: @mut 0
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,13 +29,13 @@ pub impl BufReader {
|
|||
// I can't get the borrowing to work correctly
|
||||
let bytes_reader = BytesReader {
|
||||
bytes: ::core::util::id::<&[u8]>(self.buf),
|
||||
pos: self.pos
|
||||
pos: @mut *self.pos
|
||||
};
|
||||
|
||||
let res = f(&bytes_reader);
|
||||
|
||||
// FIXME #4429: This isn't correct if f fails
|
||||
self.pos = bytes_reader.pos;
|
||||
*self.pos = *bytes_reader.pos;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -220,11 +220,18 @@ impl serialize::Encoder for Encoder {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(stage0)]
|
||||
pub struct PrettyEncoder {
|
||||
priv wr: @io::Writer,
|
||||
priv mut indent: uint,
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))]
|
||||
pub struct PrettyEncoder {
|
||||
priv wr: @io::Writer,
|
||||
priv indent: uint,
|
||||
}
|
||||
|
||||
pub fn PrettyEncoder(wr: @io::Writer) -> PrettyEncoder {
|
||||
PrettyEncoder {
|
||||
wr: wr,
|
||||
|
@ -838,10 +845,16 @@ pub fn from_str(s: &str) -> Result<Json, Error> {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(stage0)]
|
||||
pub struct Decoder {
|
||||
priv mut stack: ~[Json],
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))]
|
||||
pub struct Decoder {
|
||||
priv stack: ~[Json],
|
||||
}
|
||||
|
||||
pub fn Decoder(json: Json) -> Decoder {
|
||||
Decoder {
|
||||
stack: ~[json]
|
||||
|
|
|
@ -71,14 +71,14 @@ pub fn TcpSocket(socket_data: @TcpSocketData) -> TcpSocket {
|
|||
* satisfy both the `io::Reader` and `io::Writer` traits.
|
||||
*/
|
||||
pub struct TcpSocketBuf {
|
||||
data: @TcpBufferedSocketData,
|
||||
mut end_of_stream: bool
|
||||
data: @mut TcpBufferedSocketData,
|
||||
end_of_stream: @mut bool
|
||||
}
|
||||
|
||||
pub fn TcpSocketBuf(data: @TcpBufferedSocketData) -> TcpSocketBuf {
|
||||
pub fn TcpSocketBuf(data: @mut TcpBufferedSocketData) -> TcpSocketBuf {
|
||||
TcpSocketBuf {
|
||||
data: data,
|
||||
end_of_stream: false
|
||||
end_of_stream: @mut false
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -670,7 +670,7 @@ fn listen_common(host_ip: ip::IpAddr,
|
|||
&ip::Ipv4(_) => { false }
|
||||
&ip::Ipv6(_) => { true }
|
||||
},
|
||||
mut active: true
|
||||
active: @mut true
|
||||
};
|
||||
let server_data_ptr: *TcpListenFcData = &server_data;
|
||||
|
||||
|
@ -751,7 +751,7 @@ fn listen_common(host_ip: ip::IpAddr,
|
|||
debug!(
|
||||
"tcp::listen post-kill recv hl interact %?",
|
||||
loop_ptr);
|
||||
(*server_data_ptr).active = false;
|
||||
*(*server_data_ptr).active = false;
|
||||
uv::ll::close(server_stream_ptr, tcp_lfc_close_cb);
|
||||
}
|
||||
};
|
||||
|
@ -782,7 +782,7 @@ fn listen_common(host_ip: ip::IpAddr,
|
|||
debug!(
|
||||
"tcp::listen post-kill recv hl interact %?",
|
||||
loop_ptr);
|
||||
(*server_data_ptr).active = false;
|
||||
*(*server_data_ptr).active = false;
|
||||
uv::ll::close(server_stream_ptr, tcp_lfc_close_cb);
|
||||
}
|
||||
};
|
||||
|
@ -816,8 +816,8 @@ fn listen_common(host_ip: ip::IpAddr,
|
|||
* A buffered wrapper that you can cast as an `io::Reader` or `io::Writer`
|
||||
*/
|
||||
pub fn socket_buf(sock: TcpSocket) -> TcpSocketBuf {
|
||||
TcpSocketBuf(@TcpBufferedSocketData {
|
||||
sock: sock, mut buf: ~[], buf_off: 0
|
||||
TcpSocketBuf(@mut TcpBufferedSocketData {
|
||||
sock: sock, buf: ~[], buf_off: 0
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -902,12 +902,15 @@ impl io::Reader for TcpSocketBuf {
|
|||
// need to read in data from the socket. Note that the internal
|
||||
// buffer is of no use anymore as we read all bytes from it,
|
||||
// so we can throw it away.
|
||||
let read_result = read(&self.data.sock, 0u);
|
||||
let read_result = {
|
||||
let data = &*self.data;
|
||||
read(&data.sock, 0)
|
||||
};
|
||||
if read_result.is_err() {
|
||||
let err_data = read_result.get_err();
|
||||
|
||||
if err_data.err_name == ~"EOF" {
|
||||
self.end_of_stream = true;
|
||||
*self.end_of_stream = true;
|
||||
break;
|
||||
} else {
|
||||
debug!("ERROR sock_buf as io::reader.read err %? %?",
|
||||
|
@ -917,8 +920,7 @@ impl io::Reader for TcpSocketBuf {
|
|||
// should show up in a later call to read().
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
self.data.buf = result::unwrap(read_result);
|
||||
self.data.buf_off = 0;
|
||||
}
|
||||
|
@ -934,27 +936,29 @@ impl io::Reader for TcpSocketBuf {
|
|||
return c as int
|
||||
}
|
||||
|
||||
let read_result = read(&self.data.sock, 0u);
|
||||
let read_result = {
|
||||
let data = &*self.data;
|
||||
read(&data.sock, 0)
|
||||
};
|
||||
if read_result.is_err() {
|
||||
let err_data = read_result.get_err();
|
||||
|
||||
if err_data.err_name == ~"EOF" {
|
||||
self.end_of_stream = true;
|
||||
*self.end_of_stream = true;
|
||||
return -1
|
||||
} else {
|
||||
debug!("ERROR sock_buf as io::reader.read err %? %?",
|
||||
err_data.err_name, err_data.err_msg);
|
||||
fail!()
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
self.data.buf = result::unwrap(read_result);
|
||||
self.data.buf_off = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
fn eof(&self) -> bool {
|
||||
self.end_of_stream
|
||||
*self.end_of_stream
|
||||
}
|
||||
fn seek(&self, dist: int, seek: io::SeekStyle) {
|
||||
debug!("tcp_socket_buf seek stub %? %?", dist, seek);
|
||||
|
@ -1204,7 +1208,7 @@ struct TcpListenFcData {
|
|||
on_connect_cb: ~fn(*uv::ll::uv_tcp_t),
|
||||
iotask: IoTask,
|
||||
ipv6: bool,
|
||||
mut active: bool,
|
||||
active: @mut bool,
|
||||
}
|
||||
|
||||
extern fn tcp_lfc_close_cb(handle: *uv::ll::uv_tcp_t) {
|
||||
|
@ -1222,7 +1226,7 @@ extern fn tcp_lfc_on_connection_cb(handle: *uv::ll::uv_tcp_t,
|
|||
let server_data_ptr = uv::ll::get_data_for_uv_handle(handle)
|
||||
as *TcpListenFcData;
|
||||
let kill_ch = (*server_data_ptr).kill_ch.clone();
|
||||
if (*server_data_ptr).active {
|
||||
if *(*server_data_ptr).active {
|
||||
match status {
|
||||
0i32 => ((*server_data_ptr).on_connect_cb)(handle),
|
||||
_ => {
|
||||
|
@ -1230,7 +1234,7 @@ extern fn tcp_lfc_on_connection_cb(handle: *uv::ll::uv_tcp_t,
|
|||
kill_ch.send(
|
||||
Some(uv::ll::get_last_err_data(loop_ptr)
|
||||
.to_tcp_err()));
|
||||
(*server_data_ptr).active = false;
|
||||
*(*server_data_ptr).active = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1430,8 +1434,8 @@ struct TcpSocketData {
|
|||
|
||||
struct TcpBufferedSocketData {
|
||||
sock: TcpSocket,
|
||||
mut buf: ~[u8],
|
||||
mut buf_off: uint
|
||||
buf: ~[u8],
|
||||
buf_off: uint
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -1959,7 +1963,7 @@ mod test {
|
|||
}
|
||||
|
||||
fn tcp_write_single(sock: &TcpSocket, val: ~[u8]) {
|
||||
let write_result_future = sock.write_future(val);
|
||||
let mut write_result_future = sock.write_future(val);
|
||||
let write_result = write_result_future.get();
|
||||
if result::is_err(&write_result) {
|
||||
debug!("tcp_write_single: write failed!");
|
||||
|
|
|
@ -73,10 +73,10 @@ fn map_slices<A:Copy + Owned,B:Copy + Owned>(
|
|||
info!("num_tasks: %?", (num_tasks, futures.len()));
|
||||
assert!((num_tasks == futures.len()));
|
||||
|
||||
let r = do futures.map() |ys| {
|
||||
let r = do vec::map_consume(futures) |ys| {
|
||||
let mut ys = ys;
|
||||
ys.get()
|
||||
};
|
||||
assert!((r.len() == futures.len()));
|
||||
r
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ use core::old_iter::BaseIter;
|
|||
|
||||
#[abi = "rust-intrinsic"]
|
||||
extern "rust-intrinsic" mod rusti {
|
||||
fn move_val_init<T>(dst: &mut T, +src: T);
|
||||
fn move_val_init<T>(dst: &mut T, src: T);
|
||||
fn init<T>() -> T;
|
||||
}
|
||||
|
||||
|
|
|
@ -946,8 +946,10 @@ mod test_tim_sort {
|
|||
|
||||
impl Ord for CVal {
|
||||
fn lt(&self, other: &CVal) -> bool {
|
||||
let rng = rand::rng();
|
||||
if rng.gen::<float>() > 0.995 { fail!(~"It's happening!!!"); }
|
||||
let mut rng = rand::rng();
|
||||
if rng.gen::<float>() > 0.995 {
|
||||
fail!(~"It's happening!!!");
|
||||
}
|
||||
(*self).val < other.val
|
||||
}
|
||||
fn le(&self, other: &CVal) -> bool { (*self).val <= other.val }
|
||||
|
@ -995,7 +997,7 @@ mod test_tim_sort {
|
|||
#[should_fail]
|
||||
#[cfg(unix)]
|
||||
fn crash_test() {
|
||||
let rng = rand::rng();
|
||||
let mut rng = rand::rng();
|
||||
let mut arr = do vec::from_fn(1000) |_i| {
|
||||
CVal { val: rng.gen() }
|
||||
};
|
||||
|
@ -1015,7 +1017,7 @@ mod test_tim_sort {
|
|||
|
||||
#[test]
|
||||
fn test_bad_Ord_impl() {
|
||||
let rng = rand::rng();
|
||||
let mut rng = rand::rng();
|
||||
let mut arr = do vec::from_fn(500) |_i| {
|
||||
DVal { val: rng.gen() }
|
||||
};
|
||||
|
@ -1067,7 +1069,7 @@ mod big_tests {
|
|||
}
|
||||
}
|
||||
|
||||
let rng = rand::rng();
|
||||
let mut rng = rand::rng();
|
||||
|
||||
for uint::range(lo, hi) |i| {
|
||||
let n = 1 << i;
|
||||
|
@ -1138,7 +1140,7 @@ mod big_tests {
|
|||
}
|
||||
}
|
||||
|
||||
let rng = rand::rng();
|
||||
let mut rng = rand::rng();
|
||||
|
||||
for uint::range(lo, hi) |i| {
|
||||
let n = 1 << i;
|
||||
|
|
|
@ -28,7 +28,9 @@ not required in or otherwise suitable for the core library.
|
|||
|
||||
#[allow(vecs_implicitly_copyable)];
|
||||
#[deny(non_camel_case_types)];
|
||||
#[allow(deprecated_mutable_fields)];
|
||||
|
||||
// Allow mutable fields only in stage0.
|
||||
#[warn(deprecated_mutable_fields)];
|
||||
|
||||
pub mod uv_ll;
|
||||
|
||||
|
|
|
@ -70,7 +70,9 @@ pub impl<T> TaskPool<T> {
|
|||
task::spawn(task_body);
|
||||
}
|
||||
Some(sched_mode) => {
|
||||
task::task().sched_mode(sched_mode).spawn(task_body);
|
||||
let mut task = task::task();
|
||||
task.sched_mode(sched_mode);
|
||||
task.spawn(task_body);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
use core::rand::RngUtil;
|
||||
|
||||
pub fn mkdtemp(tmpdir: &Path, suffix: &str) -> Option<Path> {
|
||||
let r = rand::rng();
|
||||
let mut r = rand::rng();
|
||||
for 1000.times {
|
||||
let p = tmpdir.push(r.gen_str(16) + suffix);
|
||||
if os::make_dir(&p, 0x1c0) { // 700
|
||||
|
|
|
@ -556,9 +556,12 @@ pub fn run_test(force_ignore: bool,
|
|||
let testfn_cell = ::core::cell::Cell(testfn);
|
||||
do task::spawn {
|
||||
let mut result_future = None; // task::future_result(builder);
|
||||
task::task().unlinked().future_result(|+r| {
|
||||
result_future = Some(r);
|
||||
}).spawn(testfn_cell.take());
|
||||
|
||||
let mut task = task::task();
|
||||
task.unlinked();
|
||||
task.future_result(|r| { result_future = Some(r) });
|
||||
task.spawn(testfn_cell.take());
|
||||
|
||||
let task_result = result_future.unwrap().recv();
|
||||
let test_result = calc_result(&desc,
|
||||
task_result == task::Success);
|
||||
|
@ -688,7 +691,7 @@ pub mod bench {
|
|||
// not met, it may run as long as the Go algorithm.
|
||||
pub fn auto_bench(&mut self, f: &fn(&mut BenchHarness)) -> ~[f64] {
|
||||
|
||||
let rng = rand::rng();
|
||||
let mut rng = rand::rng();
|
||||
let mut magnitude = 10;
|
||||
let mut prev_madp = 0.0;
|
||||
|
||||
|
|
|
@ -14,10 +14,11 @@ use uv;
|
|||
use uv::iotask;
|
||||
use uv::iotask::IoTask;
|
||||
|
||||
use core::libc;
|
||||
use core::libc::c_void;
|
||||
use core::cast::transmute;
|
||||
use core::cast;
|
||||
use core::comm::{stream, Chan, SharedChan, Port, select2i};
|
||||
use core::libc::c_void;
|
||||
use core::libc;
|
||||
|
||||
/**
|
||||
* Wait for timeout period then send provided value over a channel
|
||||
|
@ -120,22 +121,28 @@ pub fn sleep(iotask: &IoTask, msecs: uint) {
|
|||
pub fn recv_timeout<T:Copy + Owned>(iotask: &IoTask,
|
||||
msecs: uint,
|
||||
wait_po: &Port<T>)
|
||||
-> Option<T> {
|
||||
let (timeout_po, timeout_ch) = stream::<()>();
|
||||
-> Option<T> {
|
||||
let mut (timeout_po, timeout_ch) = stream::<()>();
|
||||
delayed_send(iotask, msecs, &timeout_ch, ());
|
||||
// FIXME: This could be written clearer (#2618)
|
||||
either::either(
|
||||
|_| {
|
||||
None
|
||||
}, |_| {
|
||||
Some(wait_po.recv())
|
||||
}, &select2i(&timeout_po, wait_po)
|
||||
)
|
||||
|
||||
// XXX: Workaround due to ports and channels not being &mut. They should
|
||||
// be.
|
||||
unsafe {
|
||||
let wait_po = cast::transmute_mut(wait_po);
|
||||
|
||||
// FIXME: This could be written clearer (#2618)
|
||||
either::either(
|
||||
|_| {
|
||||
None
|
||||
}, |_| {
|
||||
Some(wait_po.recv())
|
||||
}, &select2i(&mut timeout_po, wait_po)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// INTERNAL API
|
||||
extern fn delayed_send_cb(handle: *uv::ll::uv_timer_t,
|
||||
status: libc::c_int) {
|
||||
extern fn delayed_send_cb(handle: *uv::ll::uv_timer_t, status: libc::c_int) {
|
||||
unsafe {
|
||||
debug!(
|
||||
"delayed_send_cb handle %? status %?", handle, status);
|
||||
|
@ -212,7 +219,7 @@ mod test {
|
|||
let hl_loop_clone = hl_loop.clone();
|
||||
do task::spawn {
|
||||
use core::rand::*;
|
||||
let rng = rng();
|
||||
let mut rng = rng();
|
||||
for old_iter::repeat(times) {
|
||||
sleep(&hl_loop_clone, rng.next() as uint % maxms);
|
||||
}
|
||||
|
@ -269,7 +276,8 @@ mod test {
|
|||
let hl_loop = uv::global_loop::get();
|
||||
|
||||
for old_iter::repeat(times as uint) {
|
||||
let expected = rand::rng().gen_str(16u);
|
||||
let mut rng = rand::rng();
|
||||
let expected = rng.gen_str(16u);
|
||||
let (test_po, test_ch) = stream::<~str>();
|
||||
let hl_loop_clone = hl_loop.clone();
|
||||
do task::spawn() {
|
||||
|
|
|
@ -848,7 +848,7 @@ mod test_treemap {
|
|||
check_equal(ctrl, &map);
|
||||
assert!(map.find(&5).is_none());
|
||||
|
||||
let rng = rand::IsaacRng::new_seeded(&[42]);
|
||||
let mut rng = rand::IsaacRng::new_seeded(&[42]);
|
||||
|
||||
for 3.times {
|
||||
for 90.times {
|
||||
|
|
|
@ -62,7 +62,9 @@ fn get_monitor_task_gl() -> IoTask {
|
|||
}
|
||||
};
|
||||
if installed {
|
||||
do task().unlinked().spawn() {
|
||||
let mut task = task();
|
||||
task.unlinked();
|
||||
do task.spawn {
|
||||
unsafe {
|
||||
debug!("global monitor task starting");
|
||||
// As a weak task the runtime will notify us
|
||||
|
@ -88,7 +90,9 @@ fn get_monitor_task_gl() -> IoTask {
|
|||
}
|
||||
|
||||
fn spawn_loop() -> IoTask {
|
||||
let builder = do task().add_wrapper |task_body| {
|
||||
let mut builder = task();
|
||||
|
||||
do builder.add_wrapper |task_body| {
|
||||
let result: ~fn() = || {
|
||||
// The I/O loop task also needs to be weak so it doesn't keep
|
||||
// the runtime alive
|
||||
|
@ -107,7 +111,8 @@ fn spawn_loop() -> IoTask {
|
|||
};
|
||||
result
|
||||
};
|
||||
let builder = builder.unlinked();
|
||||
|
||||
builder.unlinked();
|
||||
spawn_iotask(builder)
|
||||
}
|
||||
|
||||
|
|
|
@ -36,11 +36,11 @@ impl Clone for IoTask {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn spawn_iotask(task: task::TaskBuilder) -> IoTask {
|
||||
|
||||
pub fn spawn_iotask(mut task: task::TaskBuilder) -> IoTask {
|
||||
let (iotask_port, iotask_chan) = stream();
|
||||
|
||||
do task.sched_mode(task::SingleThreaded).spawn {
|
||||
task.sched_mode(task::SingleThreaded);
|
||||
do task.spawn {
|
||||
debug!("entering libuv task");
|
||||
run_loop(&iotask_chan);
|
||||
debug!("libuv task exiting");
|
||||
|
|
|
@ -780,23 +780,24 @@ extern mod rustrt {
|
|||
// FIXME ref #2064
|
||||
unsafe fn rust_uv_tcp_connect(connect_ptr: *uv_connect_t,
|
||||
tcp_handle_ptr: *uv_tcp_t,
|
||||
++after_cb: *u8,
|
||||
++addr: *sockaddr_in) -> libc::c_int;
|
||||
after_cb: *u8,
|
||||
addr: *sockaddr_in)
|
||||
-> libc::c_int;
|
||||
// FIXME ref #2064
|
||||
unsafe fn rust_uv_tcp_bind(tcp_server: *uv_tcp_t,
|
||||
++addr: *sockaddr_in) -> libc::c_int;
|
||||
addr: *sockaddr_in) -> libc::c_int;
|
||||
// FIXME ref #2064
|
||||
unsafe fn rust_uv_tcp_connect6(connect_ptr: *uv_connect_t,
|
||||
tcp_handle_ptr: *uv_tcp_t,
|
||||
++after_cb: *u8,
|
||||
++addr: *sockaddr_in6) -> libc::c_int;
|
||||
after_cb: *u8,
|
||||
addr: *sockaddr_in6) -> libc::c_int;
|
||||
// FIXME ref #2064
|
||||
unsafe fn rust_uv_tcp_bind6(tcp_server: *uv_tcp_t,
|
||||
++addr: *sockaddr_in6) -> libc::c_int;
|
||||
addr: *sockaddr_in6) -> libc::c_int;
|
||||
unsafe fn rust_uv_tcp_getpeername(tcp_handle_ptr: *uv_tcp_t,
|
||||
++name: *sockaddr_in) -> libc::c_int;
|
||||
name: *sockaddr_in) -> libc::c_int;
|
||||
unsafe fn rust_uv_tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t,
|
||||
++name: *sockaddr_in6) ->libc::c_int;
|
||||
name: *sockaddr_in6) ->libc::c_int;
|
||||
unsafe fn rust_uv_listen(stream: *libc::c_void,
|
||||
backlog: libc::c_int,
|
||||
cb: *u8) -> libc::c_int;
|
||||
|
@ -804,7 +805,7 @@ extern mod rustrt {
|
|||
-> libc::c_int;
|
||||
unsafe fn rust_uv_write(req: *libc::c_void,
|
||||
stream: *libc::c_void,
|
||||
++buf_in: *uv_buf_t,
|
||||
buf_in: *uv_buf_t,
|
||||
buf_cnt: libc::c_int,
|
||||
cb: *u8)
|
||||
-> libc::c_int;
|
||||
|
@ -843,7 +844,7 @@ extern mod rustrt {
|
|||
unsafe fn rust_uv_addrinfo_as_sockaddr_in6(input: *addrinfo)
|
||||
-> *sockaddr_in6;
|
||||
unsafe fn rust_uv_malloc_buf_base_of(sug_size: libc::size_t) -> *u8;
|
||||
unsafe fn rust_uv_free_base_of_buf(++buf: uv_buf_t);
|
||||
unsafe fn rust_uv_free_base_of_buf(buf: uv_buf_t);
|
||||
unsafe fn rust_uv_get_stream_handle_from_connect_req(
|
||||
connect_req: *uv_connect_t)
|
||||
-> *uv_stream_t;
|
||||
|
@ -864,8 +865,8 @@ extern mod rustrt {
|
|||
-> *libc::c_void;
|
||||
unsafe fn rust_uv_set_data_for_req(req: *libc::c_void,
|
||||
data: *libc::c_void);
|
||||
unsafe fn rust_uv_get_base_from_buf(++buf: uv_buf_t) -> *u8;
|
||||
unsafe fn rust_uv_get_len_from_buf(++buf: uv_buf_t) -> libc::size_t;
|
||||
unsafe fn rust_uv_get_base_from_buf(buf: uv_buf_t) -> *u8;
|
||||
unsafe fn rust_uv_get_len_from_buf(buf: uv_buf_t) -> libc::size_t;
|
||||
|
||||
// sizeof testing helpers
|
||||
unsafe fn rust_uv_helper_uv_tcp_t_size() -> libc::c_uint;
|
||||
|
@ -1258,7 +1259,7 @@ mod test {
|
|||
|
||||
extern fn on_read_cb(stream: *uv_stream_t,
|
||||
nread: libc::ssize_t,
|
||||
++buf: uv_buf_t) {
|
||||
buf: uv_buf_t) {
|
||||
unsafe {
|
||||
let nread = nread as int;
|
||||
debug!("CLIENT entering on_read_cb nred: %d",
|
||||
|
@ -1444,7 +1445,7 @@ mod test {
|
|||
|
||||
extern fn on_server_read_cb(client_stream_ptr: *uv_stream_t,
|
||||
nread: libc::ssize_t,
|
||||
++buf: uv_buf_t) {
|
||||
buf: uv_buf_t) {
|
||||
unsafe {
|
||||
let nread = nread as int;
|
||||
if (nread > 0) {
|
||||
|
|
|
@ -1168,7 +1168,7 @@ pub type struct_field = spanned<struct_field_>;
|
|||
#[auto_decode]
|
||||
#[deriving(Eq)]
|
||||
pub enum struct_field_kind {
|
||||
named_field(ident, struct_mutability, visibility),
|
||||
named_field(ident, visibility),
|
||||
unnamed_field // element of a tuple-like struct
|
||||
}
|
||||
|
||||
|
@ -1218,17 +1218,6 @@ pub enum item_ {
|
|||
item_mac(mac),
|
||||
}
|
||||
|
||||
#[auto_encode]
|
||||
#[auto_decode]
|
||||
#[deriving(Eq)]
|
||||
pub enum struct_mutability { struct_mutable, struct_immutable }
|
||||
|
||||
impl to_bytes::IterBytes for struct_mutability {
|
||||
fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
|
||||
(*self as u8).iter_bytes(lsb0, f)
|
||||
}
|
||||
}
|
||||
|
||||
#[auto_encode]
|
||||
#[auto_decode]
|
||||
#[deriving(Eq)]
|
||||
|
@ -1289,6 +1278,21 @@ mod test {
|
|||
assert_eq! (s,~[14]);
|
||||
}
|
||||
|
||||
#[test] fn test_marksof () {
|
||||
let stopname = uints_to_name(&~[12,14,78]);
|
||||
assert_eq!(s,~[]);
|
||||
xorPush(&mut s,14);
|
||||
assert_eq!(s,~[14]);
|
||||
xorPush(&mut s,15);
|
||||
assert_eq!(s,~[14,15]);
|
||||
xorPush (&mut s,16);
|
||||
assert_eq! (s,~[14,15,16]);
|
||||
xorPush (&mut s,16);
|
||||
assert_eq! (s,~[14,15]);
|
||||
xorPush (&mut s,15);
|
||||
assert_eq! (s,~[14]);
|
||||
}
|
||||
|
||||
#[test] fn test_marksof () {
|
||||
let stopname = uints_to_name(&~[12,14,78]);
|
||||
let name1 = uints_to_name(&~[4,9,7]);
|
||||
|
@ -1347,3 +1351,12 @@ mod test {
|
|||
}
|
||||
|
||||
*/
|
||||
//
|
||||
// Local Variables:
|
||||
// mode: rust
|
||||
// fill-column: 78;
|
||||
// indent-tabs-mode: nil
|
||||
// c-basic-offset: 4
|
||||
// buffer-file-coding-system: utf-8-unix
|
||||
// End:
|
||||
//
|
||||
|
|
|
@ -285,7 +285,7 @@ pub fn split_trait_methods(trait_methods: &[trait_method])
|
|||
|
||||
pub fn struct_field_visibility(field: ast::struct_field) -> visibility {
|
||||
match field.node.kind {
|
||||
ast::named_field(_, _, visibility) => visibility,
|
||||
ast::named_field(_, visibility) => visibility,
|
||||
ast::unnamed_field => ast::public
|
||||
}
|
||||
}
|
||||
|
|
|
@ -914,19 +914,15 @@ struct field {
|
|||
|
||||
fn mk_struct_fields(fields: &[@ast::struct_field]) -> ~[field] {
|
||||
do fields.map |field| {
|
||||
let (ident, mutbl) = match field.node.kind {
|
||||
ast::named_field(ident, mutbl, _) => (ident, mutbl),
|
||||
_ => fail!(~"[auto_encode] does not support \
|
||||
unnamed fields")
|
||||
let ident = match field.node.kind {
|
||||
ast::named_field(ident, _) => ident,
|
||||
_ => fail!(~"[auto_encode] does not support unnamed fields")
|
||||
};
|
||||
|
||||
field {
|
||||
span: field.span,
|
||||
ident: ident,
|
||||
mutbl: match mutbl {
|
||||
ast::struct_mutable => ast::m_mutbl,
|
||||
ast::struct_immutable => ast::m_imm,
|
||||
},
|
||||
mutbl: ast::m_imm,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
use ast;
|
||||
use codemap;
|
||||
use codemap::span;
|
||||
use fold;
|
||||
use ext::base::ext_ctxt;
|
||||
use ext::build;
|
||||
|
||||
|
@ -516,3 +517,20 @@ pub fn mk_unreachable(cx: @ext_ctxt, span: span) -> @ast::expr {
|
|||
pub fn mk_unreachable_arm(cx: @ext_ctxt, span: span) -> ast::arm {
|
||||
mk_arm(cx, span, ~[mk_pat_wild(cx, span)], mk_unreachable(cx, span))
|
||||
}
|
||||
|
||||
//
|
||||
// Duplication functions
|
||||
//
|
||||
// These functions just duplicate AST nodes.
|
||||
//
|
||||
|
||||
pub fn duplicate_expr(cx: @ext_ctxt, expr: @ast::expr) -> @ast::expr {
|
||||
let folder = fold::default_ast_fold();
|
||||
let folder = @fold::AstFoldFns {
|
||||
new_id: |_| cx.next_id(),
|
||||
..*folder
|
||||
};
|
||||
let folder = fold::make_fold(folder);
|
||||
folder.fold_expr(expr)
|
||||
}
|
||||
|
||||
|
|
|
@ -280,7 +280,7 @@ fn expand_deriving_decodable_struct_method(
|
|||
let mut fields = ~[];
|
||||
for struct_def.fields.each |struct_field| {
|
||||
match struct_field.node.kind {
|
||||
named_field(ident, _, _) => {
|
||||
named_field(ident, _) => {
|
||||
fields.push(create_read_struct_field(cx, span, i, ident));
|
||||
}
|
||||
unnamed_field => {
|
||||
|
|
|
@ -211,7 +211,7 @@ fn expand_deriving_encodable_struct_method(
|
|||
let mut statements = ~[];
|
||||
for struct_def.fields.each |struct_field| {
|
||||
match struct_field.node.kind {
|
||||
named_field(ident, _, _) => {
|
||||
named_field(ident, _) => {
|
||||
// Create the accessor for this field.
|
||||
let self_field = build::mk_access(
|
||||
cx,
|
||||
|
|
|
@ -818,12 +818,8 @@ fn summarise_struct(cx: @ext_ctxt, span: span,
|
|||
let mut unnamed_count = 0;
|
||||
for struct_def.fields.each |field| {
|
||||
match field.node.kind {
|
||||
ast::named_field(ident, _, _) => {
|
||||
named_idents.push(ident)
|
||||
}
|
||||
ast::unnamed_field => {
|
||||
unnamed_count += 1;
|
||||
}
|
||||
ast::named_field(ident, _) => named_idents.push(ident),
|
||||
ast::unnamed_field => unnamed_count += 1,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -90,4 +90,4 @@ fn iter_bytes_substructure(cx: @ext_ctxt, span: span, substr: &Substructure) ->
|
|||
}
|
||||
|
||||
build::mk_block(cx, span, ~[], stmts, None)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -281,8 +281,8 @@ pub fn create_struct_pattern(cx: @ext_ctxt,
|
|||
|
||||
for struct_def.fields.eachi |i, struct_field| {
|
||||
let opt_id = match struct_field.node.kind {
|
||||
ast::named_field(ident, _, _) if (struct_type == Unknown ||
|
||||
struct_type == Record) => {
|
||||
ast::named_field(ident, _) if (struct_type == Unknown ||
|
||||
struct_type == Record) => {
|
||||
struct_type = Record;
|
||||
Some(ident)
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ pub fn expand_deriving_rand(cx: @ext_ctxt,
|
|||
self_ty: None,
|
||||
args: ~[
|
||||
Ptr(~Literal(Path::new_local(~"R")),
|
||||
Borrowed(None, ast::m_imm))
|
||||
Borrowed(None, ast::m_mutbl))
|
||||
],
|
||||
ret_ty: Self,
|
||||
const_nonmatching: false,
|
||||
|
@ -59,8 +59,10 @@ fn rand_substructure(cx: @ext_ctxt, span: span, substr: &Substructure) -> @expr
|
|||
cx.ident_of(~"rand")
|
||||
];
|
||||
let rand_call = || {
|
||||
build::mk_call_global(cx, span,
|
||||
copy rand_ident, copy rng)
|
||||
build::mk_call_global(cx,
|
||||
span,
|
||||
copy rand_ident,
|
||||
~[ build::duplicate_expr(cx, rng[0]) ])
|
||||
};
|
||||
|
||||
return match *substr.fields {
|
||||
|
@ -80,7 +82,10 @@ fn rand_substructure(cx: @ext_ctxt, span: span, substr: &Substructure) -> @expr
|
|||
let rand_name = build::mk_raw_path_(span, copy rand_ident, None, ~[ u32_ty, r_ty ]);
|
||||
let rand_name = build::mk_path_raw(cx, span, rand_name);
|
||||
|
||||
let rv_call = build::mk_call_(cx, span, rand_name, copy rng);
|
||||
let rv_call = build::mk_call_(cx,
|
||||
span,
|
||||
rand_name,
|
||||
~[ build::duplicate_expr(cx, rng[0]) ]);
|
||||
|
||||
// rand() % variants.len()
|
||||
let rand_variant = build::mk_binary(cx, span, ast::rem,
|
||||
|
@ -133,4 +138,4 @@ fn rand_substructure(cx: @ext_ctxt, span: span, substr: &Substructure) -> @expr
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,6 +64,7 @@ impl gen_send for message {
|
|||
|
||||
let mut body = ~"{\n";
|
||||
body += fmt!("use super::%s;\n", name);
|
||||
body += ~"let mut pipe = pipe;\n";
|
||||
|
||||
if this.proto.is_bounded() {
|
||||
let (sp, rp) = match (this.dir, next.dir) {
|
||||
|
@ -73,12 +74,12 @@ impl gen_send for message {
|
|||
(recv, recv) => (~"c", ~"s")
|
||||
};
|
||||
|
||||
body += ~"let b = pipe.reuse_buffer();\n";
|
||||
body += ~"let mut b = pipe.reuse_buffer();\n";
|
||||
body += fmt!("let %s = ::core::pipes::SendPacketBuffered(\
|
||||
&(b.buffer.data.%s));\n",
|
||||
&mut (b.buffer.data.%s));\n",
|
||||
sp, next.name);
|
||||
body += fmt!("let %s = ::core::pipes::RecvPacketBuffered(\
|
||||
&(b.buffer.data.%s));\n",
|
||||
&mut (b.buffer.data.%s));\n",
|
||||
rp, next.name);
|
||||
}
|
||||
else {
|
||||
|
@ -366,7 +367,7 @@ impl gen_init for protocol {
|
|||
fmt!("data.%s.set_buffer(buffer)",
|
||||
s.name))),
|
||||
ext_cx.parse_expr(fmt!(
|
||||
"::core::ptr::to_unsafe_ptr(&(data.%s))",
|
||||
"::core::ptr::to_mut_unsafe_ptr(&mut (data.%s))",
|
||||
self.states[0].name))));
|
||||
|
||||
quote_expr!({
|
||||
|
@ -410,10 +411,8 @@ impl gen_init for protocol {
|
|||
|
||||
@spanned {
|
||||
node: ast::struct_field_ {
|
||||
kind: ast::named_field(
|
||||
cx.ident_of(s.name),
|
||||
ast::struct_immutable,
|
||||
ast::inherited),
|
||||
kind: ast::named_field(cx.ident_of(s.name),
|
||||
ast::inherited),
|
||||
id: cx.next_id(),
|
||||
ty: fty,
|
||||
attrs: ~[],
|
||||
|
|
|
@ -859,3 +859,4 @@ impl AstFoldExtensions for @ast_fold {
|
|||
pub fn make_fold(afp: ast_fold_fns) -> @ast_fold {
|
||||
afp as @ast_fold
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ use ast::{pat_tup, pat_uniq, pat_wild, private};
|
|||
use ast::{rem, required};
|
||||
use ast::{ret_style, return_val, self_ty, shl, shr, stmt, stmt_decl};
|
||||
use ast::{stmt_expr, stmt_semi, stmt_mac, struct_def, struct_field};
|
||||
use ast::{struct_immutable, struct_mutable, struct_variant_kind, subtract};
|
||||
use ast::{struct_variant_kind, subtract};
|
||||
use ast::{sty_box, sty_region, sty_static, sty_uniq, sty_value};
|
||||
use ast::{token_tree, trait_method, trait_ref, tt_delim, tt_seq, tt_tok};
|
||||
use ast::{tt_nonterminal, tuple_variant_kind, Ty, ty_, ty_bot, ty_box};
|
||||
|
@ -390,8 +390,8 @@ pub impl Parser {
|
|||
// parse a ty_closure type
|
||||
fn parse_ty_closure(&self,
|
||||
sigil: ast::Sigil,
|
||||
region: Option<@ast::Lifetime>) -> ty_
|
||||
{
|
||||
region: Option<@ast::Lifetime>)
|
||||
-> ty_ {
|
||||
/*
|
||||
|
||||
(&|~|@) ['r] [pure|unsafe] [once] fn <'lt> (S) -> T
|
||||
|
@ -773,20 +773,17 @@ pub impl Parser {
|
|||
return ty_rptr(opt_lifetime, mt);
|
||||
}
|
||||
|
||||
// parse an optional mode.
|
||||
// XXX: Remove after snapshot.
|
||||
// parse an optional, obsolete argument mode.
|
||||
fn parse_arg_mode(&self) {
|
||||
if self.eat(&token::BINOP(token::MINUS)) {
|
||||
self.obsolete(*self.span, ObsoleteMode);
|
||||
} else if self.eat(&token::ANDAND) {
|
||||
// Ignore.
|
||||
self.obsolete(*self.span, ObsoleteMode);
|
||||
} else if self.eat(&token::BINOP(token::PLUS)) {
|
||||
if self.eat(&token::BINOP(token::PLUS)) {
|
||||
// ++ mode is obsolete, but we need a snapshot
|
||||
// to stop parsing it.
|
||||
// Ignore.
|
||||
self.obsolete(*self.span, ObsoleteMode);
|
||||
} else {
|
||||
// Ignore.
|
||||
self.obsolete(*self.span, ObsoleteMode);
|
||||
}
|
||||
} else {
|
||||
// Ignore.
|
||||
|
@ -2528,10 +2525,10 @@ pub impl Parser {
|
|||
fn parse_name_and_ty(&self,
|
||||
pr: visibility,
|
||||
attrs: ~[attribute]) -> @struct_field {
|
||||
let mut is_mutbl = struct_immutable;
|
||||
let lo = self.span.lo;
|
||||
if self.eat_keyword(&~"mut") {
|
||||
is_mutbl = struct_mutable;
|
||||
// Do nothing, for backwards compatibility.
|
||||
// XXX: Remove after snapshot.
|
||||
}
|
||||
if !is_plain_ident(&*self.token) {
|
||||
self.fatal(~"expected ident");
|
||||
|
@ -2540,7 +2537,7 @@ pub impl Parser {
|
|||
self.expect(&token::COLON);
|
||||
let ty = self.parse_ty(false);
|
||||
@spanned(lo, self.last_span.hi, ast::struct_field_ {
|
||||
kind: named_field(name, is_mutbl, pr),
|
||||
kind: named_field(name, pr),
|
||||
id: self.get_id(),
|
||||
ty: ty,
|
||||
attrs: attrs,
|
||||
|
|
|
@ -703,14 +703,11 @@ pub fn print_struct(s: @ps,
|
|||
for struct_def.fields.each |field| {
|
||||
match field.node.kind {
|
||||
ast::unnamed_field => fail!(~"unexpected unnamed field"),
|
||||
ast::named_field(ident, mutability, visibility) => {
|
||||
ast::named_field(ident, visibility) => {
|
||||
hardbreak_if_not_bol(s);
|
||||
maybe_print_comment(s, field.span.lo);
|
||||
print_outer_attributes(s, field.node.attrs);
|
||||
print_visibility(s, visibility);
|
||||
if mutability == ast::struct_mutable {
|
||||
word_nbsp(s, ~"mut");
|
||||
}
|
||||
print_ident(s, ident);
|
||||
word_nbsp(s, ~":");
|
||||
print_type(s, field.node.ty);
|
||||
|
|
|
@ -84,7 +84,7 @@ pub impl<T:Eq + IterBytes + Hash + Const + Copy> Interner<T> {
|
|||
* for another case of this. */
|
||||
macro_rules! interner_key (
|
||||
() => (cast::transmute::<(uint, uint),
|
||||
&fn(+v: @@::parse::token::ident_interner)>(
|
||||
&fn(v: @@::parse::token::ident_interner)>(
|
||||
(-3 as uint, 0u)))
|
||||
)
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ pub mod kitties {
|
|||
fn meow_count(&mut self) -> uint { self.meows }
|
||||
}
|
||||
|
||||
pub fn cat<U>(in_x : uint, in_y : int, +in_info: ~[U]) -> cat<U> {
|
||||
pub fn cat<U>(in_x : uint, in_y : int, in_info: ~[U]) -> cat<U> {
|
||||
cat {
|
||||
meows: in_x,
|
||||
how_hungry: in_y,
|
||||
|
|
|
@ -103,7 +103,7 @@ fn main() {
|
|||
let mut rand = vec::with_capacity(n_keys);
|
||||
|
||||
{
|
||||
let rng = core::rand::IsaacRng::new_seeded([1, 1, 1, 1, 1, 1, 1]);
|
||||
let mut rng = core::rand::IsaacRng::new_seeded([1, 1, 1, 1, 1, 1, 1]);
|
||||
let mut set = HashSet::new();
|
||||
while set.len() != n_keys {
|
||||
let next = rng.next() as uint;
|
||||
|
|
|
@ -31,8 +31,13 @@ fn timed(result: &mut float, op: &fn()) {
|
|||
}
|
||||
|
||||
pub impl Results {
|
||||
fn bench_int<T:Set<uint>, R: rand::Rng>(&mut self, rng: &R, num_keys: uint,
|
||||
rand_cap: uint, f: &fn() -> T) {
|
||||
fn bench_int<T:Set<uint>,
|
||||
R: rand::Rng>(
|
||||
&mut self,
|
||||
rng: &mut R,
|
||||
num_keys: uint,
|
||||
rand_cap: uint,
|
||||
f: &fn() -> T) {
|
||||
{
|
||||
let mut set = f();
|
||||
do timed(&mut self.sequential_ints) {
|
||||
|
@ -69,8 +74,12 @@ pub impl Results {
|
|||
}
|
||||
}
|
||||
|
||||
fn bench_str<T:Set<~str>, R: rand::Rng>(&mut self, rng: &R, num_keys: uint,
|
||||
f: &fn() -> T) {
|
||||
fn bench_str<T:Set<~str>,
|
||||
R:rand::Rng>(
|
||||
&mut self,
|
||||
rng: &mut R,
|
||||
num_keys: uint,
|
||||
f: &fn() -> T) {
|
||||
{
|
||||
let mut set = f();
|
||||
do timed(&mut self.sequential_strings) {
|
||||
|
@ -155,25 +164,25 @@ fn main() {
|
|||
let max = 200000;
|
||||
|
||||
{
|
||||
let rng = rand::IsaacRng::new_seeded(seed);
|
||||
let mut rng = rand::IsaacRng::new_seeded(seed);
|
||||
let mut results = empty_results();
|
||||
results.bench_int(&rng, num_keys, max, || HashSet::new::<uint>());
|
||||
results.bench_str(&rng, num_keys, || HashSet::new::<~str>());
|
||||
results.bench_int(&mut rng, num_keys, max, || HashSet::new::<uint>());
|
||||
results.bench_str(&mut rng, num_keys, || HashSet::new::<~str>());
|
||||
write_results("core::hashmap::HashSet", &results);
|
||||
}
|
||||
|
||||
{
|
||||
let rng = rand::IsaacRng::new_seeded(seed);
|
||||
let mut rng = rand::IsaacRng::new_seeded(seed);
|
||||
let mut results = empty_results();
|
||||
results.bench_int(&rng, num_keys, max, || TreeSet::new::<uint>());
|
||||
results.bench_str(&rng, num_keys, || TreeSet::new::<~str>());
|
||||
results.bench_int(&mut rng, num_keys, max, || TreeSet::new::<uint>());
|
||||
results.bench_str(&mut rng, num_keys, || TreeSet::new::<~str>());
|
||||
write_results("std::treemap::TreeSet", &results);
|
||||
}
|
||||
|
||||
{
|
||||
let rng = rand::IsaacRng::new_seeded(seed);
|
||||
let mut rng = rand::IsaacRng::new_seeded(seed);
|
||||
let mut results = empty_results();
|
||||
results.bench_int(&rng, num_keys, max, || BitvSet::new());
|
||||
results.bench_int(&mut rng, num_keys, max, || BitvSet::new());
|
||||
write_results("std::bitv::BitvSet", &results);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,12 +33,15 @@ fn main() {
|
|||
fn maybe_run_test(argv: &[~str], name: ~str, test: &fn()) {
|
||||
let mut run_test = false;
|
||||
|
||||
if os::getenv(~"RUST_BENCH").is_some() { run_test = true }
|
||||
else if argv.len() > 0 {
|
||||
if os::getenv(~"RUST_BENCH").is_some() {
|
||||
run_test = true
|
||||
} else if argv.len() > 0 {
|
||||
run_test = argv.contains(&~"all") || argv.contains(&name)
|
||||
}
|
||||
|
||||
if !run_test { return }
|
||||
if !run_test {
|
||||
return
|
||||
}
|
||||
|
||||
let start = precise_time_s();
|
||||
test();
|
||||
|
@ -69,7 +72,7 @@ fn read_line() {
|
|||
}
|
||||
|
||||
fn vec_plus() {
|
||||
let r = rand::rng();
|
||||
let mut r = rand::rng();
|
||||
|
||||
let mut v = ~[];
|
||||
let mut i = 0;
|
||||
|
@ -86,7 +89,7 @@ fn vec_plus() {
|
|||
}
|
||||
|
||||
fn vec_append() {
|
||||
let r = rand::rng();
|
||||
let mut r = rand::rng();
|
||||
|
||||
let mut v = ~[];
|
||||
let mut i = 0;
|
||||
|
@ -103,7 +106,7 @@ fn vec_append() {
|
|||
}
|
||||
|
||||
fn vec_push_all() {
|
||||
let r = rand::rng();
|
||||
let mut r = rand::rng();
|
||||
|
||||
let mut v = ~[];
|
||||
for uint::range(0, 1500) |i| {
|
||||
|
|
|
@ -32,19 +32,20 @@ type graph = ~[~[node_id]];
|
|||
type bfs_result = ~[node_id];
|
||||
|
||||
fn make_edges(scale: uint, edgefactor: uint) -> ~[(node_id, node_id)] {
|
||||
let r = rand::XorShiftRng::new();
|
||||
|
||||
fn choose_edge<R: rand::Rng>(i: node_id, j: node_id, scale: uint, r: &R)
|
||||
-> (node_id, node_id) {
|
||||
let mut r = rand::XorShiftRng::new();
|
||||
|
||||
fn choose_edge<R: rand::Rng>(i: node_id,
|
||||
j: node_id,
|
||||
scale: uint,
|
||||
r: &mut R)
|
||||
-> (node_id, node_id) {
|
||||
let A = 0.57;
|
||||
let B = 0.19;
|
||||
let C = 0.19;
|
||||
|
||||
if scale == 0u {
|
||||
(i, j)
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
let i = i * 2i64;
|
||||
let j = j * 2i64;
|
||||
let scale = scale - 1u;
|
||||
|
@ -73,7 +74,7 @@ fn make_edges(scale: uint, edgefactor: uint) -> ~[(node_id, node_id)] {
|
|||
}
|
||||
|
||||
do vec::from_fn((1u << scale) * edgefactor) |_i| {
|
||||
choose_edge(0i64, 0i64, scale, &r)
|
||||
choose_edge(0i64, 0i64, scale, &mut r)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -103,7 +104,7 @@ fn make_graph(N: uint, edges: ~[(node_id, node_id)]) -> graph {
|
|||
|
||||
fn gen_search_keys(graph: &[~[node_id]], n: uint) -> ~[node_id] {
|
||||
let mut keys = HashSet::new();
|
||||
let r = rand::rng();
|
||||
let mut r = rand::rng();
|
||||
|
||||
while keys.len() < n {
|
||||
let k = r.gen_uint_range(0u, graph.len());
|
||||
|
@ -272,7 +273,7 @@ fn pbfs(graph: &arc::ARC<graph>, key: node_id) -> bfs_result {
|
|||
colors = do par::mapi(*color_vec) {
|
||||
let colors = arc::clone(&color);
|
||||
let graph = arc::clone(graph);
|
||||
let result: ~fn(+x: uint, +y: &color) -> color = |i, c| {
|
||||
let result: ~fn(x: uint, y: &color) -> color = |i, c| {
|
||||
let colors = arc::get(&colors);
|
||||
let graph = arc::get(&graph);
|
||||
match *c {
|
||||
|
@ -394,7 +395,7 @@ fn validate(edges: ~[(node_id, node_id)],
|
|||
|
||||
let status = do par::alli(tree) {
|
||||
let edges = copy edges;
|
||||
let result: ~fn(+x: uint, v: &i64) -> bool = |u, v| {
|
||||
let result: ~fn(x: uint, v: &i64) -> bool = |u, v| {
|
||||
let u = u as node_id;
|
||||
if *v == -1i64 || u == root {
|
||||
true
|
||||
|
|
|
@ -65,15 +65,15 @@ fn run(args: &[~str]) {
|
|||
let mut worker_results = ~[];
|
||||
for uint::range(0, workers) |_i| {
|
||||
let to_child = to_child.clone();
|
||||
do task::task().future_result(|+r| {
|
||||
worker_results.push(r);
|
||||
}).spawn || {
|
||||
let mut builder = task::task();
|
||||
builder.future_result(|r| worker_results.push(r));
|
||||
do builder.spawn {
|
||||
for uint::range(0, size / workers) |_i| {
|
||||
//error!("worker %?: sending %? bytes", i, num_bytes);
|
||||
to_child.send(bytes(num_bytes));
|
||||
}
|
||||
//error!("worker %? exiting", i);
|
||||
};
|
||||
}
|
||||
}
|
||||
do task::spawn || {
|
||||
server(&from_parent, &to_parent);
|
||||
|
|
|
@ -62,9 +62,9 @@ fn run(args: &[~str]) {
|
|||
for uint::range(0, workers) |_i| {
|
||||
let (from_parent_, to_child) = stream();
|
||||
from_parent.add(from_parent_);
|
||||
do task::task().future_result(|+r| {
|
||||
worker_results.push(r);
|
||||
}).spawn || {
|
||||
let mut builder = task::task();
|
||||
builder.future_result(|r| worker_results.push(r));
|
||||
do builder.spawn {
|
||||
for uint::range(0, size / workers) |_i| {
|
||||
//error!("worker %?: sending %? bytes", i, num_bytes);
|
||||
to_child.send(bytes(num_bytes));
|
||||
|
|
|
@ -45,10 +45,7 @@ fn init() -> (pipe,pipe) {
|
|||
}
|
||||
|
||||
|
||||
fn thread_ring(i: uint,
|
||||
count: uint,
|
||||
+num_chan: pipe,
|
||||
+num_port: pipe) {
|
||||
fn thread_ring(i: uint, count: uint, num_chan: pipe, num_port: pipe) {
|
||||
let mut num_chan = Some(num_chan);
|
||||
let mut num_port = Some(num_port);
|
||||
// Send/Receive lots of messages.
|
||||
|
@ -103,7 +100,9 @@ fn main() {
|
|||
thread_ring(0, msg_per_task, num_chan.take(), num_port);
|
||||
|
||||
// synchronize
|
||||
for futures.each |f| { f.get() };
|
||||
for futures.each_mut |f| {
|
||||
f.get()
|
||||
}
|
||||
|
||||
let stop = time::precise_time_s();
|
||||
|
||||
|
|
|
@ -35,8 +35,8 @@ macro_rules! move_out (
|
|||
|
||||
fn thread_ring(i: uint,
|
||||
count: uint,
|
||||
+num_chan: ring::client::num,
|
||||
+num_port: ring::server::num) {
|
||||
num_chan: ring::client::num,
|
||||
num_port: ring::server::num) {
|
||||
let mut num_chan = Some(num_chan);
|
||||
let mut num_port = Some(num_port);
|
||||
// Send/Receive lots of messages.
|
||||
|
@ -96,7 +96,9 @@ fn main() {
|
|||
thread_ring(0, msg_per_task, num_chan.take(), num_port);
|
||||
|
||||
// synchronize
|
||||
for futures.each |f| { f.get() };
|
||||
for futures.each_mut |f| {
|
||||
let _ = f.get();
|
||||
}
|
||||
|
||||
let stop = time::precise_time_s();
|
||||
|
||||
|
|
|
@ -46,10 +46,7 @@ fn init() -> (pipe,pipe) {
|
|||
}
|
||||
|
||||
|
||||
fn thread_ring(i: uint,
|
||||
count: uint,
|
||||
+num_chan: pipe,
|
||||
+num_port: pipe) {
|
||||
fn thread_ring(i: uint, count: uint, num_chan: pipe, num_port: pipe) {
|
||||
let mut num_chan = Some(num_chan);
|
||||
let mut num_port = Some(num_port);
|
||||
// Send/Receive lots of messages.
|
||||
|
@ -104,7 +101,9 @@ fn main() {
|
|||
thread_ring(0, msg_per_task, num_chan.take(), num_port);
|
||||
|
||||
// synchronize
|
||||
for futures.each |f| { f.get() };
|
||||
for futures.each_mut |f| {
|
||||
let _ = f.get();
|
||||
}
|
||||
|
||||
let stop = time::precise_time_s();
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ fn lerp(a: f32, b: f32, v: f32) -> f32 { a * (1.0 - v) + b * v }
|
|||
#[inline(always)]
|
||||
fn smooth(v: f32) -> f32 { v * v * (3.0 - 2.0 * v) }
|
||||
|
||||
fn random_gradient<R:Rng>(r: &R) -> Vec2 {
|
||||
fn random_gradient<R:Rng>(r: &mut R) -> Vec2 {
|
||||
let v = 2.0 * float::consts::pi * r.gen();
|
||||
Vec2 {
|
||||
x: float::cos(v) as f32,
|
||||
|
@ -33,11 +33,15 @@ struct Noise2DContext {
|
|||
|
||||
pub impl Noise2DContext {
|
||||
fn new() -> Noise2DContext {
|
||||
let r = rand::rng();
|
||||
let mut r = rand::rng();
|
||||
let mut rgradients = [ Vec2 { x: 0.0, y: 0.0 }, ..256 ];
|
||||
for int::range(0, 256) |i| { rgradients[i] = random_gradient(&r); }
|
||||
for int::range(0, 256) |i| {
|
||||
rgradients[i] = random_gradient(&mut r);
|
||||
}
|
||||
let mut permutations = [ 0, ..256 ];
|
||||
for int::range(0, 256) |i| { permutations[i] = i; }
|
||||
for int::range(0, 256) |i| {
|
||||
permutations[i] = i;
|
||||
}
|
||||
r.shuffle_mut(permutations);
|
||||
|
||||
Noise2DContext {
|
||||
|
@ -53,7 +57,11 @@ pub impl Noise2DContext {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn get_gradients(&self, gradients: &mut [Vec2, ..4], origins: &mut [Vec2, ..4], x: f32, y: f32) {
|
||||
fn get_gradients(&self,
|
||||
gradients: &mut [Vec2, ..4],
|
||||
origins: &mut [Vec2, ..4],
|
||||
x: f32,
|
||||
y: f32) {
|
||||
let x0f = f32::floor(x);
|
||||
let y0f = f32::floor(y);
|
||||
let x0 = x0f as int;
|
||||
|
|
|
@ -117,8 +117,9 @@ pub fn spawn_service_recv<T:Owned,Tb:Owned>(
|
|||
client
|
||||
}
|
||||
|
||||
fn switch<T:Owned,Tb:Owned,U>(+endp: core::pipes::RecvPacketBuffered<T, Tb>,
|
||||
f: &fn(+v: Option<T>) -> U) -> U {
|
||||
fn switch<T:Owned,Tb:Owned,U>(endp: core::pipes::RecvPacketBuffered<T, Tb>,
|
||||
f: &fn(v: Option<T>) -> U)
|
||||
-> U {
|
||||
f(core::pipes::try_recv(endp))
|
||||
}
|
||||
|
||||
|
|
|
@ -63,7 +63,10 @@ fn make_random_fasta(wr: @io::Writer,
|
|||
genelist: ~[AminoAcids],
|
||||
n: int) {
|
||||
wr.write_line(~">" + id + ~" " + desc);
|
||||
let rng = @mut MyRandom {last: rand::rng().next()};
|
||||
let mut rng = rand::rng();
|
||||
let rng = @mut MyRandom {
|
||||
last: rng.next()
|
||||
};
|
||||
let mut op: ~str = ~"";
|
||||
for uint::range(0u, n as uint) |_i| {
|
||||
str::push_char(&mut op, select_random(myrandom_next(rng, 100u32),
|
||||
|
|
|
@ -26,7 +26,6 @@ use core::int::range;
|
|||
use core::comm::*;
|
||||
use core::io::WriterUtil;
|
||||
|
||||
use core::result;
|
||||
use core::result::{Ok, Err};
|
||||
|
||||
fn fib(n: int) -> int {
|
||||
|
@ -67,7 +66,7 @@ fn parse_opts(argv: ~[~str]) -> Config {
|
|||
}
|
||||
}
|
||||
|
||||
fn stress_task(&&id: int) {
|
||||
fn stress_task(id: int) {
|
||||
let mut i = 0;
|
||||
loop {
|
||||
let n = 15;
|
||||
|
@ -80,13 +79,15 @@ fn stress_task(&&id: int) {
|
|||
fn stress(num_tasks: int) {
|
||||
let mut results = ~[];
|
||||
for range(0, num_tasks) |i| {
|
||||
do task::task().future_result(|+r| {
|
||||
results.push(r);
|
||||
}).spawn {
|
||||
let mut builder = task::task();
|
||||
builder.future_result(|r| results.push(r));
|
||||
do builder.spawn {
|
||||
stress_task(i);
|
||||
}
|
||||
}
|
||||
for results.each |r| { r.recv(); }
|
||||
for results.each |r| {
|
||||
r.recv();
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
|
|
@ -46,9 +46,12 @@ fn grandchild_group(num_tasks: uint) {
|
|||
// Master grandchild task exits early.
|
||||
}
|
||||
|
||||
fn spawn_supervised_blocking(myname: &str, +f: ~fn()) {
|
||||
fn spawn_supervised_blocking(myname: &str, f: ~fn()) {
|
||||
let mut res = None;
|
||||
task::task().future_result(|+r| res = Some(r)).supervised().spawn(f);
|
||||
let mut builder = task::task();
|
||||
builder.future_result(|r| res = Some(r));
|
||||
builder.supervised();
|
||||
builder.spawn(f);
|
||||
error!("%s group waiting", myname);
|
||||
let x = res.unwrap().recv();
|
||||
assert!(x == task::Success);
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
fn f(&&n: uint) {
|
||||
fn f(n: uint) {
|
||||
let mut i = 0u;
|
||||
while i < n {
|
||||
task::try(|| g() );
|
||||
|
|
|
@ -12,9 +12,9 @@
|
|||
// other tycons.
|
||||
|
||||
fn coerce(b: &fn()) -> extern fn() {
|
||||
fn lol(+f: extern fn(+v: &fn()) -> extern fn(),
|
||||
+g: &fn()) -> extern fn() { return f(g); }
|
||||
fn fn_id(+f: extern fn()) -> extern fn() { return f }
|
||||
fn lol(f: extern fn(v: &fn()) -> extern fn(),
|
||||
g: &fn()) -> extern fn() { return f(g); }
|
||||
fn fn_id(f: extern fn()) -> extern fn() { return f }
|
||||
return lol(fn_id, b);
|
||||
//~^ ERROR mismatched types
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue