<commit_before>//! Zero-cost Futures in Rust
//!
//! This library is an implementation of futures in Rust which aims to provide
//! a robust implementation of handling asynchronous computations, ergonomic
//! composition and usage, and zero-cost abstractions over what would otherwise
//! be written by hand.
//!
//! Futures are a concept for an object which is a proxy for another value that
//! may not be ready yet. For example issuing an HTTP request may return a
//! future for the HTTP response, as it probably hasn't arrived yet. With an
//! object representing a value that will eventually be available, futures allow
//! for powerful composition of tasks through basic combinators that can perform
//! operations like chaining computations, changing the types of futures, or
//! waiting for two futures to complete at the same time.
//!
//! ## Installation
//!
//! Add this to your `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! futures = "0.1"
//! ```
//!
//! ## Examples
//!
//! Let's take a look at a few examples of how futures might be used:
//!
//! ```
//! extern crate futures;
//!
//! use std::io;
//! use std::time::Duration;
//! use futures::{Future, Map};
//!
//! // A future is actually a trait implementation, so we can generically take a
//! // future of any integer and return back a future that will resolve to that
//! // value plus 10 more.
//! //
//! // Note here that like iterators, we're returning the `Map` combinator in
//! // the futures crate, not a boxed abstraction. This is a zero-cost
//! // construction of a future.
//! fn add_ten<F>(future: F) -> Map<F, fn(i32) -> i32>
//!     where F: Future<Item=i32>,
//! {
//!     fn add(a: i32) -> i32 { a + 10 }
//!     future.map(add)
//! }
//!
//! // Not only can we modify one future, but we can even compose them together!
//! // Here we have a function which takes two futures as input, and returns a
//! // future that will calculate the sum of their two values.
//! //
//! // Above we saw a direct return value of the `Map` combinator, but
//! // performance isn't always critical and sometimes it's more ergonomic to
//! // return a trait object like we do here. Note though that there's only one
//! // allocation here, not any for the intermediate futures.
//! fn add<'a, A, B>(a: A, b: B) -> Box<Future<Item=i32, Error=A::Error> + 'a>
//!     where A: Future<Item=i32> + 'a,
//!           B: Future<Item=i32, Error=A::Error> + 'a,
//! {
//!     Box::new(a.join(b).map(|(a, b)| a + b))
//! }
//!
//! // Futures also allow chaining computations together, starting another after
//! // the previous finishes. Here we wait for the first computation to finish,
//! // and then decide what to do depending on the result.
//! fn download_timeout(url: &str,
//!                     timeout_dur: Duration)
//!                     -> Box<Future<Item=Vec<u8>, Error=io::Error>> {
//!     use std::io;
//!     use std::net::{SocketAddr, TcpStream};
//!
//!     type IoFuture<T> = Box<Future<Item=T, Error=io::Error>>;
//!
//!     // First thing to do is we need to resolve our URL to an address. This
//!     // will likely perform a DNS lookup which may take some time.
//!     let addr = resolve(url);
//!
//!     // After we acquire the address, we next want to open up a TCP
//!     // connection.
//!     let tcp = addr.and_then(|addr| connect(&addr));
//!
//!     // After the TCP connection is established and ready to go, we're off to
//!     // the races!
//!     let data = tcp.and_then(|conn| download(conn));
//!
//!     // That all might take awhile, though, so let's not wait too long for it
//!     // to all come back. The `select` combinator here returns a future which
//!     // resolves to the first value that's ready plus the next future.
//!     //
//!     // Note we can also use the `then` combinator which which is similar to
//!     // `and_then` above except that it receives the result of the
//!     // computation, not just the successful value.
//!     //
//!     // Again note that all the above calls to `and_then` and the below calls
//!     // to `map` and such require no allocations. We only ever allocate once
//!     // we hit the `.boxed()` call at the end here, which means we've built
//!     // up a relatively involved computation with only one box, and even that
//!     // was optional!
//!
//!     let data = data.map(Ok);
//!     let timeout = timeout(timeout_dur).map(Err);
//!
//!     let ret = data.select(timeout).then(|result| {
//!         match result {
//!             // One future succeeded, and it was the one which was
//!             // downloading data from the connection.
//!             Ok((Ok(data), _other_future)) => Ok(data),
//!
//!             // The timeout fired, and otherwise no error was found, so
//!             // we translate this to an error.
//!             Ok((Err(_timeout), _other_future)) => {
//!                 Err(io::Error::new(io::ErrorKind::Other, "timeout"))
//!             }
//!
//!             // A normal I/O error happened, so we pass that on through.
//!             Err((e, _other_future)) => Err(e),
//!         }
//!     });
//!     return Box::new(ret);
//!
//!     fn resolve(url: &str) -> IoFuture<SocketAddr> {
//!         // ...
//! #       panic!("unimplemented");
//!     }
//!
//!     fn connect(hostname: &SocketAddr) -> IoFuture<TcpStream> {
//!         // ...
//! #       panic!("unimplemented");
//!     }
//!
//!     fn download(stream: TcpStream) -> IoFuture<Vec<u8>> {
//!         // ...
//! #       panic!("unimplemented");
//!     }
//!
//!     fn timeout(stream: Duration) -> IoFuture<()> {
//!         // ...
//! #       panic!("unimplemented");
//!     }
//! }
//! # fn main() {}
//! ```
//!
//! Some more information can also be found in the [README] for now, but
//! otherwise feel free to jump in to the docs below!
//!
//! [README]: https://github.com/alexcrichton/futures-rs#futures-rs

#![no_std]
#![deny(missing_docs)]
#![doc(html_root_url = "https://docs.rs/futures/0.1")]

#[macro_use]
#[cfg(feature = "use_std")]
extern crate std;

#[macro_use]
extern crate log;

macro_rules! if_std {
    ($($i:item)*) => ($(
        #[cfg(feature = "use_std")]
        $i
    )*)
}

#[macro_use]
mod poll;
pub use poll::{Poll, Async, AsyncSink, StartSend};

pub mod future;
pub use future::{Future, IntoFuture};

pub mod stream;
pub use stream::{Stream};

pub mod sink;
pub use sink::Sink;

#[deprecated(since = "0.1.4", note = "import through the future module instead")]
pub use future::{done, empty, failed, finished, lazy};

#[doc(hidden)]
#[deprecated(since = "0.1.4", note = "import through the future module instead")]
pub use future::{
    Done, Empty, Failed, Finished, Lazy, AndThen, Flatten, FlattenStream, Fuse, IntoStream,
    Join, Join3, Join4, Join5, Map, MapErr, OrElse, Select, SelectNext, Then
};

if_std! {
    mod lock;
    mod task_impl;

    pub mod task;
    pub mod executor;
    pub mod sync;

    #[doc(hidden)]
    #[deprecated(since = "0.1.4", note = "use sync::oneshot::channel instead")]
    pub use sync::oneshot::channel as oneshot;

    #[doc(hidden)]
    #[deprecated(since = "0.1.4", note = "use sync::oneshot::Receiver instead")]
    pub use sync::oneshot::Receiver as Oneshot;

    #[doc(hidden)]
    #[deprecated(since = "0.1.4", note = "use sync::oneshot::Sender instead")]
    pub use sync::oneshot::Sender as Complete;

    #[doc(hidden)]
    #[deprecated(since = "0.1.4", note = "use sync::oneshot::Canceled instead")]
    pub use sync::oneshot::Canceled;

    #[doc(hidden)]
    #[deprecated(since = "0.1.4", note = "import through the future module instead")]
    pub use future::{BoxFuture, collect, select_all, select_ok};
}
<commit_msg>Remove extra braces<commit_after>//! Zero-cost Futures in Rust
//!
//! This library is an implementation of futures in Rust which aims to provide
//! a robust implementation of handling asynchronous computations, ergonomic
//! composition and usage, and zero-cost abstractions over what would otherwise
//! be written by hand.
//!
//! Futures are a concept for an object which is a proxy for another value that
//! may not be ready yet. For example issuing an HTTP request may return a
//! future for the HTTP response, as it probably hasn't arrived yet. With an
//! object representing a value that will eventually be available, futures allow
//! for powerful composition of tasks through basic combinators that can perform
//! operations like chaining computations, changing the types of futures, or
//! waiting for two futures to complete at the same time.
//!
//! ## Installation
//!
//! Add this to your `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! futures = "0.1"
//! ```
//!
//! ## Examples
//!
//! Let's take a look at a few examples of how futures might be used:
//!
//! ```
//! extern crate futures;
//!
//! use std::io;
//! use std::time::Duration;
//! use futures::{Future, Map};
//!
//! // A future is actually a trait implementation, so we can generically take a
//! // future of any integer and return back a future that will resolve to that
//! // value plus 10 more.
//! //
//! // Note here that like iterators, we're returning the `Map` combinator in
//! // the futures crate, not a boxed abstraction. This is a zero-cost
//! // construction of a future.
//! fn add_ten<F>(future: F) -> Map<F, fn(i32) -> i32>
//!     where F: Future<Item=i32>,
//! {
//!     fn add(a: i32) -> i32 { a + 10 }
//!     future.map(add)
//! }
//!
//! // Not only can we modify one future, but we can even compose them together!
//! // Here we have a function which takes two futures as input, and returns a
//! // future that will calculate the sum of their two values.
//! //
//! // Above we saw a direct return value of the `Map` combinator, but
//! // performance isn't always critical and sometimes it's more ergonomic to
//! // return a trait object like we do here. Note though that there's only one
//! // allocation here, not any for the intermediate futures.
//! fn add<'a, A, B>(a: A, b: B) -> Box<Future<Item=i32, Error=A::Error> + 'a>
//!     where A: Future<Item=i32> + 'a,
//!           B: Future<Item=i32, Error=A::Error> + 'a,
//! {
//!     Box::new(a.join(b).map(|(a, b)| a + b))
//! }
//!
//! // Futures also allow chaining computations together, starting another after
//! // the previous finishes. Here we wait for the first computation to finish,
//! // and then decide what to do depending on the result.
//! fn download_timeout(url: &str,
//!                     timeout_dur: Duration)
//!                     -> Box<Future<Item=Vec<u8>, Error=io::Error>> {
//!     use std::io;
//!     use std::net::{SocketAddr, TcpStream};
//!
//!     type IoFuture<T> = Box<Future<Item=T, Error=io::Error>>;
//!
//!     // First thing to do is we need to resolve our URL to an address. This
//!     // will likely perform a DNS lookup which may take some time.
//!     let addr = resolve(url);
//!
//!     // After we acquire the address, we next want to open up a TCP
//!     // connection.
//!     let tcp = addr.and_then(|addr| connect(&addr));
//!
//!     // After the TCP connection is established and ready to go, we're off to
//!     // the races!
//!     let data = tcp.and_then(|conn| download(conn));
//!
//!     // That all might take awhile, though, so let's not wait too long for it
//!     // to all come back. The `select` combinator here returns a future which
//!     // resolves to the first value that's ready plus the next future.
//!     //
//!     // Note we can also use the `then` combinator which which is similar to
//!     // `and_then` above except that it receives the result of the
//!     // computation, not just the successful value.
//!     //
//!     // Again note that all the above calls to `and_then` and the below calls
//!     // to `map` and such require no allocations. We only ever allocate once
//!     // we hit the `.boxed()` call at the end here, which means we've built
//!     // up a relatively involved computation with only one box, and even that
//!     // was optional!
//!
//!     let data = data.map(Ok);
//!     let timeout = timeout(timeout_dur).map(Err);
//!
//!     let ret = data.select(timeout).then(|result| {
//!         match result {
//!             // One future succeeded, and it was the one which was
//!             // downloading data from the connection.
//!             Ok((Ok(data), _other_future)) => Ok(data),
//!
//!             // The timeout fired, and otherwise no error was found, so
//!             // we translate this to an error.
//!             Ok((Err(_timeout), _other_future)) => {
//!                 Err(io::Error::new(io::ErrorKind::Other, "timeout"))
//!             }
//!
//!             // A normal I/O error happened, so we pass that on through.
//!             Err((e, _other_future)) => Err(e),
//!         }
//!     });
//!     return Box::new(ret);
//!
//!     fn resolve(url: &str) -> IoFuture<SocketAddr> {
//!         // ...
//! #       panic!("unimplemented");
//!     }
//!
//!     fn connect(hostname: &SocketAddr) -> IoFuture<TcpStream> {
//!         // ...
//! #       panic!("unimplemented");
//!     }
//!
//!     fn download(stream: TcpStream) -> IoFuture<Vec<u8>> {
//!         // ...
//! #       panic!("unimplemented");
//!     }
//!
//!     fn timeout(stream: Duration) -> IoFuture<()> {
//!         // ...
//! #       panic!("unimplemented");
//!     }
//! }
//! # fn main() {}
//! ```
//!
//! Some more information can also be found in the [README] for now, but
//! otherwise feel free to jump in to the docs below!
//!
//! [README]: https://github.com/alexcrichton/futures-rs#futures-rs

#![no_std]
#![deny(missing_docs)]
#![doc(html_root_url = "https://docs.rs/futures/0.1")]

#[macro_use]
#[cfg(feature = "use_std")]
extern crate std;

#[macro_use]
extern crate log;

macro_rules! if_std {
    ($($i:item)*) => ($(
        #[cfg(feature = "use_std")]
        $i
    )*)
}

#[macro_use]
mod poll;
pub use poll::{Poll, Async, AsyncSink, StartSend};

pub mod future;
pub use future::{Future, IntoFuture};

pub mod stream;
pub use stream::Stream;

pub mod sink;
pub use sink::Sink;

#[deprecated(since = "0.1.4", note = "import through the future module instead")]
pub use future::{done, empty, failed, finished, lazy};

#[doc(hidden)]
#[deprecated(since = "0.1.4", note = "import through the future module instead")]
pub use future::{
    Done, Empty, Failed, Finished, Lazy, AndThen, Flatten, FlattenStream, Fuse, IntoStream,
    Join, Join3, Join4, Join5, Map, MapErr, OrElse, Select, SelectNext, Then
};

if_std! {
    mod lock;
    mod task_impl;

    pub mod task;
    pub mod executor;
    pub mod sync;

    #[doc(hidden)]
    #[deprecated(since = "0.1.4", note = "use sync::oneshot::channel instead")]
    pub use sync::oneshot::channel as oneshot;

    #[doc(hidden)]
    #[deprecated(since = "0.1.4", note = "use sync::oneshot::Receiver instead")]
    pub use sync::oneshot::Receiver as Oneshot;

    #[doc(hidden)]
    #[deprecated(since = "0.1.4", note = "use sync::oneshot::Sender instead")]
    pub use sync::oneshot::Sender as Complete;

    #[doc(hidden)]
    #[deprecated(since = "0.1.4", note = "use sync::oneshot::Canceled instead")]
    pub use sync::oneshot::Canceled;

    #[doc(hidden)]
    #[deprecated(since = "0.1.4", note = "import through the future module instead")]
    pub use future::{BoxFuture, collect, select_all, select_ok};
}
<|endoftext|>


<commit_before><commit_msg>Removing tests for now.<commit_after><|endoftext|>


<commit_before><commit_msg>`xaudio2.h` functions<commit_after><|endoftext|>


<commit_before><commit_msg>pub use.<commit_after><|endoftext|>


<commit_before><commit_msg>improve `Origin`<commit_after><|endoftext|>


<commit_before><commit_msg>Implement .encrypt() method.<commit_after><|endoftext|>


<commit_before>extern crate orbclient;
extern crate sinulation;

pub mod start;
pub mod vid;
pub mod shaders;
//pub mod out;
<commit_msg>Added a flag to remove annoying pointless warnings\<commit_after>extern crate orbclient;
extern crate sinulation;

pub mod start;
pub mod vid;

#[allow(dead_code)]
pub mod shaders;
//pub mod out;
<|endoftext|>


<commit_before><commit_msg>Problem 58<commit_after>#[deriving(Clone)]
enum BinaryTree<T> {
    Node(T, ~BinaryTree<T>, ~BinaryTree<T>),
    Empty
}

fn is_mirror<T>(t1: &BinaryTree<T>, t2: &BinaryTree<T>) -> bool {
    match (t1, t2) {
        (&Empty, &Empty) => true,
        (&Node(_, ~ref t1l, ~ref t1r), &Node(_, ~ref t2l, ~ref t2r)) => is_mirror(t1l, t2r) && is_mirror(t1r, t2l),
        _ => false
    }
}

fn is_symmetric<T>(tree: &BinaryTree<T>) -> bool {
    match *tree {
        Empty => true,
        Node(_, ~ref l, ~ref r) => is_mirror(l, r)
    }
}

fn cbal_tree(n: uint) -> ~[BinaryTree<char>] {
    match n {
        0 => ~[Empty],
        _ if n % 2 == 1 => {
            let t = cbal_tree(n/2);
            t.flat_map(|s| t.iter().map(|u| Node('x', ~s.clone(), ~u.clone())).to_owned_vec())
        }
        _ => {
            let a = cbal_tree(n/2 - 1);
            let b = cbal_tree(n/2);
            let lr = a.flat_map(|s| b.iter().map(|u| Node('x', ~s.clone(), ~u.clone())).to_owned_vec());
            let rl = b.flat_map(|s| a.iter().map(|u| Node('x', ~s.clone(), ~u.clone())).to_owned_vec());
            std::vec::append(lr, rl)
        }
    }
}

fn sym_cbal_trees(n: uint) -> ~[BinaryTree<char>] {
    cbal_tree(n).move_iter().filter(|t| is_symmetric(t)).to_owned_vec()
}

fn main() {
    assert!(sym_cbal_trees(57).len() == 256);
}
<|endoftext|>


<commit_before><commit_msg>command refactor<commit_after><|endoftext|>


<commit_before><commit_msg>Reformat code<commit_after><|endoftext|>


<commit_before><commit_msg>Clean warnings.<commit_after><|endoftext|>


<commit_before><commit_msg>Add a passing test for const unsafe_unreachable<commit_after>// run-pass

#![feature(const_fn)]
#![feature(const_unreachable_unchecked)]

const unsafe fn foo(x: bool) -> bool {
    match x {
        true => true,
        false => std::hint::unreachable_unchecked(),
    }
}

const BAR: bool = unsafe { foo(true) };

fn main() {
  assert_eq!(BAR, true);
}
<|endoftext|>


<commit_before>// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! This module contains everything needed to instantiate an interpreter.
//! This separation exists to ensure that no fancy miri features like
//! interpreting common C functions leak into CTFE.

use std::borrow::{Borrow, Cow};
use std::hash::Hash;

use rustc::hir::{self, def_id::DefId};
use rustc::mir;
use rustc::ty::{self, layout::TyLayout, query::TyCtxtAt};

use super::{
    Allocation, AllocId, EvalResult, Scalar, AllocationExtra,
    EvalContext, PlaceTy, MPlaceTy, OpTy, Pointer, MemoryKind,
};

/// Whether this kind of memory is allowed to leak
pub trait MayLeak: Copy {
    fn may_leak(self) -> bool;
}

/// The functionality needed by memory to manage its allocations
pub trait AllocMap<K: Hash + Eq, V> {
    /// Test if the map contains the given key.
    /// Deliberately takes `&mut` because that is sufficient, and some implementations
    /// can be more efficient then (using `RefCell::get_mut`).
    fn contains_key<Q: ?Sized + Hash + Eq>(&mut self, k: &Q) -> bool
        where K: Borrow<Q>;

    /// Insert new entry into the map.
    fn insert(&mut self, k: K, v: V) -> Option<V>;

    /// Remove entry from the map.
    fn remove<Q: ?Sized + Hash + Eq>(&mut self, k: &Q) -> Option<V>
        where K: Borrow<Q>;

    /// Return data based the keys and values in the map.
    fn filter_map_collect<T>(&self, f: impl FnMut(&K, &V) -> Option<T>) -> Vec<T>;

    /// Return a reference to entry `k`.  If no such entry exists, call
    /// `vacant` and either forward its error, or add its result to the map
    /// and return a reference to *that*.
    fn get_or<E>(
        &self,
        k: K,
        vacant: impl FnOnce() -> Result<V, E>
    ) -> Result<&V, E>;

    /// Return a mutable reference to entry `k`.  If no such entry exists, call
    /// `vacant` and either forward its error, or add its result to the map
    /// and return a reference to *that*.
    fn get_mut_or<E>(
        &mut self,
        k: K,
        vacant: impl FnOnce() -> Result<V, E>
    ) -> Result<&mut V, E>;
}

/// Methods of this trait signifies a point where CTFE evaluation would fail
/// and some use case dependent behaviour can instead be applied.
pub trait Machine<'a, 'mir, 'tcx>: Sized {
    /// Additional memory kinds a machine wishes to distinguish from the builtin ones
    type MemoryKinds: ::std::fmt::Debug + MayLeak + Eq + 'static;

    /// Tag tracked alongside every pointer.  This is used to implement "Stacked Borrows"
    /// <https://www.ralfj.de/blog/2018/08/07/stacked-borrows.html>.
    /// The `default()` is used for pointers to consts, statics, vtables and functions.
    type PointerTag: ::std::fmt::Debug + Default + Copy + Eq + Hash + 'static;

    /// Extra data stored in every allocation.
    type AllocExtra: AllocationExtra<Self::PointerTag>;

    /// Memory's allocation map
    type MemoryMap:
        AllocMap<
            AllocId,
            (MemoryKind<Self::MemoryKinds>, Allocation<Self::PointerTag, Self::AllocExtra>)
        > +
        Default +
        Clone;

    /// The memory kind to use for copied statics -- or None if statics should not be mutated
    /// and thus any such attempt will cause a `ModifiedStatic` error is raised.
    /// Statics are copied under two circumstances: When they are mutated, and when
    /// `static_with_default_tag` or `find_foreign_static` (see below) returns an owned allocation
    /// that is added to the memory so that the work is not done twice.
    const STATIC_KIND: Option<Self::MemoryKinds>;

    /// Whether to enforce the validity invariant
    fn enforce_validity(ecx: &EvalContext<'a, 'mir, 'tcx, Self>) -> bool;

    /// Called before a basic block terminator is executed.
    /// You can use this to detect endlessly running programs.
    fn before_terminator(ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>) -> EvalResult<'tcx>;

    /// Entry point to all function calls.
    ///
    /// Returns either the mir to use for the call, or `None` if execution should
    /// just proceed (which usually means this hook did all the work that the
    /// called function should usually have done).  In the latter case, it is
    /// this hook's responsibility to call `goto_block(ret)` to advance the instruction pointer!
    /// (This is to support functions like `__rust_maybe_catch_panic` that neither find a MIR
    /// nor just jump to `ret`, but instead push their own stack frame.)
    /// Passing `dest`and `ret` in the same `Option` proved very annoying when only one of them
    /// was used.
    fn find_fn(
        ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
        instance: ty::Instance<'tcx>,
        args: &[OpTy<'tcx, Self::PointerTag>],
        dest: Option<PlaceTy<'tcx, Self::PointerTag>>,
        ret: Option<mir::BasicBlock>,
    ) -> EvalResult<'tcx, Option<&'mir mir::Mir<'tcx>>>;

    /// Directly process an intrinsic without pushing a stack frame.
    /// If this returns successfully, the engine will take care of jumping to the next block.
    fn call_intrinsic(
        ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
        instance: ty::Instance<'tcx>,
        args: &[OpTy<'tcx, Self::PointerTag>],
        dest: PlaceTy<'tcx, Self::PointerTag>,
    ) -> EvalResult<'tcx>;

    /// Called for read access to a foreign static item.
    ///
    /// This will only be called once per static and machine; the result is cached in
    /// the machine memory. (This relies on `AllocMap::get_or` being able to add the
    /// owned allocation to the map even when the map is shared.)
    fn find_foreign_static(
        tcx: TyCtxtAt<'a, 'tcx, 'tcx>,
        def_id: DefId,
    ) -> EvalResult<'tcx, Cow<'tcx, Allocation<Self::PointerTag, Self::AllocExtra>>>;

    /// Called to turn an allocation obtained from the `tcx` into one that has
    /// the right type for this machine.
    ///
    /// This should avoid copying if no work has to be done! If this returns an owned
    /// allocation (because a copy had to be done to add tags or metadata), machine memory will
    /// cache the result. (This relies on `AllocMap::get_or` being able to add the
    /// owned allocation to the map even when the map is shared.)
    fn adjust_static_allocation(
        alloc: &'_ Allocation
    ) -> Cow<'_, Allocation<Self::PointerTag, Self::AllocExtra>>;

    /// Called for all binary operations on integer(-like) types when one operand is a pointer
    /// value, and for the `Offset` operation that is inherently about pointers.
    ///
    /// Returns a (value, overflowed) pair if the operation succeeded
    fn ptr_op(
        ecx: &EvalContext<'a, 'mir, 'tcx, Self>,
        bin_op: mir::BinOp,
        left: Scalar<Self::PointerTag>,
        left_layout: TyLayout<'tcx>,
        right: Scalar<Self::PointerTag>,
        right_layout: TyLayout<'tcx>,
    ) -> EvalResult<'tcx, (Scalar<Self::PointerTag>, bool)>;

    /// Heap allocations via the `box` keyword.
    fn box_alloc(
        ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
        dest: PlaceTy<'tcx, Self::PointerTag>,
    ) -> EvalResult<'tcx>;

    /// Add the tag for a newly allocated pointer.
    fn tag_new_allocation(
        ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
        ptr: Pointer,
        kind: MemoryKind<Self::MemoryKinds>,
    ) -> EvalResult<'tcx, Pointer<Self::PointerTag>>;

    /// Executed when evaluating the `*` operator: Following a reference.
    /// This has the chance to adjust the tag.  It should not change anything else!
    /// `mutability` can be `None` in case a raw ptr is being dereferenced.
    #[inline]
    fn tag_dereference(
        _ecx: &EvalContext<'a, 'mir, 'tcx, Self>,
        place: MPlaceTy<'tcx, Self::PointerTag>,
        _mutability: Option<hir::Mutability>,
    ) -> EvalResult<'tcx, Scalar<Self::PointerTag>> {
        Ok(place.ptr)
    }

    /// Execute a retagging operation
    #[inline]
    fn retag(
        _ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
        _fn_entry: bool,
        _place: PlaceTy<'tcx, Self::PointerTag>,
    ) -> EvalResult<'tcx> {
        Ok(())
    }

    /// Execute an escape-to-raw operation
    #[inline]
    fn escape_to_raw(
        _ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
        _ptr: OpTy<'tcx, Self::PointerTag>,
    ) -> EvalResult<'tcx> {
        Ok(())
    }
}
<commit_msg>Grammar nit<commit_after>// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! This module contains everything needed to instantiate an interpreter.
//! This separation exists to ensure that no fancy miri features like
//! interpreting common C functions leak into CTFE.

use std::borrow::{Borrow, Cow};
use std::hash::Hash;

use rustc::hir::{self, def_id::DefId};
use rustc::mir;
use rustc::ty::{self, layout::TyLayout, query::TyCtxtAt};

use super::{
    Allocation, AllocId, EvalResult, Scalar, AllocationExtra,
    EvalContext, PlaceTy, MPlaceTy, OpTy, Pointer, MemoryKind,
};

/// Whether this kind of memory is allowed to leak
pub trait MayLeak: Copy {
    fn may_leak(self) -> bool;
}

/// The functionality needed by memory to manage its allocations
pub trait AllocMap<K: Hash + Eq, V> {
    /// Test if the map contains the given key.
    /// Deliberately takes `&mut` because that is sufficient, and some implementations
    /// can be more efficient then (using `RefCell::get_mut`).
    fn contains_key<Q: ?Sized + Hash + Eq>(&mut self, k: &Q) -> bool
        where K: Borrow<Q>;

    /// Insert new entry into the map.
    fn insert(&mut self, k: K, v: V) -> Option<V>;

    /// Remove entry from the map.
    fn remove<Q: ?Sized + Hash + Eq>(&mut self, k: &Q) -> Option<V>
        where K: Borrow<Q>;

    /// Return data based the keys and values in the map.
    fn filter_map_collect<T>(&self, f: impl FnMut(&K, &V) -> Option<T>) -> Vec<T>;

    /// Return a reference to entry `k`.  If no such entry exists, call
    /// `vacant` and either forward its error, or add its result to the map
    /// and return a reference to *that*.
    fn get_or<E>(
        &self,
        k: K,
        vacant: impl FnOnce() -> Result<V, E>
    ) -> Result<&V, E>;

    /// Return a mutable reference to entry `k`.  If no such entry exists, call
    /// `vacant` and either forward its error, or add its result to the map
    /// and return a reference to *that*.
    fn get_mut_or<E>(
        &mut self,
        k: K,
        vacant: impl FnOnce() -> Result<V, E>
    ) -> Result<&mut V, E>;
}

/// Methods of this trait signifies a point where CTFE evaluation would fail
/// and some use case dependent behaviour can instead be applied.
pub trait Machine<'a, 'mir, 'tcx>: Sized {
    /// Additional memory kinds a machine wishes to distinguish from the builtin ones
    type MemoryKinds: ::std::fmt::Debug + MayLeak + Eq + 'static;

    /// Tag tracked alongside every pointer.  This is used to implement "Stacked Borrows"
    /// <https://www.ralfj.de/blog/2018/08/07/stacked-borrows.html>.
    /// The `default()` is used for pointers to consts, statics, vtables and functions.
    type PointerTag: ::std::fmt::Debug + Default + Copy + Eq + Hash + 'static;

    /// Extra data stored in every allocation.
    type AllocExtra: AllocationExtra<Self::PointerTag>;

    /// Memory's allocation map
    type MemoryMap:
        AllocMap<
            AllocId,
            (MemoryKind<Self::MemoryKinds>, Allocation<Self::PointerTag, Self::AllocExtra>)
        > +
        Default +
        Clone;

    /// The memory kind to use for copied statics -- or None if statics should not be mutated
    /// and thus any such attempt will cause a `ModifiedStatic` error to be raised.
    /// Statics are copied under two circumstances: When they are mutated, and when
    /// `static_with_default_tag` or `find_foreign_static` (see below) returns an owned allocation
    /// that is added to the memory so that the work is not done twice.
    const STATIC_KIND: Option<Self::MemoryKinds>;

    /// Whether to enforce the validity invariant
    fn enforce_validity(ecx: &EvalContext<'a, 'mir, 'tcx, Self>) -> bool;

    /// Called before a basic block terminator is executed.
    /// You can use this to detect endlessly running programs.
    fn before_terminator(ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>) -> EvalResult<'tcx>;

    /// Entry point to all function calls.
    ///
    /// Returns either the mir to use for the call, or `None` if execution should
    /// just proceed (which usually means this hook did all the work that the
    /// called function should usually have done).  In the latter case, it is
    /// this hook's responsibility to call `goto_block(ret)` to advance the instruction pointer!
    /// (This is to support functions like `__rust_maybe_catch_panic` that neither find a MIR
    /// nor just jump to `ret`, but instead push their own stack frame.)
    /// Passing `dest`and `ret` in the same `Option` proved very annoying when only one of them
    /// was used.
    fn find_fn(
        ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
        instance: ty::Instance<'tcx>,
        args: &[OpTy<'tcx, Self::PointerTag>],
        dest: Option<PlaceTy<'tcx, Self::PointerTag>>,
        ret: Option<mir::BasicBlock>,
    ) -> EvalResult<'tcx, Option<&'mir mir::Mir<'tcx>>>;

    /// Directly process an intrinsic without pushing a stack frame.
    /// If this returns successfully, the engine will take care of jumping to the next block.
    fn call_intrinsic(
        ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
        instance: ty::Instance<'tcx>,
        args: &[OpTy<'tcx, Self::PointerTag>],
        dest: PlaceTy<'tcx, Self::PointerTag>,
    ) -> EvalResult<'tcx>;

    /// Called for read access to a foreign static item.
    ///
    /// This will only be called once per static and machine; the result is cached in
    /// the machine memory. (This relies on `AllocMap::get_or` being able to add the
    /// owned allocation to the map even when the map is shared.)
    fn find_foreign_static(
        tcx: TyCtxtAt<'a, 'tcx, 'tcx>,
        def_id: DefId,
    ) -> EvalResult<'tcx, Cow<'tcx, Allocation<Self::PointerTag, Self::AllocExtra>>>;

    /// Called to turn an allocation obtained from the `tcx` into one that has
    /// the right type for this machine.
    ///
    /// This should avoid copying if no work has to be done! If this returns an owned
    /// allocation (because a copy had to be done to add tags or metadata), machine memory will
    /// cache the result. (This relies on `AllocMap::get_or` being able to add the
    /// owned allocation to the map even when the map is shared.)
    fn adjust_static_allocation(
        alloc: &'_ Allocation
    ) -> Cow<'_, Allocation<Self::PointerTag, Self::AllocExtra>>;

    /// Called for all binary operations on integer(-like) types when one operand is a pointer
    /// value, and for the `Offset` operation that is inherently about pointers.
    ///
    /// Returns a (value, overflowed) pair if the operation succeeded
    fn ptr_op(
        ecx: &EvalContext<'a, 'mir, 'tcx, Self>,
        bin_op: mir::BinOp,
        left: Scalar<Self::PointerTag>,
        left_layout: TyLayout<'tcx>,
        right: Scalar<Self::PointerTag>,
        right_layout: TyLayout<'tcx>,
    ) -> EvalResult<'tcx, (Scalar<Self::PointerTag>, bool)>;

    /// Heap allocations via the `box` keyword.
    fn box_alloc(
        ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
        dest: PlaceTy<'tcx, Self::PointerTag>,
    ) -> EvalResult<'tcx>;

    /// Add the tag for a newly allocated pointer.
    fn tag_new_allocation(
        ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
        ptr: Pointer,
        kind: MemoryKind<Self::MemoryKinds>,
    ) -> EvalResult<'tcx, Pointer<Self::PointerTag>>;

    /// Executed when evaluating the `*` operator: Following a reference.
    /// This has the chance to adjust the tag.  It should not change anything else!
    /// `mutability` can be `None` in case a raw ptr is being dereferenced.
    #[inline]
    fn tag_dereference(
        _ecx: &EvalContext<'a, 'mir, 'tcx, Self>,
        place: MPlaceTy<'tcx, Self::PointerTag>,
        _mutability: Option<hir::Mutability>,
    ) -> EvalResult<'tcx, Scalar<Self::PointerTag>> {
        Ok(place.ptr)
    }

    /// Execute a retagging operation
    #[inline]
    fn retag(
        _ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
        _fn_entry: bool,
        _place: PlaceTy<'tcx, Self::PointerTag>,
    ) -> EvalResult<'tcx> {
        Ok(())
    }

    /// Execute an escape-to-raw operation
    #[inline]
    fn escape_to_raw(
        _ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
        _ptr: OpTy<'tcx, Self::PointerTag>,
    ) -> EvalResult<'tcx> {
        Ok(())
    }
}
<|endoftext|>


<commit_before><commit_msg>added xfailed test for issue 9737<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// ignore-test #9737

#![feature(macro_rules)]

macro_rules! f((v: $x:expr) => ( println!("{:?}", $x) ))

fn main () {
    let v = 5;
    f!(v: 3);
}
<|endoftext|>


<commit_before><commit_msg>Split out draw/display functions<commit_after><|endoftext|>


<commit_before><commit_msg>Add test for LookupHost iterator Send/Sync traits<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(lookup_host)]

use std::net::lookup_host;

fn is_sync<T>(_: T) where T: Sync {}
fn is_send<T>(_: T) where T: Send {}

macro_rules! all_sync_send {
    ($ctor:expr, $($iter:ident),+) => ({
        $(
            let mut x = $ctor;
            is_sync(x.$iter());
            let mut y = $ctor;
            is_send(y.$iter());
        )+
    })
}

fn main() {
    all_sync_send!(lookup_host("localhost").unwrap(), next);
}
<|endoftext|>


<commit_before>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

fn f1(ref_string: &str) -> ~str {
    match ref_string {
        "a" => ~"found a",
        "b" => ~"found b",
        _ => ~"not found"
    }
}

fn f2(ref_string: &str) -> ~str {
    match ref_string {
        "a" => ~"found a",
        "b" => ~"found b",
        s => fmt!("not found (%s)", s)
    }
}

fn g1(ref_1: &str, ref_2: &str) -> ~str {
    match (ref_1, ref_2) {
        ("a", "b") => ~"found a,b",
        ("b", "c") => ~"found b,c",
        _ => ~"not found"
    }
}

fn g2(ref_1: &str, ref_2: &str) -> ~str {
    match (ref_1, ref_2) {
        ("a", "b") => ~"found a,b",
        ("b", "c") => ~"found b,c",
        (s1, s2) => fmt!("not found (%s, %s)", s1, s2)
    }
}

pub fn main() {
    assert_eq!(f1(@"a"), ~"found a");
    assert_eq!(f1(~"b"), ~"found b");
    assert_eq!(f1(&"c"), ~"not found");
    assert_eq!(f1("d"), ~"not found");
    assert_eq!(f2(@"a"), ~"found a");
    assert_eq!(f2(~"b"), ~"found b");
    assert_eq!(f2(&"c"), ~"not found (c)");
    assert_eq!(f2("d"), ~"not found (d)");
    assert_eq!(g1(@"a", @"b"), ~"found a,b");
    assert_eq!(g1(~"b", ~"c"), ~"found b,c");
    assert_eq!(g1(&"c", &"d"), ~"not found");
    assert_eq!(g1("d", "e"), ~"not found");
    assert_eq!(g2(@"a", @"b"), ~"found a,b");
    assert_eq!(g2(~"b", ~"c"), ~"found b,c");
    assert_eq!(g2(&"c", &"d"), ~"not found (c, d)");
    assert_eq!(g2("d", "e"), ~"not found (d, e)");
}

<commit_msg>last bit of whitespace<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

fn f1(ref_string: &str) -> ~str {
    match ref_string {
        "a" => ~"found a",
        "b" => ~"found b",
        _ => ~"not found"
    }
}

fn f2(ref_string: &str) -> ~str {
    match ref_string {
        "a" => ~"found a",
        "b" => ~"found b",
        s => fmt!("not found (%s)", s)
    }
}

fn g1(ref_1: &str, ref_2: &str) -> ~str {
    match (ref_1, ref_2) {
        ("a", "b") => ~"found a,b",
        ("b", "c") => ~"found b,c",
        _ => ~"not found"
    }
}

fn g2(ref_1: &str, ref_2: &str) -> ~str {
    match (ref_1, ref_2) {
        ("a", "b") => ~"found a,b",
        ("b", "c") => ~"found b,c",
        (s1, s2) => fmt!("not found (%s, %s)", s1, s2)
    }
}

pub fn main() {
    assert_eq!(f1(@"a"), ~"found a");
    assert_eq!(f1(~"b"), ~"found b");
    assert_eq!(f1(&"c"), ~"not found");
    assert_eq!(f1("d"), ~"not found");
    assert_eq!(f2(@"a"), ~"found a");
    assert_eq!(f2(~"b"), ~"found b");
    assert_eq!(f2(&"c"), ~"not found (c)");
    assert_eq!(f2("d"), ~"not found (d)");
    assert_eq!(g1(@"a", @"b"), ~"found a,b");
    assert_eq!(g1(~"b", ~"c"), ~"found b,c");
    assert_eq!(g1(&"c", &"d"), ~"not found");
    assert_eq!(g1("d", "e"), ~"not found");
    assert_eq!(g2(@"a", @"b"), ~"found a,b");
    assert_eq!(g2(~"b", ~"c"), ~"found b,c");
    assert_eq!(g2(&"c", &"d"), ~"not found (c, d)");
    assert_eq!(g2("d", "e"), ~"not found (d, e)");
}
<|endoftext|>


<commit_before><commit_msg>Add test for no_core statics<commit_after>// compile-pass

#![feature(no_core, lang_items)]
#![no_core]
#![crate_type = "lib"]

#[lang = "sized"]
trait Sized {}

extern {
    pub static A: u32;
}
<|endoftext|>


<commit_before><commit_msg>Fix x86 test.<commit_after><|endoftext|>


<commit_before>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/*!

Named pipes

This module contains the ability to communicate over named pipes with
synchronous I/O. On windows, this corresponds to talking over a Named Pipe,
while on Unix it corresponds to UNIX domain sockets.

These pipes are similar to TCP in the sense that you can have both a stream to a
server and a server itself. The server provided accepts other `UnixStream`
instances as clients.

*/

use prelude::*;

use c_str::ToCStr;
use rt::rtio::{IoFactory, RtioUnixListener, with_local_io};
use rt::rtio::{RtioUnixAcceptor, RtioPipe};
use rt::io::pipe::PipeStream;
use rt::io::{io_error, Listener, Acceptor, Reader, Writer};

/// A stream which communicates over a named pipe.
pub struct UnixStream {
    priv obj: PipeStream,
}

impl UnixStream {
    fn new(obj: ~RtioPipe) -> UnixStream {
        UnixStream { obj: PipeStream::new(obj) }
    }

    /// Connect to a pipe named by `path`. This will attempt to open a
    /// connection to the underlying socket.
    ///
    /// The returned stream will be closed when the object falls out of scope.
    ///
    /// # Failure
    ///
    /// This function will raise on the `io_error` condition if the connection
    /// could not be made.
    ///
    /// # Example
    ///
    ///     use std::rt::io::net::unix::UnixStream;
    ///
    ///     let server = Path("path/to/my/socket");
    ///     let mut stream = UnixStream::connect(&server);
    ///     stream.write([1, 2, 3]);
    ///
    pub fn connect<P: ToCStr>(path: &P) -> Option<UnixStream> {
        do with_local_io |io| {
            match io.unix_connect(&path.to_c_str()) {
                Ok(s) => Some(UnixStream::new(s)),
                Err(ioerr) => {
                    io_error::cond.raise(ioerr);
                    None
                }
            }
        }
    }
}

impl Reader for UnixStream {
    fn read(&mut self, buf: &mut [u8]) -> Option<uint> { self.obj.read(buf) }
    fn eof(&mut self) -> bool { self.obj.eof() }
}

impl Writer for UnixStream {
    fn write(&mut self, buf: &[u8]) { self.obj.write(buf) }
    fn flush(&mut self) { self.obj.flush() }
}

pub struct UnixListener {
    priv obj: ~RtioUnixListener,
}

impl UnixListener {

    /// Creates a new listener, ready to receive incoming connections on the
    /// specified socket. The server will be named by `path`.
    ///
    /// This listener will be closed when it falls out of scope.
    ///
    /// # Failure
    ///
    /// This function will raise on the `io_error` condition if the specified
    /// path could not be bound.
    ///
    /// # Example
    ///
    ///     use std::rt::io::net::unix::UnixListener;
    ///
    ///     let server = Path("path/to/my/socket");
    ///     let mut stream = UnixListener::bind(&server);
    ///     for client in stream.incoming() {
    ///         let mut client = client;
    ///         client.write([1, 2, 3, 4]);
    ///     }
    ///
    pub fn bind<P: ToCStr>(path: &P) -> Option<UnixListener> {
        do with_local_io |io| {
            match io.unix_bind(&path.to_c_str()) {
                Ok(s) => Some(UnixListener{ obj: s }),
                Err(ioerr) => {
                    io_error::cond.raise(ioerr);
                    None
                }
            }
        }
    }
}

impl Listener<UnixStream, UnixAcceptor> for UnixListener {
    fn listen(self) -> Option<UnixAcceptor> {
        match self.obj.listen() {
            Ok(acceptor) => Some(UnixAcceptor { obj: acceptor }),
            Err(ioerr) => {
                io_error::cond.raise(ioerr);
                None
            }
        }
    }
}

pub struct UnixAcceptor {
    priv obj: ~RtioUnixAcceptor,
}

impl Acceptor<UnixStream> for UnixAcceptor {
    fn accept(&mut self) -> Option<UnixStream> {
        match self.obj.accept() {
            Ok(s) => Some(UnixStream::new(s)),
            Err(ioerr) => {
                io_error::cond.raise(ioerr);
                None
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use prelude::*;
    use super::*;
    use cell::Cell;
    use rt::test::*;
    use rt::io::*;
    use rt::comm::oneshot;
    use os;

    fn smalltest(server: ~fn(UnixStream), client: ~fn(UnixStream)) {
        let server = Cell::new(server);
        let client = Cell::new(client);
        do run_in_mt_newsched_task {
            let server = Cell::new(server.take());
            let client = Cell::new(client.take());
            let path1 = next_test_unix();
            let path2 = path1.clone();
            let (port, chan) = oneshot();
            let port = Cell::new(port);
            let chan = Cell::new(chan);

            do spawntask {
                let mut acceptor = UnixListener::bind(&path1).listen();
                chan.take().send(());
                server.take()(acceptor.accept().unwrap());
            }

            do spawntask {
                port.take().recv();
                client.take()(UnixStream::connect(&path2).unwrap());
            }
        }
    }

    #[test]
    fn bind_error() {
        do run_in_mt_newsched_task {
            let mut called = false;
            do io_error::cond.trap(|e| {
                assert!(e.kind == PermissionDenied);
                called = true;
            }).inside {
                let listener = UnixListener::bind(&("path/to/nowhere"));
                assert!(listener.is_none());
            }
            assert!(called);
        }
    }

    #[test]
    fn connect_error() {
        do run_in_mt_newsched_task {
            let mut called = false;
            do io_error::cond.trap(|e| {
                assert_eq!(e.kind, OtherIoError);
                called = true;
            }).inside {
                let stream = UnixStream::connect(&("path/to/nowhere"));
                assert!(stream.is_none());
            }
            assert!(called);
        }
    }

    #[test]
    fn smoke() {
        smalltest(|mut server| {
            let mut buf = [0];
            server.read(buf);
            assert!(buf[0] == 99);
        }, |mut client| {
            client.write([99]);
        })
    }

    #[test]
    fn read_eof() {
        smalltest(|mut server| {
            let mut buf = [0];
            assert!(server.read(buf).is_none());
            assert!(server.read(buf).is_none());
        }, |_client| {
            // drop the client
        })
    }

    #[test]
    fn write_begone() {
        smalltest(|mut server| {
            let buf = [0];
            let mut stop = false;
            while !stop{
                do io_error::cond.trap(|e| {
                    assert_eq!(e.kind, BrokenPipe);
                    stop = true;
                }).inside {
                    server.write(buf);
                }
            }
        }, |_client| {
            // drop the client
        })
    }

    #[test]
    fn accept_lots() {
        do run_in_mt_newsched_task {
            let times = 10;
            let path1 = next_test_unix();
            let path2 = path1.clone();
            let (port, chan) = oneshot();
            let port = Cell::new(port);
            let chan = Cell::new(chan);

            do spawntask {
                let mut acceptor = UnixListener::bind(&path1).listen();
                chan.take().send(());
                do times.times {
                    let mut client = acceptor.accept();
                    let mut buf = [0];
                    client.read(buf);
                    assert_eq!(buf[0], 100);
                }
            }

            do spawntask {
                port.take().recv();
                do times.times {
                    let mut stream = UnixStream::connect(&path2);
                    stream.write([100]);
                }
            }
        }
    }

    #[test]
    fn path_exists() {
        do run_in_mt_newsched_task {
            let path = next_test_unix();
            let _acceptor = UnixListener::bind(&path).listen();
            assert!(os::path_exists(&path));
        }
    }
}
<commit_msg>auto merge of #10133 : alexcrichton/rust/another-error, r=thestinger<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/*!

Named pipes

This module contains the ability to communicate over named pipes with
synchronous I/O. On windows, this corresponds to talking over a Named Pipe,
while on Unix it corresponds to UNIX domain sockets.

These pipes are similar to TCP in the sense that you can have both a stream to a
server and a server itself. The server provided accepts other `UnixStream`
instances as clients.

*/

use prelude::*;

use c_str::ToCStr;
use rt::rtio::{IoFactory, RtioUnixListener, with_local_io};
use rt::rtio::{RtioUnixAcceptor, RtioPipe};
use rt::io::pipe::PipeStream;
use rt::io::{io_error, Listener, Acceptor, Reader, Writer};

/// A stream which communicates over a named pipe.
pub struct UnixStream {
    priv obj: PipeStream,
}

impl UnixStream {
    fn new(obj: ~RtioPipe) -> UnixStream {
        UnixStream { obj: PipeStream::new(obj) }
    }

    /// Connect to a pipe named by `path`. This will attempt to open a
    /// connection to the underlying socket.
    ///
    /// The returned stream will be closed when the object falls out of scope.
    ///
    /// # Failure
    ///
    /// This function will raise on the `io_error` condition if the connection
    /// could not be made.
    ///
    /// # Example
    ///
    ///     use std::rt::io::net::unix::UnixStream;
    ///
    ///     let server = Path("path/to/my/socket");
    ///     let mut stream = UnixStream::connect(&server);
    ///     stream.write([1, 2, 3]);
    ///
    pub fn connect<P: ToCStr>(path: &P) -> Option<UnixStream> {
        do with_local_io |io| {
            match io.unix_connect(&path.to_c_str()) {
                Ok(s) => Some(UnixStream::new(s)),
                Err(ioerr) => {
                    io_error::cond.raise(ioerr);
                    None
                }
            }
        }
    }
}

impl Reader for UnixStream {
    fn read(&mut self, buf: &mut [u8]) -> Option<uint> { self.obj.read(buf) }
    fn eof(&mut self) -> bool { self.obj.eof() }
}

impl Writer for UnixStream {
    fn write(&mut self, buf: &[u8]) { self.obj.write(buf) }
    fn flush(&mut self) { self.obj.flush() }
}

pub struct UnixListener {
    priv obj: ~RtioUnixListener,
}

impl UnixListener {

    /// Creates a new listener, ready to receive incoming connections on the
    /// specified socket. The server will be named by `path`.
    ///
    /// This listener will be closed when it falls out of scope.
    ///
    /// # Failure
    ///
    /// This function will raise on the `io_error` condition if the specified
    /// path could not be bound.
    ///
    /// # Example
    ///
    ///     use std::rt::io::net::unix::UnixListener;
    ///
    ///     let server = Path("path/to/my/socket");
    ///     let mut stream = UnixListener::bind(&server);
    ///     for client in stream.incoming() {
    ///         let mut client = client;
    ///         client.write([1, 2, 3, 4]);
    ///     }
    ///
    pub fn bind<P: ToCStr>(path: &P) -> Option<UnixListener> {
        do with_local_io |io| {
            match io.unix_bind(&path.to_c_str()) {
                Ok(s) => Some(UnixListener{ obj: s }),
                Err(ioerr) => {
                    io_error::cond.raise(ioerr);
                    None
                }
            }
        }
    }
}

impl Listener<UnixStream, UnixAcceptor> for UnixListener {
    fn listen(self) -> Option<UnixAcceptor> {
        match self.obj.listen() {
            Ok(acceptor) => Some(UnixAcceptor { obj: acceptor }),
            Err(ioerr) => {
                io_error::cond.raise(ioerr);
                None
            }
        }
    }
}

pub struct UnixAcceptor {
    priv obj: ~RtioUnixAcceptor,
}

impl Acceptor<UnixStream> for UnixAcceptor {
    fn accept(&mut self) -> Option<UnixStream> {
        match self.obj.accept() {
            Ok(s) => Some(UnixStream::new(s)),
            Err(ioerr) => {
                io_error::cond.raise(ioerr);
                None
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use prelude::*;
    use super::*;
    use cell::Cell;
    use rt::test::*;
    use rt::io::*;
    use rt::comm::oneshot;
    use os;

    fn smalltest(server: ~fn(UnixStream), client: ~fn(UnixStream)) {
        let server = Cell::new(server);
        let client = Cell::new(client);
        do run_in_mt_newsched_task {
            let server = Cell::new(server.take());
            let client = Cell::new(client.take());
            let path1 = next_test_unix();
            let path2 = path1.clone();
            let (port, chan) = oneshot();
            let port = Cell::new(port);
            let chan = Cell::new(chan);

            do spawntask {
                let mut acceptor = UnixListener::bind(&path1).listen();
                chan.take().send(());
                server.take()(acceptor.accept().unwrap());
            }

            do spawntask {
                port.take().recv();
                client.take()(UnixStream::connect(&path2).unwrap());
            }
        }
    }

    #[test]
    fn bind_error() {
        do run_in_mt_newsched_task {
            let mut called = false;
            do io_error::cond.trap(|e| {
                assert!(e.kind == PermissionDenied);
                called = true;
            }).inside {
                let listener = UnixListener::bind(&("path/to/nowhere"));
                assert!(listener.is_none());
            }
            assert!(called);
        }
    }

    #[test]
    fn connect_error() {
        do run_in_mt_newsched_task {
            let mut called = false;
            do io_error::cond.trap(|e| {
                assert_eq!(e.kind, OtherIoError);
                called = true;
            }).inside {
                let stream = UnixStream::connect(&("path/to/nowhere"));
                assert!(stream.is_none());
            }
            assert!(called);
        }
    }

    #[test]
    fn smoke() {
        smalltest(|mut server| {
            let mut buf = [0];
            server.read(buf);
            assert!(buf[0] == 99);
        }, |mut client| {
            client.write([99]);
        })
    }

    #[test]
    fn read_eof() {
        smalltest(|mut server| {
            let mut buf = [0];
            assert!(server.read(buf).is_none());
            assert!(server.read(buf).is_none());
        }, |_client| {
            // drop the client
        })
    }

    #[test]
    fn write_begone() {
        smalltest(|mut server| {
            let buf = [0];
            let mut stop = false;
            while !stop{
                do io_error::cond.trap(|e| {
                    assert!(e.kind == BrokenPipe || e.kind == NotConnected,
                            "unknown error {:?}", e);
                    stop = true;
                }).inside {
                    server.write(buf);
                }
            }
        }, |_client| {
            // drop the client
        })
    }

    #[test]
    fn accept_lots() {
        do run_in_mt_newsched_task {
            let times = 10;
            let path1 = next_test_unix();
            let path2 = path1.clone();
            let (port, chan) = oneshot();
            let port = Cell::new(port);
            let chan = Cell::new(chan);

            do spawntask {
                let mut acceptor = UnixListener::bind(&path1).listen();
                chan.take().send(());
                do times.times {
                    let mut client = acceptor.accept();
                    let mut buf = [0];
                    client.read(buf);
                    assert_eq!(buf[0], 100);
                }
            }

            do spawntask {
                port.take().recv();
                do times.times {
                    let mut stream = UnixStream::connect(&path2);
                    stream.write([100]);
                }
            }
        }
    }

    #[test]
    fn path_exists() {
        do run_in_mt_newsched_task {
            let path = next_test_unix();
            let _acceptor = UnixListener::bind(&path).listen();
            assert!(os::path_exists(&path));
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Abstraction of a task pool for basic parallelism.

use core::prelude::*;

use task::spawn;
use comm::{channel, Sender, Receiver};
use sync::{Arc, Mutex};

struct Sentinel<'a> {
    jobs: &'a Arc<Mutex<Receiver<proc(): Send>>>,
    active: bool
}

impl<'a> Sentinel<'a> {
    fn new(jobs: &Arc<Mutex<Receiver<proc(): Send>>>) -> Sentinel {
        Sentinel {
            jobs: jobs,
            active: true
        }
    }

    // Cancel and destroy this sentinel.
    fn cancel(mut self) {
        self.active = false;
    }
}

#[unsafe_destructor]
impl<'a> Drop for Sentinel<'a> {
    fn drop(&mut self) {
        if self.active {
            spawn_in_pool(self.jobs.clone())
        }
    }
}

/// A task pool used to execute functions in parallel.
///
/// Spawns `n` worker tasks and replenishes the pool if any worker tasks
/// panic.
///
/// # Example
///
/// ```rust
/// # use sync::TaskPool;
/// # use iter::AdditiveIterator;
///
/// let pool = TaskPool::new(4u);
///
/// let (tx, rx) = channel();
/// for _ in range(0, 8u) {
///     let tx = tx.clone();
///     pool.execute(proc() {
///         tx.send(1u);
///     });
/// }
///
/// assert_eq!(rx.iter().take(8u).sum(), 8u);
/// ```
pub struct TaskPool {
    // How the taskpool communicates with subtasks.
    //
    // This is the only such Sender, so when it is dropped all subtasks will
    // quit.
    jobs: Sender<proc(): Send>
}

impl TaskPool {
    /// Spawns a new task pool with `tasks` tasks.
    ///
    /// # Panics
    ///
    /// This function will panic if `tasks` is 0.
    pub fn new(tasks: uint) -> TaskPool {
        assert!(tasks >= 1);

        let (tx, rx) = channel::<proc(): Send>();
        let rx = Arc::new(Mutex::new(rx));

        // Taskpool tasks.
        for _ in range(0, tasks) {
            spawn_in_pool(rx.clone());
        }

        TaskPool { jobs: tx }
    }

    /// Executes the function `job` on a task in the pool.
    pub fn execute(&self, job: proc():Send) {
        self.jobs.send(job);
    }
}

fn spawn_in_pool(jobs: Arc<Mutex<Receiver<proc(): Send>>>) {
    spawn(proc() {
        // Will spawn a new task on panic unless it is cancelled.
        let sentinel = Sentinel::new(&jobs);

        loop {
            let message = {
                // Only lock jobs for the time it takes
                // to get a job, not run it.
                let lock = jobs.lock();
                lock.recv_opt()
            };

            match message {
                Ok(job) => job(),

                // The Taskpool was dropped.
                Err(..) => break
            }
        }

        sentinel.cancel();
    })
}

#[cfg(test)]
mod test {
    use core::prelude::*;
    use super::*;
    use comm::channel;
    use iter::range;

    const TEST_TASKS: uint = 4u;

    #[test]
    fn test_works() {
        use iter::AdditiveIterator;

        let pool = TaskPool::new(TEST_TASKS);

        let (tx, rx) = channel();
        for _ in range(0, TEST_TASKS) {
            let tx = tx.clone();
            pool.execute(proc() {
                tx.send(1u);
            });
        }

        assert_eq!(rx.iter().take(TEST_TASKS).sum(), TEST_TASKS);
    }

    #[test]
    #[should_fail]
    fn test_zero_tasks_panic() {
        TaskPool::new(0);
    }

    #[test]
    fn test_recovery_from_subtask_panic() {
        use iter::AdditiveIterator;

        let pool = TaskPool::new(TEST_TASKS);

        // Panic all the existing tasks.
        for _ in range(0, TEST_TASKS) {
            pool.execute(proc() { panic!() });
        }

        // Ensure new tasks were spawned to compensate.
        let (tx, rx) = channel();
        for _ in range(0, TEST_TASKS) {
            let tx = tx.clone();
            pool.execute(proc() {
                tx.send(1u);
            });
        }

        assert_eq!(rx.iter().take(TEST_TASKS).sum(), TEST_TASKS);
    }

    #[test]
    fn test_should_not_panic_on_drop_if_subtasks_panic_after_drop() {
        use sync::{Arc, Barrier};

        let pool = TaskPool::new(TEST_TASKS);
        let waiter = Arc::new(Barrier::new(TEST_TASKS + 1));

        // Panic all the existing tasks in a bit.
        for _ in range(0, TEST_TASKS) {
            let waiter = waiter.clone();
            pool.execute(proc() {
                waiter.wait();
                panic!();
            });
        }

        drop(pool);

        // Kick off the failure.
        waiter.wait();
    }
}

<commit_msg>Fix doctests<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Abstraction of a task pool for basic parallelism.

use core::prelude::*;

use task::spawn;
use comm::{channel, Sender, Receiver};
use sync::{Arc, Mutex};

struct Sentinel<'a> {
    jobs: &'a Arc<Mutex<Receiver<proc(): Send>>>,
    active: bool
}

impl<'a> Sentinel<'a> {
    fn new(jobs: &Arc<Mutex<Receiver<proc(): Send>>>) -> Sentinel {
        Sentinel {
            jobs: jobs,
            active: true
        }
    }

    // Cancel and destroy this sentinel.
    fn cancel(mut self) {
        self.active = false;
    }
}

#[unsafe_destructor]
impl<'a> Drop for Sentinel<'a> {
    fn drop(&mut self) {
        if self.active {
            spawn_in_pool(self.jobs.clone())
        }
    }
}

/// A task pool used to execute functions in parallel.
///
/// Spawns `n` worker tasks and replenishes the pool if any worker tasks
/// panic.
///
/// # Example
///
/// ```rust
/// # use std::sync::TaskPool;
/// # use std::iter::AdditiveIterator;
///
/// let pool = TaskPool::new(4u);
///
/// let (tx, rx) = channel();
/// for _ in range(0, 8u) {
///     let tx = tx.clone();
///     pool.execute(proc() {
///         tx.send(1u);
///     });
/// }
///
/// assert_eq!(rx.iter().take(8u).sum(), 8u);
/// ```
pub struct TaskPool {
    // How the taskpool communicates with subtasks.
    //
    // This is the only such Sender, so when it is dropped all subtasks will
    // quit.
    jobs: Sender<proc(): Send>
}

impl TaskPool {
    /// Spawns a new task pool with `tasks` tasks.
    ///
    /// # Panics
    ///
    /// This function will panic if `tasks` is 0.
    pub fn new(tasks: uint) -> TaskPool {
        assert!(tasks >= 1);

        let (tx, rx) = channel::<proc(): Send>();
        let rx = Arc::new(Mutex::new(rx));

        // Taskpool tasks.
        for _ in range(0, tasks) {
            spawn_in_pool(rx.clone());
        }

        TaskPool { jobs: tx }
    }

    /// Executes the function `job` on a task in the pool.
    pub fn execute(&self, job: proc():Send) {
        self.jobs.send(job);
    }
}

fn spawn_in_pool(jobs: Arc<Mutex<Receiver<proc(): Send>>>) {
    spawn(proc() {
        // Will spawn a new task on panic unless it is cancelled.
        let sentinel = Sentinel::new(&jobs);

        loop {
            let message = {
                // Only lock jobs for the time it takes
                // to get a job, not run it.
                let lock = jobs.lock();
                lock.recv_opt()
            };

            match message {
                Ok(job) => job(),

                // The Taskpool was dropped.
                Err(..) => break
            }
        }

        sentinel.cancel();
    })
}

#[cfg(test)]
mod test {
    use core::prelude::*;
    use super::*;
    use comm::channel;
    use iter::range;

    const TEST_TASKS: uint = 4u;

    #[test]
    fn test_works() {
        use iter::AdditiveIterator;

        let pool = TaskPool::new(TEST_TASKS);

        let (tx, rx) = channel();
        for _ in range(0, TEST_TASKS) {
            let tx = tx.clone();
            pool.execute(proc() {
                tx.send(1u);
            });
        }

        assert_eq!(rx.iter().take(TEST_TASKS).sum(), TEST_TASKS);
    }

    #[test]
    #[should_fail]
    fn test_zero_tasks_panic() {
        TaskPool::new(0);
    }

    #[test]
    fn test_recovery_from_subtask_panic() {
        use iter::AdditiveIterator;

        let pool = TaskPool::new(TEST_TASKS);

        // Panic all the existing tasks.
        for _ in range(0, TEST_TASKS) {
            pool.execute(proc() { panic!() });
        }

        // Ensure new tasks were spawned to compensate.
        let (tx, rx) = channel();
        for _ in range(0, TEST_TASKS) {
            let tx = tx.clone();
            pool.execute(proc() {
                tx.send(1u);
            });
        }

        assert_eq!(rx.iter().take(TEST_TASKS).sum(), TEST_TASKS);
    }

    #[test]
    fn test_should_not_panic_on_drop_if_subtasks_panic_after_drop() {
        use sync::{Arc, Barrier};

        let pool = TaskPool::new(TEST_TASKS);
        let waiter = Arc::new(Barrier::new(TEST_TASKS + 1));

        // Panic all the existing tasks in a bit.
        for _ in range(0, TEST_TASKS) {
            let waiter = waiter.clone();
            pool.execute(proc() {
                waiter.wait();
                panic!();
            });
        }

        drop(pool);

        // Kick off the failure.
        waiter.wait();
    }
}

<|endoftext|>


<commit_before><commit_msg>Copy/paste error<commit_after><|endoftext|>


<commit_before><commit_msg>fix camera location calculation<commit_after><|endoftext|>


<commit_before><commit_msg>LinkedList type with iteration<commit_after>enum List< T > {
	Empty,
	Cons{
		head : T,
		tail : Box< List< T > >
	},
}

struct ListIterator< 'a, T : 'a > {
	cur : &'a List< T >,
}

impl< 'a, T > IntoIterator for &'a List< T > {
	type Item = &'a T;
	type IntoIter = ListIterator< 'a, T >;
	fn into_iter( self ) -> Self::IntoIter {
		ListIterator{ cur : self }
	}
}

impl < 'a, T > Iterator for ListIterator< 'a, T > {
	type Item = &'a T;

	fn next( &mut self ) -> Option< &'a T > {
		match self.cur {
			&List::Empty => None,
			&List::Cons{ ref head, ref tail } => {
				self.cur = tail;
				Some( head )
			},
		}
	}
}

fn main() {
	let list = List::Cons{ head : 42, tail : Box::new(
		List::Cons{ head : 1337, tail : Box::new(
			List::Cons{ head : -1, tail : Box::new(
				List::Empty ) } ) } ) };
	for x in &list {
		println!( "{}", x );
	}
}
<|endoftext|>


<commit_before>use alloc::boxed::*;

use core::ptr;

use common::memory::*;
use common::paging::*;
use common::scheduler::*;
use common::vec::*;

pub const CONTEXT_STACK_SIZE: usize = 1024*1024;

pub static mut contexts_ptr: *mut Box<Vec<Context>> = 0 as *mut Box<Vec<Context>>;
pub static mut context_i: usize = 0;
pub static mut context_enabled: bool = false;

pub unsafe fn context_switch(interrupted: bool){
    let reenable = start_no_ints();

    let contexts = &*(*contexts_ptr);
    if context_enabled {
        let current_i = context_i;
        context_i += 1;
        if context_i >= contexts.len(){
            context_i -= contexts.len();
        }
        if context_i != current_i {
            match contexts.get(current_i){
                Option::Some(current) => match contexts.get(context_i) {
                    Option::Some(next) => {
                        current.interrupted = interrupted;
                        next.interrupted = false;
                        current.remap(next);
                        current.switch(next);
                    },
                    Option::None => ()
                },
                Option::None => ()
            }
        }
    }

    end_no_ints(reenable);
}

//TODO: To clean up memory leak, current must be destroyed!
pub unsafe extern "cdecl" fn context_exit() {
    let reenable = start_no_ints();

    let contexts = &mut *(*contexts_ptr);

    if contexts.len() > 1 && context_i > 1 {
        let current_option = contexts.remove(context_i);

        if context_i >= contexts.len() {
            context_i -= contexts.len();
        }
        match current_option {
            Option::Some(mut current) => match contexts.get(context_i) {
                Option::Some(next) => {
                    current.remap(next);
                    current.switch(next);
                },
                Option::None => ()
            },
            Option::None => ()
        }
    }

    end_no_ints(reenable);
}

pub unsafe extern "cdecl" fn context_box(box_fn_ptr: usize){
    let box_fn = ptr::read(box_fn_ptr as *mut Box<FnBox()>);
    unalloc(box_fn_ptr);
    box_fn();
}

pub struct ContextMemory {
    pub physical_address: usize,
    pub virtual_address: usize,
    pub virtual_size: usize,
    pub cleanup: bool
}

pub struct Context {
    pub stack: usize,
    pub stack_ptr: u32,
    pub fx: usize,
    pub memory: Vec<ContextMemory>,
    pub interrupted: bool
}

impl Context {
    pub unsafe fn root() -> Context {
        let ret = Context {
            stack: 0,
            stack_ptr: 0,
            fx: alloc(512),
            memory: Vec::new(),
            interrupted: false
        };

        for i in 0..512 {
            ptr::write((ret.fx + i) as *mut u8, 0);
        }

        return ret;
    }

    pub unsafe fn new(call: usize, args: &Vec<usize>) -> Context {
        let stack = alloc(CONTEXT_STACK_SIZE);

        let mut ret = Context {
            stack: stack,
            stack_ptr: (stack + CONTEXT_STACK_SIZE) as u32,
            fx: alloc(512),
            memory: Vec::new(),
            interrupted: false
        };

        let ebp = ret.stack_ptr;

        for arg in args.iter() {
            ret.push(*arg as u32);
        }

        ret.push(context_exit as u32); //If the function call returns, we will exit
        ret.push(call as u32); //We will ret into this function call

        ret.push(0); //ESI is a param used in the switch function

        ret.push(1 << 9); //Flags

        let esp = ret.stack_ptr;

        ret.push(0); //EAX
        ret.push(0); //ECX
        ret.push(0); //EDX
        ret.push(0); //EBX
        ret.push(esp); //ESP (ignored)
        ret.push(ebp); //EBP
        ret.push(0); //ESI
        ret.push(0); //EDI

        for i in 0..512 {
            ptr::write((ret.fx + i) as *mut u8, 0);
        }

        return ret;
    }

    pub fn spawn(box_fn: Box<FnBox()>) {
        unsafe{
            let box_fn_ptr: *mut Box<FnBox()> = alloc_type();
            ptr::write(box_fn_ptr, box_fn);

            let mut context_box_args: Vec<usize> = Vec::new();
            context_box_args.push(box_fn_ptr as usize);

            let reenable = start_no_ints();
            if contexts_ptr as usize > 0 {
                (*contexts_ptr).push(Context::new(context_box as usize, &context_box_args));
            }
            end_no_ints(reenable);
        }
    }

    pub unsafe fn push(&mut self, data: u32){
        self.stack_ptr -= 4;
        ptr::write(self.stack_ptr as *mut u32, data);
    }

    pub unsafe fn map(&mut self){
        for entry in self.memory.iter() {
            for i in 0..(entry.virtual_size + 4095)/4096 {
                set_page(entry.virtual_address + i*4096, entry.physical_address + i*4096);
            }
        }
    }

    pub unsafe fn unmap(&mut self){
        for entry in self.memory.iter() {
            for i in 0..(entry.virtual_size + 4095)/4096 {
                identity_page(entry.virtual_address + i*4096);
            }
        }
    }

    pub unsafe fn remap(&mut self, other: &mut Context){
        self.unmap();
        other.map();
    }

    //Warning: This function MUST be inspected in disassembly for correct push/pop
    //It should have exactly one extra push/pop of ESI
    #[cold]
    #[inline(never)]
    pub unsafe fn switch(&mut self, other: &mut Context){
        asm!("pushfd
            pushad
            mov [esi], esp"
            :
            : "{esi}"(&mut self.stack_ptr)
            : "memory"
            : "intel", "volatile");

        asm!("fxsave [esi]"
            :
            : "{esi}"(self.fx)
            : "memory"
            : "intel", "volatile");

        asm!("fxrstor [esi]"
            :
            : "{esi}"(other.fx)
            : "memory"
            : "intel", "volatile");

        asm!("mov esp, [esi]
            popad
            popfd"
            :
            : "{esi}"(&mut other.stack_ptr)
            : "memory"
            : "intel", "volatile");
    }
}

impl Drop for Context {
    fn drop(&mut self){
        /*
        while Option::Some(entry) = self.memory.pop() {
            if entry.cleanup {
                d("Application forgot to free ");
                dh(entry.physical_address);
                dl();
                unalloc(entry.physical_address);
            }
        }
        */

        if self.stack > 0 {
            unsafe {
                unalloc(self.stack);
            }
        }

        if self.fx > 0 {
            unsafe {
                unalloc(self.fx);
            }
        }
    }
}
<commit_msg>Fix memory leaks<commit_after>use alloc::boxed::*;

use core::ptr;

use common::memory::*;
use common::paging::*;
use common::scheduler::*;
use common::vec::*;

pub const CONTEXT_STACK_SIZE: usize = 1024*1024;

pub static mut contexts_ptr: *mut Box<Vec<Context>> = 0 as *mut Box<Vec<Context>>;
pub static mut context_i: usize = 0;
pub static mut context_enabled: bool = false;

pub unsafe fn context_switch(interrupted: bool){
    let reenable = start_no_ints();

    let contexts = &mut *(*contexts_ptr);
    if context_enabled {
        let current_i = context_i;
        //The only garbage collection in Redox
        loop {
            context_i += 1;
            if context_i >= contexts.len(){
                context_i -= contexts.len();
            }

            let mut remove = false;
            if let Option::Some(next) = contexts.get(context_i) {
                if next.exited {
                    remove = true;
                }
            }

            if remove {
                drop(contexts.remove(context_i));
            }else{
                break;
            }
        }

        if context_i != current_i {
            match contexts.get(current_i){
                Option::Some(current) => match contexts.get(context_i) {
                    Option::Some(next) => {
                        current.interrupted = interrupted;
                        next.interrupted = false;
                        current.remap(next);
                        current.switch(next);
                    },
                    Option::None => ()
                },
                Option::None => ()
            }
        }
    }

    end_no_ints(reenable);
}

//TODO: To clean up memory leak, current must be destroyed!
pub unsafe extern "cdecl" fn context_exit() {
    let reenable = start_no_ints();

    let contexts = &*(*contexts_ptr);
    if context_enabled && context_i > 1 {
        match contexts.get(context_i) {
            Option::Some(mut current) => current.exited = true,
            Option::None => ()
        }
        context_switch(false);
    }

    end_no_ints(reenable);
}

pub unsafe extern "cdecl" fn context_box(box_fn_ptr: usize){
    let box_fn = ptr::read(box_fn_ptr as *mut Box<FnBox()>);
    unalloc(box_fn_ptr);
    box_fn();
}

pub struct ContextMemory {
    pub physical_address: usize,
    pub virtual_address: usize,
    pub virtual_size: usize,
    pub cleanup: bool
}

pub struct Context {
    pub stack: usize,
    pub stack_ptr: u32,
    pub fx: usize,
    pub memory: Vec<ContextMemory>,
    pub interrupted: bool,
    pub exited: bool
}

impl Context {
    pub unsafe fn root() -> Context {
        let ret = Context {
            stack: 0,
            stack_ptr: 0,
            fx: alloc(512),
            memory: Vec::new(),
            interrupted: false,
            exited: false
        };

        for i in 0..512 {
            ptr::write((ret.fx + i) as *mut u8, 0);
        }

        return ret;
    }

    pub unsafe fn new(call: usize, args: &Vec<usize>) -> Context {
        let stack = alloc(CONTEXT_STACK_SIZE + 512);

        let mut ret = Context {
            stack: stack,
            stack_ptr: (stack + CONTEXT_STACK_SIZE) as u32,
            fx: stack + CONTEXT_STACK_SIZE,
            memory: Vec::new(),
            interrupted: false,
            exited: false
        };

        let ebp = ret.stack_ptr;

        for arg in args.iter() {
            ret.push(*arg as u32);
        }

        ret.push(context_exit as u32); //If the function call returns, we will exit
        ret.push(call as u32); //We will ret into this function call

        ret.push(0); //ESI is a param used in the switch function

        ret.push(1 << 9); //Flags

        let esp = ret.stack_ptr;

        ret.push(0); //EAX
        ret.push(0); //ECX
        ret.push(0); //EDX
        ret.push(0); //EBX
        ret.push(esp); //ESP (ignored)
        ret.push(ebp); //EBP
        ret.push(0); //ESI
        ret.push(0); //EDI

        for i in 0..512 {
            ptr::write((ret.fx + i) as *mut u8, 0);
        }

        return ret;
    }

    pub fn spawn(box_fn: Box<FnBox()>) {
        unsafe{
            let box_fn_ptr: *mut Box<FnBox()> = alloc_type();
            ptr::write(box_fn_ptr, box_fn);

            let mut context_box_args: Vec<usize> = Vec::new();
            context_box_args.push(box_fn_ptr as usize);

            let reenable = start_no_ints();
            if contexts_ptr as usize > 0 {
                (*contexts_ptr).push(Context::new(context_box as usize, &context_box_args));
            }
            end_no_ints(reenable);
        }
    }

    pub unsafe fn push(&mut self, data: u32){
        self.stack_ptr -= 4;
        ptr::write(self.stack_ptr as *mut u32, data);
    }

    pub unsafe fn map(&mut self){
        for entry in self.memory.iter() {
            for i in 0..(entry.virtual_size + 4095)/4096 {
                set_page(entry.virtual_address + i*4096, entry.physical_address + i*4096);
            }
        }
    }

    pub unsafe fn unmap(&mut self){
        for entry in self.memory.iter() {
            for i in 0..(entry.virtual_size + 4095)/4096 {
                identity_page(entry.virtual_address + i*4096);
            }
        }
    }

    pub unsafe fn remap(&mut self, other: &mut Context){
        self.unmap();
        other.map();
    }

    //Warning: This function MUST be inspected in disassembly for correct push/pop
    //It should have exactly one extra push/pop of ESI
    #[cold]
    #[inline(never)]
    pub unsafe fn switch(&mut self, other: &mut Context){
        asm!("pushfd
            pushad
            mov [esi], esp"
            :
            : "{esi}"(&mut self.stack_ptr)
            : "memory"
            : "intel", "volatile");

        asm!("fxsave [esi]"
            :
            : "{esi}"(self.fx)
            : "memory"
            : "intel", "volatile");

        asm!("fxrstor [esi]"
            :
            : "{esi}"(other.fx)
            : "memory"
            : "intel", "volatile");

        asm!("mov esp, [esi]
            popad
            popfd"
            :
            : "{esi}"(&mut other.stack_ptr)
            : "memory"
            : "intel", "volatile");
    }
}

impl Drop for Context {
    fn drop(&mut self){
        while let Option::Some(entry) = self.memory.remove(0) {
            if entry.cleanup {
                unsafe {
                    unalloc(entry.physical_address);
                }
            }
        }

        if self.stack > 0 {
            unsafe {
                unalloc(self.stack);
            }
            self.stack = 0;
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>extern kevent<commit_after><|endoftext|>


<commit_before><commit_msg>Improve use statements<commit_after><|endoftext|>


<commit_before>use std::mem;
use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};

use {PollResult, Callback, Future, PollError};
use executor::{Executor, DEFAULT};
use lock::Lock;
use slot::Slot;
use util;

/// Future for the `select` combinator, waiting for one of two futures to
/// complete.
///
/// This is created by this `Future::select` method.
pub struct Select<A, B> where A: Future, B: Future<Item=A::Item, Error=A::Error> {
    state: State<A, B>,
}

/// Future yielded as the second result in a `Select` future.
///
/// This sentinel future represents the completion of the second future to a
/// `select` which finished second.
pub struct SelectNext<A, B> where A: Future, B: Future<Item=A::Item, Error=A::Error> {
    state: Arc<Scheduled<A, B>>,
}

pub fn new<A, B>(a: A, b: B) -> Select<A, B>
    where A: Future,
          B: Future<Item=A::Item, Error=A::Error>
{
    Select {
        state: State::Start(a, b),
    }
}

impl<A, B> Future for Select<A, B>
    where A: Future,
          B: Future<Item=A::Item, Error=A::Error>,
{
    type Item = (A::Item, SelectNext<A, B>);
    type Error = (A::Error, SelectNext<A, B>);

    fn schedule<G>(&mut self, g: G)
        where G: FnOnce(PollResult<Self::Item, Self::Error>) + Send + 'static
    {
        // TODO: pretty unfortunate we gotta box this up
        self.schedule_boxed(Box::new(g))
    }

    fn schedule_boxed(&mut self, cb: Box<Callback<Self::Item, Self::Error>>) {
        let (mut a, mut b) = match mem::replace(&mut self.state, State::Canceled) {
            State::Start(a, b) => (a, b),
            State::Canceled => {
                return DEFAULT.execute(|| cb.call(Err(PollError::Canceled)))
            }
            State::Scheduled(s) => {
                self.state = State::Scheduled(s);
                return DEFAULT.execute(|| cb.call(Err(util::reused())))
            }
        };

        // TODO: optimize the case that either future is immediately done.
        let data1 = Arc::new(Scheduled {
            futures: Lock::new(None),
            state: AtomicUsize::new(0),
            cb: Lock::new(Some(cb)),
            data: Slot::new(None),
        });
        let data2 = data1.clone();
        let data3 = data2.clone();

        a.schedule(move |result| Scheduled::finish(data1, result));
        b.schedule(move |result| Scheduled::finish(data2, result));
        *data3.futures.try_lock().expect("[s] futures locked") = Some((a, b));

        // Inform our state flags that the futures are available to be canceled.
        // If the cancellation flag is set then we never turn SET on and instead
        // we just cancel the futures and go on our merry way.
        let mut state = data3.state.load(Ordering::SeqCst);
        loop {
            assert!(state & SET == 0);
            if state & CANCEL != 0 {
                assert!(state & DONE != 0);
                data3.cancel();
                break
            }
            let old = data3.state.compare_and_swap(state, state | SET,
                                                   Ordering::SeqCst);
            if old == state {
                break
            }
            state = old;
        }

        self.state = State::Scheduled(data3);
    }
}

enum State<A, B> where A: Future, B: Future<Item=A::Item, Error=A::Error> {
    Start(A, B),
    Scheduled(Arc<Scheduled<A, B>>),
    Canceled,
}

const DONE: usize = 1 << 0;
const CANCEL: usize = 1 << 1;
const SET: usize = 1 << 2;

struct Scheduled<A, B>
    where A: Future,
          B: Future<Item=A::Item, Error=A::Error>,
{
    futures: Lock<Option<(A, B)>>,
    state: AtomicUsize,
    cb: Lock<Option<Box<Callback<(A::Item, SelectNext<A, B>),
                                 (A::Error, SelectNext<A, B>)>>>>,
    data: Slot<PollResult<A::Item, A::Error>>,
}

impl<A, B> Scheduled<A, B>
    where A: Future,
          B: Future<Item=A::Item, Error=A::Error>,
{
    fn finish(me: Arc<Scheduled<A, B>>,
              val: PollResult<A::Item, A::Error>) {
        let old = me.state.fetch_or(DONE, Ordering::SeqCst);

        // if the other side finished before we did then we just drop our result
        // on the ground and let them take care of everything.
        if old & DONE != 0 {
            me.data.try_produce(val).ok().unwrap();
            return
        }

        let cb = me.cb.try_lock().expect("[s] done but cb is locked")
                      .take().expect("[s] done done but cb not here");
        let next = SelectNext { state: me };
        let res = match val {
            Ok(v) => Ok((v, next)),
            Err(PollError::Other(e)) => Err(PollError::Other((e, next))),
            Err(PollError::Panicked(p)) => Err(PollError::Panicked(p)),
            Err(PollError::Canceled) => Err(PollError::Canceled),
        };
        DEFAULT.execute(|| cb.call(res))
    }

    fn cancel(&self) {
        let pair = self.futures.try_lock().expect("[s] futures locked in cancel")
                               .take().expect("[s] cancel but futures not here");
        drop(pair)
    }
}

impl<A, B> Drop for Select<A, B>
    where A: Future,
          B: Future<Item=A::Item, Error=A::Error>
{
    fn drop(&mut self) {
        if let State::Scheduled(ref state) = self.state {
            // If the old state was "nothing has happened", then we cancel both
            // futures. Otherwise one future has finished which implies that the
            // future we returned to that closure is responsible for canceling
            // itself.
            let old = state.state.compare_and_swap(SET, 0, Ordering::SeqCst);
            if old == SET {
                state.cancel();
            }
        }
    }
}

impl<A, B> Future for SelectNext<A, B>
    where A: Future,
          B: Future<Item=A::Item, Error=A::Error>
{
    type Item = A::Item;
    type Error = A::Error;

    fn schedule<G>(&mut self, g: G)
        where G: FnOnce(PollResult<Self::Item, Self::Error>) + Send + 'static
    {
        self.state.data.on_full(|slot| {
            let data = slot.try_consume().unwrap();
            DEFAULT.execute(|| g(data));
        });
    }

    fn schedule_boxed(&mut self, cb: Box<Callback<Self::Item, Self::Error>>) {
        self.schedule(|r| cb.call(r))
    }
}

impl<A, B> Drop for SelectNext<A, B>
    where A: Future,
          B: Future<Item=A::Item, Error=A::Error>
{
    fn drop(&mut self) {
        let mut state = self.state.state.load(Ordering::SeqCst);
        loop {
            // We should in theory only be here if one half is done and we
            // haven't canceled yet.
            assert!(state & CANCEL == 0);
            assert!(state & DONE != 0);

            // Our next state will indicate that we are canceled, and if the
            // futures are available to us we're gonna take them.
            let next = state | CANCEL & !SET;
            let old = self.state.state.compare_and_swap(state, next,
                                                        Ordering::SeqCst);
            if old == state {
                break
            }
            state = old
        }

        // If the old state indicated that we had the futures, then we just took
        // ownership of them so we cancel the futures here.
        if state & SET != 0 {
            self.state.cancel();
        }
    }
}
<commit_msg>Drop `me` ASAP in select before we call a callback<commit_after>use std::mem;
use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};

use {PollResult, Callback, Future, PollError};
use executor::{Executor, DEFAULT};
use lock::Lock;
use slot::Slot;
use util;

/// Future for the `select` combinator, waiting for one of two futures to
/// complete.
///
/// This is created by this `Future::select` method.
pub struct Select<A, B> where A: Future, B: Future<Item=A::Item, Error=A::Error> {
    state: State<A, B>,
}

/// Future yielded as the second result in a `Select` future.
///
/// This sentinel future represents the completion of the second future to a
/// `select` which finished second.
pub struct SelectNext<A, B> where A: Future, B: Future<Item=A::Item, Error=A::Error> {
    state: Arc<Scheduled<A, B>>,
}

pub fn new<A, B>(a: A, b: B) -> Select<A, B>
    where A: Future,
          B: Future<Item=A::Item, Error=A::Error>
{
    Select {
        state: State::Start(a, b),
    }
}

impl<A, B> Future for Select<A, B>
    where A: Future,
          B: Future<Item=A::Item, Error=A::Error>,
{
    type Item = (A::Item, SelectNext<A, B>);
    type Error = (A::Error, SelectNext<A, B>);

    fn schedule<G>(&mut self, g: G)
        where G: FnOnce(PollResult<Self::Item, Self::Error>) + Send + 'static
    {
        // TODO: pretty unfortunate we gotta box this up
        self.schedule_boxed(Box::new(g))
    }

    fn schedule_boxed(&mut self, cb: Box<Callback<Self::Item, Self::Error>>) {
        let (mut a, mut b) = match mem::replace(&mut self.state, State::Canceled) {
            State::Start(a, b) => (a, b),
            State::Canceled => {
                return DEFAULT.execute(|| cb.call(Err(PollError::Canceled)))
            }
            State::Scheduled(s) => {
                self.state = State::Scheduled(s);
                return DEFAULT.execute(|| cb.call(Err(util::reused())))
            }
        };

        // TODO: optimize the case that either future is immediately done.
        let data1 = Arc::new(Scheduled {
            futures: Lock::new(None),
            state: AtomicUsize::new(0),
            cb: Lock::new(Some(cb)),
            data: Slot::new(None),
        });
        let data2 = data1.clone();
        let data3 = data2.clone();

        a.schedule(move |result| Scheduled::finish(data1, result));
        b.schedule(move |result| Scheduled::finish(data2, result));
        *data3.futures.try_lock().expect("[s] futures locked") = Some((a, b));

        // Inform our state flags that the futures are available to be canceled.
        // If the cancellation flag is set then we never turn SET on and instead
        // we just cancel the futures and go on our merry way.
        let mut state = data3.state.load(Ordering::SeqCst);
        loop {
            assert!(state & SET == 0);
            if state & CANCEL != 0 {
                assert!(state & DONE != 0);
                data3.cancel();
                break
            }
            let old = data3.state.compare_and_swap(state, state | SET,
                                                   Ordering::SeqCst);
            if old == state {
                break
            }
            state = old;
        }

        self.state = State::Scheduled(data3);
    }
}

enum State<A, B> where A: Future, B: Future<Item=A::Item, Error=A::Error> {
    Start(A, B),
    Scheduled(Arc<Scheduled<A, B>>),
    Canceled,
}

const DONE: usize = 1 << 0;
const CANCEL: usize = 1 << 1;
const SET: usize = 1 << 2;

struct Scheduled<A, B>
    where A: Future,
          B: Future<Item=A::Item, Error=A::Error>,
{
    futures: Lock<Option<(A, B)>>,
    state: AtomicUsize,
    cb: Lock<Option<Box<Callback<(A::Item, SelectNext<A, B>),
                                 (A::Error, SelectNext<A, B>)>>>>,
    data: Slot<PollResult<A::Item, A::Error>>,
}

impl<A, B> Scheduled<A, B>
    where A: Future,
          B: Future<Item=A::Item, Error=A::Error>,
{
    fn finish(me: Arc<Scheduled<A, B>>,
              val: PollResult<A::Item, A::Error>) {
        let old = me.state.fetch_or(DONE, Ordering::SeqCst);

        // if the other side finished before we did then we just drop our result
        // on the ground and let them take care of everything.
        if old & DONE != 0 {
            me.data.try_produce(val).ok().unwrap();
            return
        }

        let cb = me.cb.try_lock().expect("[s] done but cb is locked")
                      .take().expect("[s] done done but cb not here");
        let res = {
            let next = SelectNext { state: me };
            match val {
                Ok(v) => Ok((v, next)),
                Err(PollError::Other(e)) => Err(PollError::Other((e, next))),
                Err(PollError::Panicked(p)) => Err(PollError::Panicked(p)),
                Err(PollError::Canceled) => Err(PollError::Canceled),
            }
        };
        DEFAULT.execute(|| cb.call(res))
    }

    fn cancel(&self) {
        let pair = self.futures.try_lock().expect("[s] futures locked in cancel")
                               .take().expect("[s] cancel but futures not here");
        drop(pair)
    }
}

impl<A, B> Drop for Select<A, B>
    where A: Future,
          B: Future<Item=A::Item, Error=A::Error>
{
    fn drop(&mut self) {
        if let State::Scheduled(ref state) = self.state {
            // If the old state was "nothing has happened", then we cancel both
            // futures. Otherwise one future has finished which implies that the
            // future we returned to that closure is responsible for canceling
            // itself.
            let old = state.state.compare_and_swap(SET, 0, Ordering::SeqCst);
            if old == SET {
                state.cancel();
            }
        }
    }
}

impl<A, B> Future for SelectNext<A, B>
    where A: Future,
          B: Future<Item=A::Item, Error=A::Error>
{
    type Item = A::Item;
    type Error = A::Error;

    fn schedule<G>(&mut self, g: G)
        where G: FnOnce(PollResult<Self::Item, Self::Error>) + Send + 'static
    {
        self.state.data.on_full(|slot| {
            let data = slot.try_consume().unwrap();
            DEFAULT.execute(|| g(data));
        });
    }

    fn schedule_boxed(&mut self, cb: Box<Callback<Self::Item, Self::Error>>) {
        self.schedule(|r| cb.call(r))
    }
}

impl<A, B> Drop for SelectNext<A, B>
    where A: Future,
          B: Future<Item=A::Item, Error=A::Error>
{
    fn drop(&mut self) {
        let mut state = self.state.state.load(Ordering::SeqCst);
        loop {
            // We should in theory only be here if one half is done and we
            // haven't canceled yet.
            assert!(state & CANCEL == 0);
            assert!(state & DONE != 0);

            // Our next state will indicate that we are canceled, and if the
            // futures are available to us we're gonna take them.
            let next = state | CANCEL & !SET;
            let old = self.state.state.compare_and_swap(state, next,
                                                        Ordering::SeqCst);
            if old == state {
                break
            }
            state = old
        }

        // If the old state indicated that we had the futures, then we just took
        // ownership of them so we cancel the futures here.
        if state & SET != 0 {
            self.state.cancel();
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Adds ::from creator.<commit_after><|endoftext|>


<commit_before><commit_msg>practice<commit_after>fn main() {
    let mut n = 1;

    while n < 1_000_001 {
        if n % 15 == 0 {
            println!("fizzbuzz");
        } else if n % 3 == 0 {
            println!("fizz");
        }else if n % 5 == 0 {
            println!("buzz");
        }else {
            println!("{}", n);
        }

        n += 1;
    }
}
<|endoftext|>


<commit_before><commit_msg>get_file<commit_after><|endoftext|>