<commit_before>// Interior vector utility functions.

import option::none;
import option::some;
import uint::next_power_of_two;
import ptr::addr_of;

native "rust-intrinsic" mod rusti {
    fn ivec_len<T>(v: &[T]) -> uint;
}

native "rust" mod rustrt {
    fn ivec_reserve_shared<T>(v: &mutable [mutable? T], n: uint);
    fn ivec_on_heap<T>(v: &[T]) -> uint;
    fn ivec_to_ptr<T>(v: &[T]) -> *T;
    fn ivec_copy_from_buf_shared<T>(v: &mutable [mutable? T], ptr: *T,
                                    count: uint);
}

/// Reserves space for `n` elements in the given vector.
fn reserve<@T>(v: &mutable [mutable? T], n: uint) {
    rustrt::ivec_reserve_shared(v, n);
}

fn on_heap<T>(v: &[T]) -> bool { ret rustrt::ivec_on_heap(v) != 0u; }

fn to_ptr<T>(v: &[T]) -> *T { ret rustrt::ivec_to_ptr(v); }

fn len<T>(v: &[mutable? T]) -> uint { ret rusti::ivec_len(v); }

type init_op<T> = fn(uint) -> T ;

fn init_fn<@T>(op: &init_op<T>, n_elts: uint) -> [T] {
    let v = ~[];
    reserve(v, n_elts);
    let i: uint = 0u;
    while i < n_elts { v += ~[op(i)]; i += 1u; }
    ret v;
}

// TODO: Remove me once we have slots.
fn init_fn_mut<@T>(op: &init_op<T>, n_elts: uint) -> [mutable T] {
    let v = ~[mutable];
    reserve(v, n_elts);
    let i: uint = 0u;
    while i < n_elts { v += ~[mutable op(i)]; i += 1u; }
    ret v;
}

fn init_elt<@T>(t: &T, n_elts: uint) -> [T] {
    let v = ~[];
    reserve(v, n_elts);
    let i: uint = 0u;
    while i < n_elts { v += ~[t]; i += 1u; }
    ret v;
}

// TODO: Remove me once we have slots.
fn init_elt_mut<@T>(t: &T, n_elts: uint) -> [mutable T] {
    let v = ~[mutable];
    reserve(v, n_elts);
    let i: uint = 0u;
    while i < n_elts { v += ~[mutable t]; i += 1u; }
    ret v;
}

fn to_mut<@T>(v: &[T]) -> [mutable T] {
    let vres = ~[mutable];
    for t: T in v { vres += ~[mutable t]; }
    ret vres;
}

fn from_mut<@T>(v: &[mutable T]) -> [T] {
    let vres = ~[];
    for t: T in v { vres += ~[t]; }
    ret vres;
}

// Predicates
pred is_empty<T>(v: &[mutable? T]) -> bool {
    // FIXME: This would be easier if we could just call len
    for t: T in v { ret false; }
    ret true;
}

pred is_not_empty<T>(v: &[mutable? T]) -> bool { ret !is_empty(v); }

// Accessors

/// Returns the first element of a vector
fn head<@T>(v: &[mutable? T]) : is_not_empty(v) -> T { ret v.(0); }

/// Returns all but the first element of a vector
fn tail<@T>(v: &[mutable? T]) : is_not_empty(v) -> [mutable? T] {
    ret slice(v, 1u, len(v));
}

/// Returns the last element of `v`.
fn last<@T>(v: &[mutable? T]) -> option::t<T> {
    if len(v) == 0u { ret none; }
    ret some(v.(len(v) - 1u));
}

/// Returns a copy of the elements from [`start`..`end`) from `v`.
fn slice<@T>(v: &[mutable? T], start: uint, end: uint) -> [T] {
    assert (start <= end);
    assert (end <= len(v));
    let result = ~[];
    reserve(result, end - start);
    let i = start;
    while i < end { result += ~[v.(i)]; i += 1u; }
    ret result;
}

// TODO: Remove me once we have slots.
fn slice_mut<@T>(v: &[mutable? T], start: uint, end: uint) -> [mutable T] {
    assert (start <= end);
    assert (end <= len(v));
    let result = ~[mutable];
    reserve(result, end - start);
    let i = start;
    while i < end { result += ~[mutable v.(i)]; i += 1u; }
    ret result;
}

// Mutators

fn shift<@T>(v: &mutable [mutable? T]) -> T {
    let ln = len::<T>(v);
    assert (ln > 0u);
    let e = v.(0);
    v = slice::<T>(v, 1u, ln);
    ret e;
}

// TODO: Write this, unsafely, in a way that's not O(n).
fn pop<@T>(v: &mutable [mutable? T]) -> T {
    let ln = len(v);
    assert (ln > 0u);
    ln -= 1u;
    let e = v.(ln);
    v = slice(v, 0u, ln);
    ret e;
}

// TODO: More.

// Appending

/// Expands the given vector in-place by appending `n` copies of `initval`.
fn grow<@T>(v: &mutable [T], n: uint, initval: &T) {
    reserve(v, next_power_of_two(len(v) + n));
    let i: uint = 0u;
    while i < n { v += ~[initval]; i += 1u; }
}

// TODO: Remove me once we have slots.
fn grow_mut<@T>(v: &mutable [mutable T], n: uint, initval: &T) {
    reserve(v, next_power_of_two(len(v) + n));
    let i: uint = 0u;
    while i < n { v += ~[mutable initval]; i += 1u; }
}

/// Calls `f` `n` times and appends the results of these calls to the given
/// vector.
fn grow_fn<@T>(v: &mutable [T], n: uint, init_fn: fn(uint) -> T ) {
    reserve(v, next_power_of_two(len(v) + n));
    let i: uint = 0u;
    while i < n { v += ~[init_fn(i)]; i += 1u; }
}

/// Sets the element at position `index` to `val`. If `index` is past the end
/// of the vector, expands the vector by replicating `initval` to fill the
/// intervening space.
fn grow_set<@T>(v: &mutable [mutable T], index: uint, initval: &T, val: &T) {
    if index >= len(v) { grow_mut(v, index - len(v) + 1u, initval); }
    v.(index) = val;
}

// Functional utilities

fn map<@T, @U>(f: &block(&T) -> U , v: &[mutable? T]) -> [U] {
    let result = ~[];
    reserve(result, len(v));
    for elem: T in v {
        let elem2 = elem; // satisfies alias checker
        result += ~[f(elem2)];
    }
    ret result;
}

fn map2<@T, @U, @V>(f: &block(&T, &U) -> V, v0: &[T], v1: &[U])
    -> [V] {
    let v0_len = len::<T>(v0);
    if v0_len != len::<U>(v1) { fail; }
    let u: [V] = ~[];
    let i = 0u;
    while i < v0_len { u += ~[f({ v0.(i) }, { v1.(i) })]; i += 1u; }
    ret u;
}

fn filter_map<@T, @U>(f: &block(&T) -> option::t<U>,
                      v: &[mutable? T]) -> [U] {
    let result = ~[];
    for elem: T in v {
        let elem2 = elem; // satisfies alias checker
        alt f(elem2) {
          none. {/* no-op */ }
          some(result_elem) { result += ~[result_elem]; }
        }
    }
    ret result;
}

fn foldl<@T, @U>(p: &block(&U, &T) -> U , z: &U, v: &[mutable? T]) -> U {
    let sz = len(v);
    if sz == 0u { ret z; }
    let first = v.(0);
    let rest = slice(v, 1u, sz);
    ret p(foldl(p, z, rest), first);
}

fn any<T>(f: &block(&T) -> bool, v: &[T]) -> bool {
    for elem: T in v { if f(elem) { ret true; } }
    ret false;
}

fn all<T>(f: &block(&T) -> bool, v: &[T]) -> bool {
    for elem: T in v { if !f(elem) { ret false; } }
    ret true;
}

fn member<T>(x: &T, v: &[T]) -> bool {
    for elt: T in v { if x == elt { ret true; } }
    ret false;
}

fn count<T>(x: &T, v: &[mutable? T]) -> uint {
    let cnt = 0u;
    for elt: T in v { if x == elt { cnt += 1u; } }
    ret cnt;
}

fn find<@T>(f: &block(&T) -> bool, v: &[T]) -> option::t<T> {
    for elt: T in v { if f(elt) { ret some(elt); } }
    ret none;
}

fn position<@T>(x: &T, v: &[T]) -> option::t<uint> {
    let i: uint = 0u;
    while i < len(v) { if x == v.(i) { ret some::<uint>(i); } i += 1u; }
    ret none;
}

fn position_pred<T>(f: fn(&T) -> bool, v: &[T]) -> option::t<uint> {
    let i: uint = 0u;
    while i < len(v) { if f(v.(i)) { ret some::<uint>(i); } i += 1u; }
    ret none;
}

fn unzip<@T, @U>(v: &[(T, U)]) -> ([T], [U]) {
    let as = ~[], bs = ~[];
    for (a, b) in v {
        as += ~[a];
        bs += ~[b];
    }
    ret (as, bs);
}

// FIXME make the lengths being equal a constraint
fn zip<@T, @U>(v: &[T], u: &[U]) -> [(T, U)] {
    let zipped = ~[];
    let sz = len(v), i = 0u;
    assert (sz == len(u));
    while i < sz {
        zipped += ~[(v.(i), u.(i))];
        i += 1u;
    }
    ret zipped;
}

// Swaps two elements in a vector
fn swap<@T>(v: &[mutable T], a: uint, b: uint) {
    let t: T = v.(a);
    v.(a) = v.(b);
    v.(b) = t;
}

// In place vector reversal
fn reverse<@T>(v: &[mutable T]) {
    let i: uint = 0u;
    let ln = len::<T>(v);
    while i < ln / 2u { swap(v, i, ln - i - 1u); i += 1u; }
}

// Functional vector reversal. Returns a reversed copy of v.
fn reversed<@T>(v: &[T]) -> [T] {
    let rs: [T] = ~[];
    let i = len::<T>(v);
    if i == 0u { ret rs; } else { i -= 1u; }
    while i != 0u { rs += ~[v.(i)]; i -= 1u; }
    rs += ~[v.(0)];
    ret rs;
}

mod unsafe {
    type ivec_repr =
        {mutable fill: uint,
         mutable alloc: uint,
         heap_part: *mutable ivec_heap_part};
    type ivec_heap_part = {mutable fill: uint};

    fn copy_from_buf<T>(v: &mutable [T], ptr: *T, count: uint) {
        ret rustrt::ivec_copy_from_buf_shared(v, ptr, count);
    }

    fn from_buf<T>(ptr: *T, bytes: uint) -> [T] {
        let v = ~[];
        copy_from_buf(v, ptr, bytes);
        ret v;
    }

    fn set_len<T>(v: &mutable [T], new_len: uint) {
        let new_fill = new_len * sys::size_of::<T>();
        let stack_part: *mutable ivec_repr =
            ::unsafe::reinterpret_cast(addr_of(v));
        if (*stack_part).fill == 0u {
            (*(*stack_part).heap_part).fill = new_fill; // On heap.
        } else {
            (*stack_part).fill = new_fill; // On stack.
        }
    }
}

// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
<commit_msg>Add an iter2 iterator to vec.<commit_after>// Interior vector utility functions.

import option::none;
import option::some;
import uint::next_power_of_two;
import ptr::addr_of;

native "rust-intrinsic" mod rusti {
    fn ivec_len<T>(v: &[T]) -> uint;
}

native "rust" mod rustrt {
    fn ivec_reserve_shared<T>(v: &mutable [mutable? T], n: uint);
    fn ivec_on_heap<T>(v: &[T]) -> uint;
    fn ivec_to_ptr<T>(v: &[T]) -> *T;
    fn ivec_copy_from_buf_shared<T>(v: &mutable [mutable? T], ptr: *T,
                                    count: uint);
}

/// Reserves space for `n` elements in the given vector.
fn reserve<@T>(v: &mutable [mutable? T], n: uint) {
    rustrt::ivec_reserve_shared(v, n);
}

fn on_heap<T>(v: &[T]) -> bool { ret rustrt::ivec_on_heap(v) != 0u; }

fn to_ptr<T>(v: &[T]) -> *T { ret rustrt::ivec_to_ptr(v); }

fn len<T>(v: &[mutable? T]) -> uint { ret rusti::ivec_len(v); }

type init_op<T> = fn(uint) -> T ;

fn init_fn<@T>(op: &init_op<T>, n_elts: uint) -> [T] {
    let v = ~[];
    reserve(v, n_elts);
    let i: uint = 0u;
    while i < n_elts { v += ~[op(i)]; i += 1u; }
    ret v;
}

// TODO: Remove me once we have slots.
fn init_fn_mut<@T>(op: &init_op<T>, n_elts: uint) -> [mutable T] {
    let v = ~[mutable];
    reserve(v, n_elts);
    let i: uint = 0u;
    while i < n_elts { v += ~[mutable op(i)]; i += 1u; }
    ret v;
}

fn init_elt<@T>(t: &T, n_elts: uint) -> [T] {
    let v = ~[];
    reserve(v, n_elts);
    let i: uint = 0u;
    while i < n_elts { v += ~[t]; i += 1u; }
    ret v;
}

// TODO: Remove me once we have slots.
fn init_elt_mut<@T>(t: &T, n_elts: uint) -> [mutable T] {
    let v = ~[mutable];
    reserve(v, n_elts);
    let i: uint = 0u;
    while i < n_elts { v += ~[mutable t]; i += 1u; }
    ret v;
}

fn to_mut<@T>(v: &[T]) -> [mutable T] {
    let vres = ~[mutable];
    for t: T in v { vres += ~[mutable t]; }
    ret vres;
}

fn from_mut<@T>(v: &[mutable T]) -> [T] {
    let vres = ~[];
    for t: T in v { vres += ~[t]; }
    ret vres;
}

// Predicates
pred is_empty<T>(v: &[mutable? T]) -> bool {
    // FIXME: This would be easier if we could just call len
    for t: T in v { ret false; }
    ret true;
}

pred is_not_empty<T>(v: &[mutable? T]) -> bool { ret !is_empty(v); }

// Accessors

/// Returns the first element of a vector
fn head<@T>(v: &[mutable? T]) : is_not_empty(v) -> T { ret v.(0); }

/// Returns all but the first element of a vector
fn tail<@T>(v: &[mutable? T]) : is_not_empty(v) -> [mutable? T] {
    ret slice(v, 1u, len(v));
}

/// Returns the last element of `v`.
fn last<@T>(v: &[mutable? T]) -> option::t<T> {
    if len(v) == 0u { ret none; }
    ret some(v.(len(v) - 1u));
}

/// Returns a copy of the elements from [`start`..`end`) from `v`.
fn slice<@T>(v: &[mutable? T], start: uint, end: uint) -> [T] {
    assert (start <= end);
    assert (end <= len(v));
    let result = ~[];
    reserve(result, end - start);
    let i = start;
    while i < end { result += ~[v.(i)]; i += 1u; }
    ret result;
}

// TODO: Remove me once we have slots.
fn slice_mut<@T>(v: &[mutable? T], start: uint, end: uint) -> [mutable T] {
    assert (start <= end);
    assert (end <= len(v));
    let result = ~[mutable];
    reserve(result, end - start);
    let i = start;
    while i < end { result += ~[mutable v.(i)]; i += 1u; }
    ret result;
}

// Mutators

fn shift<@T>(v: &mutable [mutable? T]) -> T {
    let ln = len::<T>(v);
    assert (ln > 0u);
    let e = v.(0);
    v = slice::<T>(v, 1u, ln);
    ret e;
}

// TODO: Write this, unsafely, in a way that's not O(n).
fn pop<@T>(v: &mutable [mutable? T]) -> T {
    let ln = len(v);
    assert (ln > 0u);
    ln -= 1u;
    let e = v.(ln);
    v = slice(v, 0u, ln);
    ret e;
}

// TODO: More.

// Appending

/// Expands the given vector in-place by appending `n` copies of `initval`.
fn grow<@T>(v: &mutable [T], n: uint, initval: &T) {
    reserve(v, next_power_of_two(len(v) + n));
    let i: uint = 0u;
    while i < n { v += ~[initval]; i += 1u; }
}

// TODO: Remove me once we have slots.
fn grow_mut<@T>(v: &mutable [mutable T], n: uint, initval: &T) {
    reserve(v, next_power_of_two(len(v) + n));
    let i: uint = 0u;
    while i < n { v += ~[mutable initval]; i += 1u; }
}

/// Calls `f` `n` times and appends the results of these calls to the given
/// vector.
fn grow_fn<@T>(v: &mutable [T], n: uint, init_fn: fn(uint) -> T ) {
    reserve(v, next_power_of_two(len(v) + n));
    let i: uint = 0u;
    while i < n { v += ~[init_fn(i)]; i += 1u; }
}

/// Sets the element at position `index` to `val`. If `index` is past the end
/// of the vector, expands the vector by replicating `initval` to fill the
/// intervening space.
fn grow_set<@T>(v: &mutable [mutable T], index: uint, initval: &T, val: &T) {
    if index >= len(v) { grow_mut(v, index - len(v) + 1u, initval); }
    v.(index) = val;
}

// Functional utilities

fn map<@T, @U>(f: &block(&T) -> U , v: &[mutable? T]) -> [U] {
    let result = ~[];
    reserve(result, len(v));
    for elem: T in v {
        let elem2 = elem; // satisfies alias checker
        result += ~[f(elem2)];
    }
    ret result;
}

fn map2<@T, @U, @V>(f: &block(&T, &U) -> V, v0: &[T], v1: &[U])
    -> [V] {
    let v0_len = len::<T>(v0);
    if v0_len != len::<U>(v1) { fail; }
    let u: [V] = ~[];
    let i = 0u;
    while i < v0_len { u += ~[f({ v0.(i) }, { v1.(i) })]; i += 1u; }
    ret u;
}

fn filter_map<@T, @U>(f: &block(&T) -> option::t<U>,
                      v: &[mutable? T]) -> [U] {
    let result = ~[];
    for elem: T in v {
        let elem2 = elem; // satisfies alias checker
        alt f(elem2) {
          none. {/* no-op */ }
          some(result_elem) { result += ~[result_elem]; }
        }
    }
    ret result;
}

fn foldl<@T, @U>(p: &block(&U, &T) -> U , z: &U, v: &[mutable? T]) -> U {
    let sz = len(v);
    if sz == 0u { ret z; }
    let first = v.(0);
    let rest = slice(v, 1u, sz);
    ret p(foldl(p, z, rest), first);
}

fn any<T>(f: &block(&T) -> bool, v: &[T]) -> bool {
    for elem: T in v { if f(elem) { ret true; } }
    ret false;
}

fn all<T>(f: &block(&T) -> bool, v: &[T]) -> bool {
    for elem: T in v { if !f(elem) { ret false; } }
    ret true;
}

fn member<T>(x: &T, v: &[T]) -> bool {
    for elt: T in v { if x == elt { ret true; } }
    ret false;
}

fn count<T>(x: &T, v: &[mutable? T]) -> uint {
    let cnt = 0u;
    for elt: T in v { if x == elt { cnt += 1u; } }
    ret cnt;
}

fn find<@T>(f: &block(&T) -> bool, v: &[T]) -> option::t<T> {
    for elt: T in v { if f(elt) { ret some(elt); } }
    ret none;
}

fn position<@T>(x: &T, v: &[T]) -> option::t<uint> {
    let i: uint = 0u;
    while i < len(v) { if x == v.(i) { ret some::<uint>(i); } i += 1u; }
    ret none;
}

fn position_pred<T>(f: fn(&T) -> bool, v: &[T]) -> option::t<uint> {
    let i: uint = 0u;
    while i < len(v) { if f(v.(i)) { ret some::<uint>(i); } i += 1u; }
    ret none;
}

fn unzip<@T, @U>(v: &[(T, U)]) -> ([T], [U]) {
    let as = ~[], bs = ~[];
    for (a, b) in v {
        as += ~[a];
        bs += ~[b];
    }
    ret (as, bs);
}

// FIXME make the lengths being equal a constraint
fn zip<@T, @U>(v: &[T], u: &[U]) -> [(T, U)] {
    let zipped = ~[];
    let sz = len(v), i = 0u;
    assert (sz == len(u));
    while i < sz {
        zipped += ~[(v.(i), u.(i))];
        i += 1u;
    }
    ret zipped;
}

// Swaps two elements in a vector
fn swap<@T>(v: &[mutable T], a: uint, b: uint) {
    let t: T = v.(a);
    v.(a) = v.(b);
    v.(b) = t;
}

// In place vector reversal
fn reverse<@T>(v: &[mutable T]) {
    let i: uint = 0u;
    let ln = len::<T>(v);
    while i < ln / 2u { swap(v, i, ln - i - 1u); i += 1u; }
}

// Functional vector reversal. Returns a reversed copy of v.
fn reversed<@T>(v: &[T]) -> [T] {
    let rs: [T] = ~[];
    let i = len::<T>(v);
    if i == 0u { ret rs; } else { i -= 1u; }
    while i != 0u { rs += ~[v.(i)]; i -= 1u; }
    rs += ~[v.(0)];
    ret rs;
}

// Iterate over a list with with the indexes
iter iter2<@T>(v: &[T]) -> (uint, T) {
    let i = 0u;
    for x in v {
        put (i, x);
        i += 1u;
    }
}

mod unsafe {
    type ivec_repr =
        {mutable fill: uint,
         mutable alloc: uint,
         heap_part: *mutable ivec_heap_part};
    type ivec_heap_part = {mutable fill: uint};

    fn copy_from_buf<T>(v: &mutable [T], ptr: *T, count: uint) {
        ret rustrt::ivec_copy_from_buf_shared(v, ptr, count);
    }

    fn from_buf<T>(ptr: *T, bytes: uint) -> [T] {
        let v = ~[];
        copy_from_buf(v, ptr, bytes);
        ret v;
    }

    fn set_len<T>(v: &mutable [T], new_len: uint) {
        let new_fill = new_len * sys::size_of::<T>();
        let stack_part: *mutable ivec_repr =
            ::unsafe::reinterpret_cast(addr_of(v));
        if (*stack_part).fill == 0u {
            (*(*stack_part).heap_part).fill = new_fill; // On heap.
        } else {
            (*stack_part).fill = new_fill; // On stack.
        }
    }
}

// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
<|endoftext|>


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


<commit_before>use std::sync::Arc;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering::SeqCst;
use std::error::Error;
use std::fmt;

use {Future, Poll, Async};
use lock::Lock;
use task::{self, Task};

/// A future representing the completion of a computation happening elsewhere in
/// memory.
///
/// This is created by the `oneshot` function.
#[must_use = "futures do nothing unless polled"]
pub struct Oneshot<T> {
    inner: Arc<Inner<T>>,
}

/// Represents the completion half of a oneshot through which the result of a
/// computation is signaled.
///
/// This is created by the `oneshot` function.
pub struct Complete<T> {
    inner: Arc<Inner<T>>,
}

/// Internal state of the `Oneshot`/`Complete` pair above. This is all used as
/// the internal synchronization between the two for send/recv operations.
struct Inner<T> {
    /// Indicates whether this oneshot is complete yet. This is filled in both
    /// by `Complete::drop` and by `Oneshot::drop`, and both sides iterpret it
    /// appropriately.
    ///
    /// For `Oneshot`, if this is `true`, then it's guaranteed that `data` is
    /// unlocked and ready to be inspected.
    ///
    /// For `Complete` if this is `true` then the oneshot has gone away and it
    /// can return ready from `poll_cancel`.
    complete: AtomicBool,

    /// The actual data being transferred as part of this `Oneshot`. This is
    /// filled in by `Complete::complete` and read by `Oneshot::poll`.
    ///
    /// Note that this is protected by `Lock`, but it is in theory safe to
    /// replace with an `UnsafeCell` as it's actually protected by `complete`
    /// above. I wouldn't recommend doing this, however, unless someone is
    /// supremely confident in the various atomic orderings here and there.
    data: Lock<Option<T>>,

    /// Field to store the task which is blocked in `Oneshot::poll`.
    ///
    /// This is filled in when a oneshot is polled but not ready yet. Note that
    /// the `Lock` here, unlike in `data` above, is important to resolve races.
    /// Both the `Oneshot` and the `Complete` halves understand that if they
    /// can't acquire the lock then some important interference is happening.
    rx_task: Lock<Option<Task>>,

    /// Like `rx_task` above, except for the task blocked in
    /// `Complete::poll_cancel`. Additionally, `Lock` cannot be `UnsafeCell`.
    tx_task: Lock<Option<Task>>,
}

/// Creates a new in-memory oneshot used to represent completing a computation.
///
/// A oneshot in this library is a concrete implementation of the `Future` trait
/// used to complete a computation from one location with a future representing
/// what to do in another.
///
/// This function is similar to Rust's channels found in the standard library.
/// Two halves are returned, the first of which is a `Complete` handle, used to
/// signal the end of a computation and provide its value. The second half is a
/// `Oneshot` which implements the `Future` trait, resolving to the value that
/// was given to the `Complete` handle.
///
/// Each half can be separately owned and sent across threads.
///
/// # Examples
///
/// ```
/// use std::thread;
/// use futures::*;
///
/// let (c, p) = oneshot::<i32>();
///
/// thread::spawn(|| {
///     p.map(|i| {
///         println!("got: {}", i);
///     }).wait();
/// });
///
/// c.complete(3);
/// ```
pub fn oneshot<T>() -> (Complete<T>, Oneshot<T>) {
    let inner = Arc::new(Inner {
        complete: AtomicBool::new(false),
        data: Lock::new(None),
        rx_task: Lock::new(None),
        tx_task: Lock::new(None),
    });
    let oneshot = Oneshot {
        inner: inner.clone(),
    };
    let complete = Complete {
        inner: inner,
    };
    (complete, oneshot)
}

impl<T> Complete<T> {
    /// Completes this oneshot with a successful result.
    ///
    /// This function will consume `self` and indicate to the other end, the
    /// `Oneshot`, that the error provided is the result of the computation this
    /// represents.
    pub fn complete(mut self, t: T) {
        // First up, flag that this method was called and then store the data.
        // Note that this lock acquisition should always succeed as it can only
        // interfere with `poll` in `Oneshot` which is only called when the
        // `complete` flag is true, which we're setting here.
        let mut slot = self.inner.data.try_lock().unwrap();
        assert!(slot.is_none());
        *slot = Some(t);
        drop(slot);
    }

    /// Polls this `Complete` half to detect whether the `Oneshot` this has
    /// paired with has gone away.
    ///
    /// This function can be used to learn about when the `Oneshot` (consumer)
    /// half has gone away and nothing will be able to receive a message sent
    /// from `complete`.
    ///
    /// Like `Future::poll`, this function will panic if it's not called from
    /// within the context of a task. In otherwords, this should only ever be
    /// called from inside another future.
    ///
    /// If `Ready` is returned then it means that the `Oneshot` has disappeared
    /// and the result this `Complete` would otherwise produce should no longer
    /// be produced.
    ///
    /// If `NotReady` is returned then the `Oneshot` is still alive and may be
    /// able to receive a message if sent. The current task, however, is
    /// scheduled to receive a notification if the corresponding `Oneshot` goes
    /// away.
    pub fn poll_cancel(&mut self) -> Poll<(), ()> {
        // Fast path up first, just read the flag and see if our other half is
        // gone. This flag is set both in our destructor and the oneshot
        // destructor, but our destructor hasn't run yet so if it's set then the
        // oneshot is gone.
        if self.inner.complete.load(SeqCst) {
            return Ok(Async::Ready(()))
        }

        // If our other half is not gone then we need to park our current task
        // and move it into the `notify_cancel` slot to get notified when it's
        // actually gone.
        //
        // If `try_lock` fails, then the `Oneshot` is in the process of using
        // it, so we can deduce that it's now in the process of going away and
        // hence we're canceled. If it succeeds then we just store our handle.
        //
        // Crucially we then check `oneshot_gone` *again* before we return.
        // While we were storing our handle inside `notify_cancel` the `Oneshot`
        // may have been dropped. The first thing it does is set the flag, and
        // if it fails to acquire the lock it assumes that we'll see the flag
        // later on. So... we then try to see the flag later on!
        let handle = task::park();
        match self.inner.tx_task.try_lock() {
            Some(mut p) => *p = Some(handle),
            None => return Ok(Async::Ready(())),
        }
        if self.inner.complete.load(SeqCst) {
            Ok(Async::Ready(()))
        } else {
            Ok(Async::NotReady)
        }
    }
}

impl<T> Drop for Complete<T> {
    fn drop(&mut self) {
        // Flag that we're a completed `Complete` and try to wake up a receiver.
        // Whether or not we actually stored any data will get picked up and
        // translated to either an item or cancellation.
        //
        // Note that if we fail to acquire the `rx_task` lock then that means
        // we're in one of two situations:
        //
        // 1. The receiver is trying to block in `poll`
        // 2. The receiver is being dropped
        //
        // In the first case it'll check the `complete` flag after it's done
        // blocking to see if it succeeded. In the latter case we don't need to
        // wake up anyone anyway. So in both cases it's ok to ignore the `None`
        // case of `try_lock` and bail out.
        self.inner.complete.store(true, SeqCst);
        if let Some(mut slot) = self.inner.rx_task.try_lock() {
            if let Some(task) = slot.take() {
                drop(slot);
                task.unpark();
            }
        }
    }
}

/// Error returned from a `Oneshot<T>` whenever the correponding `Complete<T>`
/// is dropped.
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct Canceled;

impl fmt::Display for Canceled {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "oneshot canceled")
    }
}

impl Error for Canceled {
    fn description(&self) -> &str {
        "oneshot canceled"
    }
}

impl<T> Future for Oneshot<T> {
    type Item = T;
    type Error = Canceled;

    fn poll(&mut self) -> Poll<T, Canceled> {
        let mut done = false;

        // Check to see if some data has arrived. If it hasn't then we need to
        // block our task.
        //
        // Note that the acquisition of the `rx_task` lock might fail below, but
        // the only situation where this can happen is during `Complete::drop`
        // when we are indeed completed already. If that's happening then we
        // know we're completed so keep going.
        if self.inner.complete.load(SeqCst) {
            done = true;
        } else {
            let task = task::park();
            match self.inner.rx_task.try_lock() {
                Some(mut slot) => *slot = Some(task),
                None => done = true,
            }
        }

        // If we're `done` via one of the paths above, then look at the data and
        // figure out what the answer is. If, however, we stored `rx_task`
        // successfully above we need to check again if we're completed in case
        // a message was sent while `rx_task` was locked and couldn't notify us
        // otherwise.
        //
        // If we're not done, and we're not complete, though, then we've
        // successfully blocked our task and we return `NotReady`.
        if done || self.inner.complete.load(SeqCst) {
            match self.inner.data.try_lock().unwrap().take() {
                Some(data) => Ok(data.into()),
                None => Err(Canceled),
            }
        } else {
            Ok(Async::NotReady)
        }
    }
}

impl<T> Drop for Oneshot<T> {
    fn drop(&mut self) {
        // Indicate to the `Complete` that we're done, so any future calls to
        // `poll_cancel` are weeded out.
        self.inner.complete.store(true, SeqCst);

        // If we've blocked a task then there's no need for it to stick around,
        // so we need to drop it. If this lock acquisition fails, though, then
        // it's just because our `Complete` is trying to take the task, so we
        // let them take care of that.
        if let Some(mut slot) = self.inner.rx_task.try_lock() {
            let task = slot.take();
            drop(slot);
            drop(task);
        }

        // Finally, if our `Complete` wants to get notified of us going away, it
        // would have stored something in `tx_task`. Here we try to peel that
        // out and unpark it.
        //
        // Note that the `try_lock` here may fail, but only if the `Complete` is
        // in the process of filling in the task. If that happens then we
        // already flagged `complete` and they'll pick that up above.
        if let Some(mut handle) = self.inner.tx_task.try_lock() {
            if let Some(task) = handle.take() {
                drop(handle);
                task.unpark()
            }
        }
    }
}
<commit_msg>Fix warning<commit_after>use std::sync::Arc;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering::SeqCst;
use std::error::Error;
use std::fmt;

use {Future, Poll, Async};
use lock::Lock;
use task::{self, Task};

/// A future representing the completion of a computation happening elsewhere in
/// memory.
///
/// This is created by the `oneshot` function.
#[must_use = "futures do nothing unless polled"]
pub struct Oneshot<T> {
    inner: Arc<Inner<T>>,
}

/// Represents the completion half of a oneshot through which the result of a
/// computation is signaled.
///
/// This is created by the `oneshot` function.
pub struct Complete<T> {
    inner: Arc<Inner<T>>,
}

/// Internal state of the `Oneshot`/`Complete` pair above. This is all used as
/// the internal synchronization between the two for send/recv operations.
struct Inner<T> {
    /// Indicates whether this oneshot is complete yet. This is filled in both
    /// by `Complete::drop` and by `Oneshot::drop`, and both sides iterpret it
    /// appropriately.
    ///
    /// For `Oneshot`, if this is `true`, then it's guaranteed that `data` is
    /// unlocked and ready to be inspected.
    ///
    /// For `Complete` if this is `true` then the oneshot has gone away and it
    /// can return ready from `poll_cancel`.
    complete: AtomicBool,

    /// The actual data being transferred as part of this `Oneshot`. This is
    /// filled in by `Complete::complete` and read by `Oneshot::poll`.
    ///
    /// Note that this is protected by `Lock`, but it is in theory safe to
    /// replace with an `UnsafeCell` as it's actually protected by `complete`
    /// above. I wouldn't recommend doing this, however, unless someone is
    /// supremely confident in the various atomic orderings here and there.
    data: Lock<Option<T>>,

    /// Field to store the task which is blocked in `Oneshot::poll`.
    ///
    /// This is filled in when a oneshot is polled but not ready yet. Note that
    /// the `Lock` here, unlike in `data` above, is important to resolve races.
    /// Both the `Oneshot` and the `Complete` halves understand that if they
    /// can't acquire the lock then some important interference is happening.
    rx_task: Lock<Option<Task>>,

    /// Like `rx_task` above, except for the task blocked in
    /// `Complete::poll_cancel`. Additionally, `Lock` cannot be `UnsafeCell`.
    tx_task: Lock<Option<Task>>,
}

/// Creates a new in-memory oneshot used to represent completing a computation.
///
/// A oneshot in this library is a concrete implementation of the `Future` trait
/// used to complete a computation from one location with a future representing
/// what to do in another.
///
/// This function is similar to Rust's channels found in the standard library.
/// Two halves are returned, the first of which is a `Complete` handle, used to
/// signal the end of a computation and provide its value. The second half is a
/// `Oneshot` which implements the `Future` trait, resolving to the value that
/// was given to the `Complete` handle.
///
/// Each half can be separately owned and sent across threads.
///
/// # Examples
///
/// ```
/// use std::thread;
/// use futures::*;
///
/// let (c, p) = oneshot::<i32>();
///
/// thread::spawn(|| {
///     p.map(|i| {
///         println!("got: {}", i);
///     }).wait();
/// });
///
/// c.complete(3);
/// ```
pub fn oneshot<T>() -> (Complete<T>, Oneshot<T>) {
    let inner = Arc::new(Inner {
        complete: AtomicBool::new(false),
        data: Lock::new(None),
        rx_task: Lock::new(None),
        tx_task: Lock::new(None),
    });
    let oneshot = Oneshot {
        inner: inner.clone(),
    };
    let complete = Complete {
        inner: inner,
    };
    (complete, oneshot)
}

impl<T> Complete<T> {
    /// Completes this oneshot with a successful result.
    ///
    /// This function will consume `self` and indicate to the other end, the
    /// `Oneshot`, that the error provided is the result of the computation this
    /// represents.
    pub fn complete(self, t: T) {
        // First up, flag that this method was called and then store the data.
        // Note that this lock acquisition should always succeed as it can only
        // interfere with `poll` in `Oneshot` which is only called when the
        // `complete` flag is true, which we're setting here.
        let mut slot = self.inner.data.try_lock().unwrap();
        assert!(slot.is_none());
        *slot = Some(t);
        drop(slot);
    }

    /// Polls this `Complete` half to detect whether the `Oneshot` this has
    /// paired with has gone away.
    ///
    /// This function can be used to learn about when the `Oneshot` (consumer)
    /// half has gone away and nothing will be able to receive a message sent
    /// from `complete`.
    ///
    /// Like `Future::poll`, this function will panic if it's not called from
    /// within the context of a task. In otherwords, this should only ever be
    /// called from inside another future.
    ///
    /// If `Ready` is returned then it means that the `Oneshot` has disappeared
    /// and the result this `Complete` would otherwise produce should no longer
    /// be produced.
    ///
    /// If `NotReady` is returned then the `Oneshot` is still alive and may be
    /// able to receive a message if sent. The current task, however, is
    /// scheduled to receive a notification if the corresponding `Oneshot` goes
    /// away.
    pub fn poll_cancel(&mut self) -> Poll<(), ()> {
        // Fast path up first, just read the flag and see if our other half is
        // gone. This flag is set both in our destructor and the oneshot
        // destructor, but our destructor hasn't run yet so if it's set then the
        // oneshot is gone.
        if self.inner.complete.load(SeqCst) {
            return Ok(Async::Ready(()))
        }

        // If our other half is not gone then we need to park our current task
        // and move it into the `notify_cancel` slot to get notified when it's
        // actually gone.
        //
        // If `try_lock` fails, then the `Oneshot` is in the process of using
        // it, so we can deduce that it's now in the process of going away and
        // hence we're canceled. If it succeeds then we just store our handle.
        //
        // Crucially we then check `oneshot_gone` *again* before we return.
        // While we were storing our handle inside `notify_cancel` the `Oneshot`
        // may have been dropped. The first thing it does is set the flag, and
        // if it fails to acquire the lock it assumes that we'll see the flag
        // later on. So... we then try to see the flag later on!
        let handle = task::park();
        match self.inner.tx_task.try_lock() {
            Some(mut p) => *p = Some(handle),
            None => return Ok(Async::Ready(())),
        }
        if self.inner.complete.load(SeqCst) {
            Ok(Async::Ready(()))
        } else {
            Ok(Async::NotReady)
        }
    }
}

impl<T> Drop for Complete<T> {
    fn drop(&mut self) {
        // Flag that we're a completed `Complete` and try to wake up a receiver.
        // Whether or not we actually stored any data will get picked up and
        // translated to either an item or cancellation.
        //
        // Note that if we fail to acquire the `rx_task` lock then that means
        // we're in one of two situations:
        //
        // 1. The receiver is trying to block in `poll`
        // 2. The receiver is being dropped
        //
        // In the first case it'll check the `complete` flag after it's done
        // blocking to see if it succeeded. In the latter case we don't need to
        // wake up anyone anyway. So in both cases it's ok to ignore the `None`
        // case of `try_lock` and bail out.
        self.inner.complete.store(true, SeqCst);
        if let Some(mut slot) = self.inner.rx_task.try_lock() {
            if let Some(task) = slot.take() {
                drop(slot);
                task.unpark();
            }
        }
    }
}

/// Error returned from a `Oneshot<T>` whenever the correponding `Complete<T>`
/// is dropped.
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct Canceled;

impl fmt::Display for Canceled {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "oneshot canceled")
    }
}

impl Error for Canceled {
    fn description(&self) -> &str {
        "oneshot canceled"
    }
}

impl<T> Future for Oneshot<T> {
    type Item = T;
    type Error = Canceled;

    fn poll(&mut self) -> Poll<T, Canceled> {
        let mut done = false;

        // Check to see if some data has arrived. If it hasn't then we need to
        // block our task.
        //
        // Note that the acquisition of the `rx_task` lock might fail below, but
        // the only situation where this can happen is during `Complete::drop`
        // when we are indeed completed already. If that's happening then we
        // know we're completed so keep going.
        if self.inner.complete.load(SeqCst) {
            done = true;
        } else {
            let task = task::park();
            match self.inner.rx_task.try_lock() {
                Some(mut slot) => *slot = Some(task),
                None => done = true,
            }
        }

        // If we're `done` via one of the paths above, then look at the data and
        // figure out what the answer is. If, however, we stored `rx_task`
        // successfully above we need to check again if we're completed in case
        // a message was sent while `rx_task` was locked and couldn't notify us
        // otherwise.
        //
        // If we're not done, and we're not complete, though, then we've
        // successfully blocked our task and we return `NotReady`.
        if done || self.inner.complete.load(SeqCst) {
            match self.inner.data.try_lock().unwrap().take() {
                Some(data) => Ok(data.into()),
                None => Err(Canceled),
            }
        } else {
            Ok(Async::NotReady)
        }
    }
}

impl<T> Drop for Oneshot<T> {
    fn drop(&mut self) {
        // Indicate to the `Complete` that we're done, so any future calls to
        // `poll_cancel` are weeded out.
        self.inner.complete.store(true, SeqCst);

        // If we've blocked a task then there's no need for it to stick around,
        // so we need to drop it. If this lock acquisition fails, though, then
        // it's just because our `Complete` is trying to take the task, so we
        // let them take care of that.
        if let Some(mut slot) = self.inner.rx_task.try_lock() {
            let task = slot.take();
            drop(slot);
            drop(task);
        }

        // Finally, if our `Complete` wants to get notified of us going away, it
        // would have stored something in `tx_task`. Here we try to peel that
        // out and unpark it.
        //
        // Note that the `try_lock` here may fail, but only if the `Complete` is
        // in the process of filling in the task. If that happens then we
        // already flagged `complete` and they'll pick that up above.
        if let Some(mut handle) = self.inner.tx_task.try_lock() {
            if let Some(task) = handle.take() {
                drop(handle);
                task.unpark()
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Publicize rotate_bytes_left<commit_after><|endoftext|>


<commit_before><commit_msg>Fix mistake in B_BL decoding<commit_after><|endoftext|>


<commit_before>

pure fn add(x: int, y: int) -> int { ret x + y; }

pure fn sub(x: int, y: int) -> int { ret x - y; }

pure fn mul(x: int, y: int) -> int { ret x * y; }

pure fn div(x: int, y: int) -> int { ret x / y; }

pure fn rem(x: int, y: int) -> int { ret x % y; }

pure fn lt(x: int, y: int) -> bool { ret x < y; }

pure fn le(x: int, y: int) -> bool { ret x <= y; }

pure fn eq(x: int, y: int) -> bool { ret x == y; }

pure fn ne(x: int, y: int) -> bool { ret x != y; }

pure fn ge(x: int, y: int) -> bool { ret x >= y; }

pure fn gt(x: int, y: int) -> bool { ret x > y; }

pure fn positive(x: int) -> bool { ret x > 0; }

pure fn negative(x: int) -> bool { ret x < 0; }

pure fn nonpositive(x: int) -> bool { ret x <= 0; }

pure fn nonnegative(x: int) -> bool { ret x >= 0; }

// FIXME: Make sure this works with negative integers.
fn hash(x: int) -> uint { ret x as uint; }

fn eq_alias(x: int, y: int) -> bool { ret x == y; }

iter range(lo: int, hi: int) -> int {
    let lo_: int = lo;
    while lo_ < hi { put lo_; lo_ += 1; }
}

fn parse_buf(buf: [u8], radix: uint) -> int {
    if vec::len::<u8>(buf) == 0u {
        log_err "parse_buf(): buf is empty";
        fail;
    }
    let i = vec::len::<u8>(buf) - 1u;
    let power = 1;
    if buf[0] == ('-' as u8) {
        power = -1;
        i -= 1u;
    }
    let n = 0;
    while true {
        n += (buf[i] - ('0' as u8) as int) * power;
        power *= radix as int;
        if i == 0u { ret n; }
        i -= 1u;
    }
    fail;
}

fn from_str(s: str) -> int { parse_buf(str::bytes(s), 10u) }

fn to_str(n: int, radix: uint) -> str {
    assert (0u < radix && radix <= 16u);
    ret if n < 0 {
            "-" + uint::to_str(-n as uint, radix)
        } else { uint::to_str(n as uint, radix) };
}
fn str(i: int) -> str { ret to_str(i, 10u); }

fn pow(base: int, exponent: uint) -> int {
    ret if exponent == 0u {
            1
        } else if base == 0 {
            0
        } else {
            let accum = base;
            let count = exponent;
            while count > 1u { accum *= base; count -= 1u; }
            accum
        };
}
// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
<commit_msg>[Optim] int.rs: reimplemented pow with fast exponentiation<commit_after>

pure fn add(x: int, y: int) -> int { ret x + y; }

pure fn sub(x: int, y: int) -> int { ret x - y; }

pure fn mul(x: int, y: int) -> int { ret x * y; }

pure fn div(x: int, y: int) -> int { ret x / y; }

pure fn rem(x: int, y: int) -> int { ret x % y; }

pure fn lt(x: int, y: int) -> bool { ret x < y; }

pure fn le(x: int, y: int) -> bool { ret x <= y; }

pure fn eq(x: int, y: int) -> bool { ret x == y; }

pure fn ne(x: int, y: int) -> bool { ret x != y; }

pure fn ge(x: int, y: int) -> bool { ret x >= y; }

pure fn gt(x: int, y: int) -> bool { ret x > y; }

pure fn positive(x: int) -> bool { ret x > 0; }

pure fn negative(x: int) -> bool { ret x < 0; }

pure fn nonpositive(x: int) -> bool { ret x <= 0; }

pure fn nonnegative(x: int) -> bool { ret x >= 0; }

// FIXME: Make sure this works with negative integers.
fn hash(x: int) -> uint { ret x as uint; }

fn eq_alias(x: int, y: int) -> bool { ret x == y; }

iter range(lo: int, hi: int) -> int {
    let lo_: int = lo;
    while lo_ < hi { put lo_; lo_ += 1; }
}

fn parse_buf(buf: [u8], radix: uint) -> int {
    if vec::len::<u8>(buf) == 0u {
        log_err "parse_buf(): buf is empty";
        fail;
    }
    let i = vec::len::<u8>(buf) - 1u;
    let power = 1;
    if buf[0] == ('-' as u8) {
        power = -1;
        i -= 1u;
    }
    let n = 0;
    while true {
        n += (buf[i] - ('0' as u8) as int) * power;
        power *= radix as int;
        if i == 0u { ret n; }
        i -= 1u;
    }
    fail;
}

fn from_str(s: str) -> int { parse_buf(str::bytes(s), 10u) }

fn to_str(n: int, radix: uint) -> str {
    assert (0u < radix && radix <= 16u);
    ret if n < 0 {
            "-" + uint::to_str(-n as uint, radix)
        } else { uint::to_str(n as uint, radix) };
}
fn str(i: int) -> str { ret to_str(i, 10u); }

fn pow(base: int, exponent: uint) -> int {
    if exponent == 0u { ret 1; } //Not mathemtically true if [base == 0]
    if base     == 0  { ret 0; }
    let my_pow  = exponent;
    let acc     = 1;
    let multiplier = base;
    while(my_pow > 0u) {
      if my_pow % 2u == 1u {
         acc *= multiplier;
      }
      my_pow     /= 2u;
      multiplier *= multiplier;
    }
    ret acc;
}
// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
<|endoftext|>


<commit_before><commit_msg>Rollup merge of #37693 - michaelwoerister:ich-tests, r=brson<commit_after>// Copyright 2016 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 test case tests the incremental compilation hash (ICH) implementation
// for function and method call expressions.

// The general pattern followed here is: Change one thing between rev1 and rev2
// and make sure that the hash has changed, then change nothing between rev2 and
// rev3 and make sure that the hash has not changed.

// must-compile-successfully
// revisions: cfail1 cfail2 cfail3
// compile-flags: -Z query-dep-graph

#![allow(warnings)]
#![feature(rustc_attrs)]
#![crate_type="rlib"]

fn callee1(_x: u32, _y: i64) {}
fn callee2(_x: u32, _y: i64) {}

// Change Callee (Function) ----------------------------------------------------
#[cfg(cfail1)]
pub fn change_callee_function() {
    callee1(1, 2)
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn change_callee_function() {
    callee2(1, 2)
}

// Change Argument (Function) --------------------------------------------------
#[cfg(cfail1)]
pub fn change_argument_function() {
    callee1(1, 2)
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn change_argument_function() {
    callee1(1, 3)
}

// Change Callee Indirectly (Function) -----------------------------------------
mod change_callee_indirectly_function {
    #[cfg(cfail1)]
    use super::callee1 as callee;
    #[cfg(not(cfail1))]
    use super::callee2 as callee;

    #[rustc_dirty(label="Hir", cfg="cfail2")]
    #[rustc_clean(label="Hir", cfg="cfail3")]
    #[rustc_metadata_dirty(cfg="cfail2")]
    #[rustc_metadata_clean(cfg="cfail3")]
    pub fn change_callee_indirectly_function() {
        callee(1, 2)
    }
}

struct Struct;
impl Struct {
    fn method1(&self, _x: char, _y: bool) {}
    fn method2(&self, _x: char, _y: bool) {}
}

// Change Callee (Method) ------------------------------------------------------
#[cfg(cfail1)]
pub fn change_callee_method() {
    let s = Struct;
    s.method1('x', true);
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn change_callee_method() {
    let s = Struct;
    s.method2('x', true);
}

// Change Argument (Method) ----------------------------------------------------
#[cfg(cfail1)]
pub fn change_argument_method() {
    let s = Struct;
    s.method1('x', true);
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn change_argument_method() {
    let s = Struct;
    s.method1('y', true);
}

// Change Callee (Method, UFCS) ------------------------------------------------
#[cfg(cfail1)]
pub fn change_ufcs_callee_method() {
    let s = Struct;
    Struct::method1(&s, 'x', true);
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn change_ufcs_callee_method() {
    let s = Struct;
    Struct::method2(&s, 'x', true);
}

// Change Argument (Method, UFCS) ----------------------------------------------
#[cfg(cfail1)]
pub fn change_argument_method_ufcs() {
    let s = Struct;
    Struct::method1(&s, 'x', true);
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn change_argument_method_ufcs() {
    let s = Struct;
    Struct::method1(&s, 'x', false);
}

// Change To UFCS --------------------------------------------------------------
#[cfg(cfail1)]
pub fn change_to_ufcs() {
    let s = Struct;
    s.method1('x', true);
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn change_to_ufcs() {
    let s = Struct;
    Struct::method1(&s, 'x', true);
}

struct Struct2;
impl Struct2 {
    fn method1(&self, _x: char, _y: bool) {}
}

// Change UFCS Callee Indirectly -----------------------------------------------
mod change_ufcs_callee_indirectly {
    #[cfg(cfail1)]
    use super::Struct as Struct;
    #[cfg(not(cfail1))]
    use super::Struct2 as Struct;

    #[rustc_dirty(label="Hir", cfg="cfail2")]
    #[rustc_clean(label="Hir", cfg="cfail3")]
    #[rustc_metadata_dirty(cfg="cfail2")]
    #[rustc_metadata_clean(cfg="cfail3")]
    pub fn change_ufcs_callee_indirectly() {
        let s = Struct;
        Struct::method1(&s, 'q', false)
    }
}
<|endoftext|>


<commit_before><commit_msg>Add test for ICE #6153<commit_after><|endoftext|>


<commit_before>//! A brainfuck interpreter compiled to Rust code.

#![crate_name="bf_bf_interpreter"]
#![crate_type="lib"]
#![feature(plugin)]

#[plugin] extern crate brainfuck_macros;

/// Return a function that was created by the `brainfuck!` macro
/// running on a brainfuck interpreter written in brainfuck. (Yo
/// dawg...).
pub fn bf() -> fn(&mut Reader, &mut Writer) -> std::io::IoResult<Vec<u8>> {
    brainfuck! {
        http://homepages.xnet.co.nz/~clive/eigenratios/cgbfi2.b

        Brainfuck Self Interpreter: by Clive Gifford

            Version 1: 01 December 2006 (one trip between code and data per op)
            Version 2: 16 December 2006 (virtual codes for various combinations)

            Credits

            A large section of code to load the input to the interpreter is copied
            from the the 423 byte dbfi interpreter as described in the November 2003
            paper "A Very Small Interpeter" by Oleg Mazonka and Daniel B Cristofani

            Goals

            The goal for this interpreter was to be efficient rather than small and
            particularly to allow as many copies of itself as possible to be "stacked"
            up with something else on top / In other words to achieve a low "eigenratio"
            (See http eigenratios dot blogspot dot com for more information)

            The main idea of the first version was to only make one round trip between
            the emulated code and emulated data for each instruction executed instead
            of multiple round trips which is what Daniel and Oleg's version does

            The second version does more pre processing of the guest program in order
            to map several common sequences to virtual codes thus reducing the memory
            footprint and also further reducing the number of round trips between the
            emulated code and data

            Other info:

        The input must consist of valid brainfuck code (to be interpreted) which
            must always be followed by an exclamation mark and then any associated data
            Input can also include "comments" (if desired) except for exclamation mark

            If you are stacking multiple copies of this interpreter then each additional
            level also has to appear in the input with a trailing exclamation mark and
            then we finally have the input for the very top level to finish things off

            The underlying brainfuck machine determines the possible range of values in
            the data cell values and what happens if an attempt is made to go outside the
            supported range but this interpreter does not more than 8 bit data itself

            Loops in the emulated code can be nested up to the maximum cell value in the
            underlying machine and this interpreter requires that at least 17 levels of
            nesting is supported

            Behaviour on end of input is also inherited from the next level down

            >>>>                        leave a little extra space before the program code
            +                           start in left hand cell of first program code pair
            [
  ->>>                      clear flag and move to the starting position
  ++>+>+++++++              setup differences and read char as per dbfi
  [<++++>>++<-]++>>+>+>     (by Daniel B Cristofani)
  +++++[>++>++++++<<-]
  +>>>,<++
  [
    [>[->>]<[>>]<<-]        see section 3 of dbfi paper
     <[<]<+>>[>]>
    [                       see section 4 of dbfi paper
      <+>-
      [[<+>-]>]             see section 5 of dbfi paper
      <                     see section 6 of dbfi paper
      [
        [[-]<]              scan left and zero the differences
        ++<-                see section 7 of dbfi paper
        [
          <+++++++++>[<->-]>>
        ]
        >>
      ]
    ]
    <<
  ]

 a three way switch to handle possibilities and adjust positioning

  >[-]+<<                   set "done" flag and position to value
  [
    --                      2 means last decode was for a valid instruction
    [                       so if we still have something left now it was a 9
      [-]                   originally (meaning input should be ignored)
      >>- <<<+>             so all we do is set the "more input" flag
    ]
    >>
    [
      -
      <<<<[>+<-]            for valid input move everything right one

 start of processing to find and recode certain combinations of codes

      +<<+                  set flags to indicate we want to process
                            the last two instructions in the loop below
      [
        ->                  clear flag and move to instruction
        [<+>>>>>>+<<<<<-]   double copy instruction and then
        <[>+<-]>>>>>>       restore original before moving to copy

 map relevant codes to values giving unique pairwise sums and also
 set a flag if we see the end of a loop

        >+<
        [
         -[
           -[
             -[
               -[
                 -[
                   -[
                     -[
                       -[
                          [-]
                          >-<
                        ]>[-<<+++++++>>] <
                      ]
                    ]
                  ]>[-]<
                ]>[-<<+++>>]<
              ]>[-<<+>>]<
            ]>[-]<
          ]>[-<<<<<<<+>>>>>>>]<   set flag if it is end of loop
        ]>[-]<
        <<<<                      goto next instruction flag
      ]

 add values from above together to get unique sum

      >>>[<<+>>-]
      <+<

 setup a switch to figure out what it means

      [
       -[
         -[
           -[
             -[
               -[
                 -[
                   -[
                     -[
                       -[
                         -[
                            [-]
                            >-<<<[-]<<+>>  change code 8 (add 1) to 9 (add 2)
                          ]
                        ]
                      ]
                    ]>[-]<
                  ]>[-<<<[-]<<+++++++>>>]< change code 4 (left) to 11 (left 2)
                ]
              ]
            ]>[-]<
          ]>[-<<<[-]<<+++++++>>>]<         change code 3 (right) to 10 (right 2)
        ]
      ]>[-]<

 clear flag set if second to last was end of loop
 and go to similar flag for last instruction

      <<<<<[-]>>
      [
        -
        <<<[>+>>+<<<-]>[<+>-]>>            copy third to last instruction

 if it is the start of a loop then we can (in some cases)
 collapse the last three instructions to single virtual code

        [
         -[
           -[
              [-]
              >>
            ]
            >
            [    Now we are ready to check what code is in the loop (must be at least 1)
              <<[<+>>+<-]>[<+>-]+<<
              -
              [
               -[
                 -[
                   -[
                     -[
                       -[
                         -[
                           -[
                             -[
                               -[
                                  -
                                  <+>         fall through & code as 16 (double skip left)
                                ]<+++++++++++++>>[-]>->-<<   code as 15 (double skip right)
                              ]
                            ]
                          ]>>[->>>>>]<<
                        ]>>[-<<<++++++++++++>>[-]>>-]<<      code as 14 (zero)
                      ]>>[->>>>>]<<
                    ]>>[-<<<+++++++++++>>[-]>>-]<<           code as 13 (skip left)
                  ]>>[-<<<++++++++++>>[-]>>-]<<              code as 12 (skip right)
                ]
              ]>>[->>>>>]<<
            ]
            <
          ]
        ]>[>>]<
        <<
      ]
      >>+>>>
    ]
    <<
  ]
  >> [->+>] <<              end of input so clear "done" and set data mark and
                            finally position to a zero cell ready for next phase

  <                         move to "more input" flag

]

<<[<<]>>                    go to the first instruction

                            ******** MAIN INTERPRETER LOOPS STARTS HERE ********

[                           start on current instruction code
                            setup a big switch statement to decode instructions
  [<+>>+<-]                 move/copy instruction code and set "done" flag to
  +<-                       start with (i less 1) (1) (i) for i = instruction
  [
   -[
     -[
       -[
         -[
           -[
             -[
               -[
                 -[
                   -[
                     -[
                       -[
                         -[
                           -[
                             -[
                                -           can't be anything but 1 so bracketing not needed
                                >->> [>>] >> [>>]< [<-<<-<] <[<<] << [<<]<   double skip left (code 16)
                              ]
                              >[->> [>>] >> [>>]< [>+>>+>] <[<<] << [<<]]<   double skip right (code 15)
                            ]
                            >[->> [>>] >> [>>] <[-]< [<<] << [<<]]<  zero (code 14)
                          ]
                          >[->> [>>] >> [>>]< [<-<] <[<<] << [<<]]<  skip left (code 13)
                        ]
                        >[->> [>>] >> [>>]< [>+>] <[<<] << [<<]]<    skip right  (code 12)
                      ]
                      >[->> [>>] >> [>>]< <-<<-< <[<<] << [<<]]<  double move left (code 11)
                    ]
                    >[->> [>>] >> [>>] +>>+ [<<] << [<<]]<        double move right (code 10)
                  ]
                  >[->> [>>] >> [>>]< ++ <[<<] << [<<]]<          add 2 (code 9)
                ]
                >[->> [>>] >> [>>]< + <[<<] << [<<]]<       increment
              ]
              >[->> [>>] >> [>>]< , <[<<] << [<<]]<         input
            ]
            >[->> [>>] >> [>>]< - <[<<] << [<<]]<           decrement
          ]
          >[->> [>>] >> [>>]< . <[<<] << [<<]]<             output
        ]
        >[->> [>>] >> [>>] <<-<< [<<] << [<<]]<             move left
      ]
      >[->> [>>] >> [>>] + [<<] << [<<]]<                   move right
    ]
    >
    [-                      left hand bracket
      >> [>>] >> [>>]<      move to data cell
      [>+>>+<<<-]>          make double copy and move to first
      [<+>-]                restore original data cell value
      >>[<<+>>[-]]+         This and the following achieves
      <<[>>-<<-]            x = not x
      >>                    go to flag cell (0 or 1)

      Some tricky stuff here: set up (not flag) also so we can later choose
      appropriate instruction sequence to get back to code area in one pass
      In one case we set flags at the other end (data greater than 0) but
      for the other we just go back without setting any flags (data equals 0)

      [<<+>>>>+<<-]         make two copies of flag
      >>[<<+>>-]
      <<[>>+<<-]+           This and the following achieves
      >>[<<->>-]<<          x = not x

      <<                    so we now have (data) (flag) () (not flag)

      [                     if flag set then
        -<< [<<] << [<<]<   clear and return to code section where we save
        << << ++            a 2 meaning we need (later) to match left bracket
        >>                  stop in zero cell for now
      ]

      >>                    if we executed code above then now at switch flag
                            else it will put us ready to return from data area

      [-<<<<<<[<<]<<[<<]<]  move back to switch flag without setting anything

      >
    ]
    <
  ]
  >
  [-                        right hand bracket
    >> [>>] >> [>>]<        move to data cell
    [>+>>+<<<-]>            make double copy and move to first
    [[<+>-]>>[-]+<<]        restore data from one then zero second and set flag
    >>                      go to flag cell (0 or 1)

    Some tricky stuff here: set up (not flag) also so we can later choose
    appropriate instruction sequence to get back to code area in one pass
    In one case we set flags at the other end (data greater than 0) but
    for the other we just go back without setting any flags (data equals 0)

    [<<+>>>>+<<-]           make two copes of flag
    >>[<<+>>-]
    <<[>>+<<-]+             This and the following achieves
    >>[<<->>-]<<            x = not x

    <<                      so we now have (data) (flag) () (not flag)

    [                       if flag set then
      -<< [<<] << [<<]<     clear and return to code section where we save
      << << +               a 1 meaning we need (later) to match right bracket
      >>                    stop in zero cell for now
    ]

    >>                      if we executed code above then now at switch flag
                            else it will put us ready to return from data area

    [-<<<<<<[<<]<<[<<]<]    move back to switch flag without setting anything

    >
  ]

  >[<+>-]                   restore original instruction code

  *** We are positioned in the cell immediately to the right of the   ***
  *** instruction that has just been "executed" in the switch above   ***
  *** The following code is to handle finding matching brackets       ***
  *** because code above has only set a cell value to 1 or 2 to show  ***
  *** what kind of loop scanning is required (1=scan left 2=right)    ***

  << << <<                  position to cell showing if matching required
  [                         if non zero we need to find a matching bracket
    >> +                    set up "done" flag for switch and
    << -                    decrement switch value so now is 0 or 1
    [                       if 1 we are looking for matching right bracket
      - >> - >> +           clear switch value & "done" & set level to 1
      [                     while level is more than 0
        >>>[-<+>>+<]        make double copy of instruction code
        +<-                 set flag and prepare for switch
        [
         -[
            [-]             clear whatever is left of code
            > - <           do nothing except clear flag
          ]
          > [- <<< + >>>] < increment level
        ]
        > [- <<< - >>>]     decrement level

        >[-<+>]<<           restore instruction code

        <<                  go to level
        [>>+<<-]            if level then move right one instruction
        >>
      ]
      << << <<              go back to switch value cell
    ]
    >>                      go to switch done flag and if still set then
    [                       we must be looking for a matching left bracket
      - << +                clear switch value & "done" & set level to 1
      [                     repeat while level is more than 0
        >>>[-<+>>+<]        make double copy of instruction code
        +<-                 set flag and prepare for switch
        [
         -[
            [-]             clear whatever is left of code
            > - <           do nothing except clear flag
          ]
          > [- <<< - >>>] < decrement level
        ]
        > [- <<< + >>>]     increment level

        >[-<+>]<<           restore instruction code

        <<                  go to level
        [<<+>>-]            if level then move left one instruction
        <<
      ]
    ]
  ]

  >> >> >>

  >                         move forward to next instruction
]
    }
}

#[test]
fn bf_interpreter() {
    use std::{io, str};
    let mut input = io::BufReader::new(b"++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>
         ---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.!");
    let mut out = io::MemWriter::new();
    assert!(bf()(&mut input, &mut out).is_ok());

    assert_eq!(str::from_utf8(&*out.into_inner()).ok().expect("non-UTF8 bf output"),
               "Hello World!\n");
}
<commit_msg>Missed a spot, for c5961ad06 2015-01-28 21:49:38 +0000.<commit_after>//! A brainfuck interpreter compiled to Rust code.

#![crate_name="bf_bf_interpreter"]
#![crate_type="lib"]
#![feature(plugin)]

#[plugin] extern crate brainfuck_macros;

/// Return a function that was created by the `brainfuck!` macro
/// running on a brainfuck interpreter written in brainfuck. (Yo
/// dawg...).
pub fn bf() -> fn(&mut Reader, &mut Writer) -> std::old_io::IoResult<Vec<u8>> {
    brainfuck! {
        http://homepages.xnet.co.nz/~clive/eigenratios/cgbfi2.b

        Brainfuck Self Interpreter: by Clive Gifford

            Version 1: 01 December 2006 (one trip between code and data per op)
            Version 2: 16 December 2006 (virtual codes for various combinations)

            Credits

            A large section of code to load the input to the interpreter is copied
            from the the 423 byte dbfi interpreter as described in the November 2003
            paper "A Very Small Interpeter" by Oleg Mazonka and Daniel B Cristofani

            Goals

            The goal for this interpreter was to be efficient rather than small and
            particularly to allow as many copies of itself as possible to be "stacked"
            up with something else on top / In other words to achieve a low "eigenratio"
            (See http eigenratios dot blogspot dot com for more information)

            The main idea of the first version was to only make one round trip between
            the emulated code and emulated data for each instruction executed instead
            of multiple round trips which is what Daniel and Oleg's version does

            The second version does more pre processing of the guest program in order
            to map several common sequences to virtual codes thus reducing the memory
            footprint and also further reducing the number of round trips between the
            emulated code and data

            Other info:

        The input must consist of valid brainfuck code (to be interpreted) which
            must always be followed by an exclamation mark and then any associated data
            Input can also include "comments" (if desired) except for exclamation mark

            If you are stacking multiple copies of this interpreter then each additional
            level also has to appear in the input with a trailing exclamation mark and
            then we finally have the input for the very top level to finish things off

            The underlying brainfuck machine determines the possible range of values in
            the data cell values and what happens if an attempt is made to go outside the
            supported range but this interpreter does not more than 8 bit data itself

            Loops in the emulated code can be nested up to the maximum cell value in the
            underlying machine and this interpreter requires that at least 17 levels of
            nesting is supported

            Behaviour on end of input is also inherited from the next level down

            >>>>                        leave a little extra space before the program code
            +                           start in left hand cell of first program code pair
            [
  ->>>                      clear flag and move to the starting position
  ++>+>+++++++              setup differences and read char as per dbfi
  [<++++>>++<-]++>>+>+>     (by Daniel B Cristofani)
  +++++[>++>++++++<<-]
  +>>>,<++
  [
    [>[->>]<[>>]<<-]        see section 3 of dbfi paper
     <[<]<+>>[>]>
    [                       see section 4 of dbfi paper
      <+>-
      [[<+>-]>]             see section 5 of dbfi paper
      <                     see section 6 of dbfi paper
      [
        [[-]<]              scan left and zero the differences
        ++<-                see section 7 of dbfi paper
        [
          <+++++++++>[<->-]>>
        ]
        >>
      ]
    ]
    <<
  ]

 a three way switch to handle possibilities and adjust positioning

  >[-]+<<                   set "done" flag and position to value
  [
    --                      2 means last decode was for a valid instruction
    [                       so if we still have something left now it was a 9
      [-]                   originally (meaning input should be ignored)
      >>- <<<+>             so all we do is set the "more input" flag
    ]
    >>
    [
      -
      <<<<[>+<-]            for valid input move everything right one

 start of processing to find and recode certain combinations of codes

      +<<+                  set flags to indicate we want to process
                            the last two instructions in the loop below
      [
        ->                  clear flag and move to instruction
        [<+>>>>>>+<<<<<-]   double copy instruction and then
        <[>+<-]>>>>>>       restore original before moving to copy

 map relevant codes to values giving unique pairwise sums and also
 set a flag if we see the end of a loop

        >+<
        [
         -[
           -[
             -[
               -[
                 -[
                   -[
                     -[
                       -[
                          [-]
                          >-<
                        ]>[-<<+++++++>>] <
                      ]
                    ]
                  ]>[-]<
                ]>[-<<+++>>]<
              ]>[-<<+>>]<
            ]>[-]<
          ]>[-<<<<<<<+>>>>>>>]<   set flag if it is end of loop
        ]>[-]<
        <<<<                      goto next instruction flag
      ]

 add values from above together to get unique sum

      >>>[<<+>>-]
      <+<

 setup a switch to figure out what it means

      [
       -[
         -[
           -[
             -[
               -[
                 -[
                   -[
                     -[
                       -[
                         -[
                            [-]
                            >-<<<[-]<<+>>  change code 8 (add 1) to 9 (add 2)
                          ]
                        ]
                      ]
                    ]>[-]<
                  ]>[-<<<[-]<<+++++++>>>]< change code 4 (left) to 11 (left 2)
                ]
              ]
            ]>[-]<
          ]>[-<<<[-]<<+++++++>>>]<         change code 3 (right) to 10 (right 2)
        ]
      ]>[-]<

 clear flag set if second to last was end of loop
 and go to similar flag for last instruction

      <<<<<[-]>>
      [
        -
        <<<[>+>>+<<<-]>[<+>-]>>            copy third to last instruction

 if it is the start of a loop then we can (in some cases)
 collapse the last three instructions to single virtual code

        [
         -[
           -[
              [-]
              >>
            ]
            >
            [    Now we are ready to check what code is in the loop (must be at least 1)
              <<[<+>>+<-]>[<+>-]+<<
              -
              [
               -[
                 -[
                   -[
                     -[
                       -[
                         -[
                           -[
                             -[
                               -[
                                  -
                                  <+>         fall through & code as 16 (double skip left)
                                ]<+++++++++++++>>[-]>->-<<   code as 15 (double skip right)
                              ]
                            ]
                          ]>>[->>>>>]<<
                        ]>>[-<<<++++++++++++>>[-]>>-]<<      code as 14 (zero)
                      ]>>[->>>>>]<<
                    ]>>[-<<<+++++++++++>>[-]>>-]<<           code as 13 (skip left)
                  ]>>[-<<<++++++++++>>[-]>>-]<<              code as 12 (skip right)
                ]
              ]>>[->>>>>]<<
            ]
            <
          ]
        ]>[>>]<
        <<
      ]
      >>+>>>
    ]
    <<
  ]
  >> [->+>] <<              end of input so clear "done" and set data mark and
                            finally position to a zero cell ready for next phase

  <                         move to "more input" flag

]

<<[<<]>>                    go to the first instruction

                            ******** MAIN INTERPRETER LOOPS STARTS HERE ********

[                           start on current instruction code
                            setup a big switch statement to decode instructions
  [<+>>+<-]                 move/copy instruction code and set "done" flag to
  +<-                       start with (i less 1) (1) (i) for i = instruction
  [
   -[
     -[
       -[
         -[
           -[
             -[
               -[
                 -[
                   -[
                     -[
                       -[
                         -[
                           -[
                             -[
                                -           can't be anything but 1 so bracketing not needed
                                >->> [>>] >> [>>]< [<-<<-<] <[<<] << [<<]<   double skip left (code 16)
                              ]
                              >[->> [>>] >> [>>]< [>+>>+>] <[<<] << [<<]]<   double skip right (code 15)
                            ]
                            >[->> [>>] >> [>>] <[-]< [<<] << [<<]]<  zero (code 14)
                          ]
                          >[->> [>>] >> [>>]< [<-<] <[<<] << [<<]]<  skip left (code 13)
                        ]
                        >[->> [>>] >> [>>]< [>+>] <[<<] << [<<]]<    skip right  (code 12)
                      ]
                      >[->> [>>] >> [>>]< <-<<-< <[<<] << [<<]]<  double move left (code 11)
                    ]
                    >[->> [>>] >> [>>] +>>+ [<<] << [<<]]<        double move right (code 10)
                  ]
                  >[->> [>>] >> [>>]< ++ <[<<] << [<<]]<          add 2 (code 9)
                ]
                >[->> [>>] >> [>>]< + <[<<] << [<<]]<       increment
              ]
              >[->> [>>] >> [>>]< , <[<<] << [<<]]<         input
            ]
            >[->> [>>] >> [>>]< - <[<<] << [<<]]<           decrement
          ]
          >[->> [>>] >> [>>]< . <[<<] << [<<]]<             output
        ]
        >[->> [>>] >> [>>] <<-<< [<<] << [<<]]<             move left
      ]
      >[->> [>>] >> [>>] + [<<] << [<<]]<                   move right
    ]
    >
    [-                      left hand bracket
      >> [>>] >> [>>]<      move to data cell
      [>+>>+<<<-]>          make double copy and move to first
      [<+>-]                restore original data cell value
      >>[<<+>>[-]]+         This and the following achieves
      <<[>>-<<-]            x = not x
      >>                    go to flag cell (0 or 1)

      Some tricky stuff here: set up (not flag) also so we can later choose
      appropriate instruction sequence to get back to code area in one pass
      In one case we set flags at the other end (data greater than 0) but
      for the other we just go back without setting any flags (data equals 0)

      [<<+>>>>+<<-]         make two copies of flag
      >>[<<+>>-]
      <<[>>+<<-]+           This and the following achieves
      >>[<<->>-]<<          x = not x

      <<                    so we now have (data) (flag) () (not flag)

      [                     if flag set then
        -<< [<<] << [<<]<   clear and return to code section where we save
        << << ++            a 2 meaning we need (later) to match left bracket
        >>                  stop in zero cell for now
      ]

      >>                    if we executed code above then now at switch flag
                            else it will put us ready to return from data area

      [-<<<<<<[<<]<<[<<]<]  move back to switch flag without setting anything

      >
    ]
    <
  ]
  >
  [-                        right hand bracket
    >> [>>] >> [>>]<        move to data cell
    [>+>>+<<<-]>            make double copy and move to first
    [[<+>-]>>[-]+<<]        restore data from one then zero second and set flag
    >>                      go to flag cell (0 or 1)

    Some tricky stuff here: set up (not flag) also so we can later choose
    appropriate instruction sequence to get back to code area in one pass
    In one case we set flags at the other end (data greater than 0) but
    for the other we just go back without setting any flags (data equals 0)

    [<<+>>>>+<<-]           make two copes of flag
    >>[<<+>>-]
    <<[>>+<<-]+             This and the following achieves
    >>[<<->>-]<<            x = not x

    <<                      so we now have (data) (flag) () (not flag)

    [                       if flag set then
      -<< [<<] << [<<]<     clear and return to code section where we save
      << << +               a 1 meaning we need (later) to match right bracket
      >>                    stop in zero cell for now
    ]

    >>                      if we executed code above then now at switch flag
                            else it will put us ready to return from data area

    [-<<<<<<[<<]<<[<<]<]    move back to switch flag without setting anything

    >
  ]

  >[<+>-]                   restore original instruction code

  *** We are positioned in the cell immediately to the right of the   ***
  *** instruction that has just been "executed" in the switch above   ***
  *** The following code is to handle finding matching brackets       ***
  *** because code above has only set a cell value to 1 or 2 to show  ***
  *** what kind of loop scanning is required (1=scan left 2=right)    ***

  << << <<                  position to cell showing if matching required
  [                         if non zero we need to find a matching bracket
    >> +                    set up "done" flag for switch and
    << -                    decrement switch value so now is 0 or 1
    [                       if 1 we are looking for matching right bracket
      - >> - >> +           clear switch value & "done" & set level to 1
      [                     while level is more than 0
        >>>[-<+>>+<]        make double copy of instruction code
        +<-                 set flag and prepare for switch
        [
         -[
            [-]             clear whatever is left of code
            > - <           do nothing except clear flag
          ]
          > [- <<< + >>>] < increment level
        ]
        > [- <<< - >>>]     decrement level

        >[-<+>]<<           restore instruction code

        <<                  go to level
        [>>+<<-]            if level then move right one instruction
        >>
      ]
      << << <<              go back to switch value cell
    ]
    >>                      go to switch done flag and if still set then
    [                       we must be looking for a matching left bracket
      - << +                clear switch value & "done" & set level to 1
      [                     repeat while level is more than 0
        >>>[-<+>>+<]        make double copy of instruction code
        +<-                 set flag and prepare for switch
        [
         -[
            [-]             clear whatever is left of code
            > - <           do nothing except clear flag
          ]
          > [- <<< - >>>] < decrement level
        ]
        > [- <<< + >>>]     increment level

        >[-<+>]<<           restore instruction code

        <<                  go to level
        [<<+>>-]            if level then move left one instruction
        <<
      ]
    ]
  ]

  >> >> >>

  >                         move forward to next instruction
]
    }
}

#[test]
fn bf_interpreter() {
    use std::{io, str};
    let mut input = io::BufReader::new(b"++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>
         ---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.!");
    let mut out = io::MemWriter::new();
    assert!(bf()(&mut input, &mut out).is_ok());

    assert_eq!(str::from_utf8(&*out.into_inner()).ok().expect("non-UTF8 bf output"),
               "Hello World!\n");
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//! Data structure measurement.

use libc::{c_void, size_t};
use std::cell::RefCell;
use std::collections::LinkedList;
use std::mem::transmute;
use std::sync::Arc;

use azure::azure_hl::Color;
use cursor::Cursor;
use euclid::{Point2D, Rect, SideOffsets2D, Size2D, Matrix2D, Matrix4};
use geometry::Au;
use range::Range;

extern {
    // Get the size of a heap block.
    //
    // Ideally Rust would expose a function like this in std::rt::heap, which would avoid the
    // jemalloc dependence.
    //
    // The C prototype is `je_malloc_usable_size(JEMALLOC_USABLE_SIZE_CONST void *ptr)`. On some
    // platforms `JEMALLOC_USABLE_SIZE_CONST` is `const` and on some it is empty. But in practice
    // this function doesn't modify the contents of the block that `ptr` points to, so we use
    // `*const c_void` here.
    fn je_malloc_usable_size(ptr: *const c_void) -> size_t;
}

// A wrapper for je_malloc_usable_size that handles `EMPTY` and returns `usize`.
pub fn heap_size_of(ptr: *const c_void) -> usize {
    if ptr == ::std::rt::heap::EMPTY as *const c_void {
        0
    } else {
        unsafe { je_malloc_usable_size(ptr) as usize }
    }
}

// The simplest trait for measuring the size of heap data structures. More complex traits that
// return multiple measurements -- e.g. measure text separately from images -- are also possible,
// and should be used when appropriate.
//
pub trait HeapSizeOf {
    /// Measure the size of any heap-allocated structures that hang off this value, but not the
    /// space taken up by the value itself (i.e. what size_of::<T> measures, more or less); that
    /// space is handled by the implementation of HeapSizeOf for Box<T> below.
    fn heap_size_of_children(&self) -> usize;
}

// There are two possible ways to measure the size of `self` when it's on the heap: compute it
// (with `::std::rt::heap::usable_size(::std::mem::size_of::<T>(), 0)`) or measure it directly
// using the heap allocator (with `heap_size_of`). We do the latter, for the following reasons.
//
// * The heap allocator is the true authority for the sizes of heap blocks; its measurement is
//   guaranteed to be correct. In comparison, size computations are error-prone. (For example, the
//   `rt::heap::usable_size` function used in some of Rust's non-default allocator implementations
//   underestimate the true usable size of heap blocks, which is safe in general but would cause
//   under-measurement here.)
//
// * If we measure something that isn't a heap block, we'll get a crash. This keeps us honest,
//   which is important because unsafe code is involved and this can be gotten wrong.
//
// However, in the best case, the two approaches should give the same results.
//
impl<T: HeapSizeOf> HeapSizeOf for Box<T> {
    fn heap_size_of_children(&self) -> usize {
        // Measure size of `self`.
        heap_size_of(&**self as *const T as *const c_void) + (**self).heap_size_of_children()
    }
}

impl HeapSizeOf for String {
    fn heap_size_of_children(&self) -> usize {
        heap_size_of(self.as_ptr() as *const c_void)
    }
}

impl<T: HeapSizeOf> HeapSizeOf for Option<T> {
    fn heap_size_of_children(&self) -> usize {
        match *self {
            None => 0,
            Some(ref x) => x.heap_size_of_children()
        }
    }
}

impl<T: HeapSizeOf> HeapSizeOf for Arc<T> {
    fn heap_size_of_children(&self) -> usize {
        (**self).heap_size_of_children()
    }
}

impl<T: HeapSizeOf> HeapSizeOf for RefCell<T> {
    fn heap_size_of_children(&self) -> usize {
        self.borrow().heap_size_of_children()
    }
}

impl<T: HeapSizeOf> HeapSizeOf for Vec<T> {
    fn heap_size_of_children(&self) -> usize {
        heap_size_of(self.as_ptr() as *const c_void) +
            self.iter().fold(0, |n, elem| n + elem.heap_size_of_children())
    }
}

// FIXME(njn): We can't implement HeapSizeOf accurately for LinkedList because it requires access
// to the private Node type. Eventually we'll want to add HeapSizeOf (or equivalent) to Rust
// itself. In the meantime, we use the dirty hack of transmuting LinkedList into an identical type
// (LinkedList2) and measuring that.
impl<T: HeapSizeOf> HeapSizeOf for LinkedList<T> {
    fn heap_size_of_children(&self) -> usize {
        let list2: &LinkedList2<T> = unsafe { transmute(self) };
        list2.heap_size_of_children()
    }
}

struct LinkedList2<T> {
    _length: usize,
    list_head: Link<T>,
    _list_tail: Rawlink<Node<T>>,
}

type Link<T> = Option<Box<Node<T>>>;

struct Rawlink<T> {
    _p: *mut T,
}

struct Node<T> {
    next: Link<T>,
    _prev: Rawlink<Node<T>>,
    value: T,
}

impl<T: HeapSizeOf> HeapSizeOf for Node<T> {
    // Unlike most heap_size_of_children() functions, this one does *not* measure descendents.
    // Instead, LinkedList2<T>::heap_size_of_children() handles that, so that it can use iteration
    // instead of recursion, which avoids potentially blowing the stack.
    fn heap_size_of_children(&self) -> usize {
        self.value.heap_size_of_children()
    }
}

impl<T: HeapSizeOf> HeapSizeOf for LinkedList2<T> {
    fn heap_size_of_children(&self) -> usize {
        let mut size = 0;
        let mut curr: &Link<T> = &self.list_head;
        while curr.is_some() {
            size += (*curr).heap_size_of_children();
            curr = &curr.as_ref().unwrap().next;
        }
        size
    }
}

// This is a basic sanity check. If the representation of LinkedList changes such that it becomes a
// different size to LinkedList2, this will fail at compile-time.
#[allow(dead_code)]
unsafe fn linked_list2_check() {
    transmute::<LinkedList<i32>, LinkedList2<i32>>(panic!());
}

// Currently, types that implement the Drop type are larger than those that don't. Because
// LinkedList implements Drop, LinkedList2 must also so that linked_list2_check() doesn't fail.
impl<T> Drop for LinkedList2<T> {
    fn drop(&mut self) {}
}

/// For use on types defined in external crates
/// with known heap sizes.
#[macro_export]
macro_rules! known_heap_size(
    ($size:expr, $($ty:ident),+) => (
        $(
            impl $crate::mem::HeapSizeOf for $ty {
                #[inline(always)]
                fn heap_size_of_children(&self) -> usize {
                    $size
                }
            }
        )+
    );
    ($size: expr, $($ty:ident<$($gen:ident),+>),+) => (
        $(
        impl<$($gen: $crate::mem::HeapSizeOf),+> $crate::mem::HeapSizeOf for $ty<$($gen),+> {
            #[inline(always)]
            fn heap_size_of_children(&self) -> usize {
                $size
            }
        }
        )+
    );
);

known_heap_size!(0, u8, u16, u32, u64, usize);
known_heap_size!(0, i8, i16, i32, i64, isize);
known_heap_size!(0, bool, f32, f64);

known_heap_size!(0, Rect<T>, Point2D<T>, Size2D<T>, Matrix2D<T>, SideOffsets2D<T>);

known_heap_size!(0, Au, Color, Cursor, Matrix4);
known_heap_size!(0, Range<T>);
<commit_msg>Implement HeapSizeOf for Url. Fixes #6912<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//! Data structure measurement.

use libc::{c_void, size_t};
use std::cell::RefCell;
use std::collections::LinkedList;
use std::mem::transmute;
use std::sync::Arc;

use azure::azure_hl::Color;
use cursor::Cursor;
use euclid::{Point2D, Rect, SideOffsets2D, Size2D, Matrix2D, Matrix4};
use geometry::Au;
use range::Range;
use url;

extern {
    // Get the size of a heap block.
    //
    // Ideally Rust would expose a function like this in std::rt::heap, which would avoid the
    // jemalloc dependence.
    //
    // The C prototype is `je_malloc_usable_size(JEMALLOC_USABLE_SIZE_CONST void *ptr)`. On some
    // platforms `JEMALLOC_USABLE_SIZE_CONST` is `const` and on some it is empty. But in practice
    // this function doesn't modify the contents of the block that `ptr` points to, so we use
    // `*const c_void` here.
    fn je_malloc_usable_size(ptr: *const c_void) -> size_t;
}

// A wrapper for je_malloc_usable_size that handles `EMPTY` and returns `usize`.
pub fn heap_size_of(ptr: *const c_void) -> usize {
    if ptr == ::std::rt::heap::EMPTY as *const c_void {
        0
    } else {
        unsafe { je_malloc_usable_size(ptr) as usize }
    }
}

// The simplest trait for measuring the size of heap data structures. More complex traits that
// return multiple measurements -- e.g. measure text separately from images -- are also possible,
// and should be used when appropriate.
//
pub trait HeapSizeOf {
    /// Measure the size of any heap-allocated structures that hang off this value, but not the
    /// space taken up by the value itself (i.e. what size_of::<T> measures, more or less); that
    /// space is handled by the implementation of HeapSizeOf for Box<T> below.
    fn heap_size_of_children(&self) -> usize;
}

// There are two possible ways to measure the size of `self` when it's on the heap: compute it
// (with `::std::rt::heap::usable_size(::std::mem::size_of::<T>(), 0)`) or measure it directly
// using the heap allocator (with `heap_size_of`). We do the latter, for the following reasons.
//
// * The heap allocator is the true authority for the sizes of heap blocks; its measurement is
//   guaranteed to be correct. In comparison, size computations are error-prone. (For example, the
//   `rt::heap::usable_size` function used in some of Rust's non-default allocator implementations
//   underestimate the true usable size of heap blocks, which is safe in general but would cause
//   under-measurement here.)
//
// * If we measure something that isn't a heap block, we'll get a crash. This keeps us honest,
//   which is important because unsafe code is involved and this can be gotten wrong.
//
// However, in the best case, the two approaches should give the same results.
//
impl<T: HeapSizeOf> HeapSizeOf for Box<T> {
    fn heap_size_of_children(&self) -> usize {
        // Measure size of `self`.
        heap_size_of(&**self as *const T as *const c_void) + (**self).heap_size_of_children()
    }
}

impl HeapSizeOf for String {
    fn heap_size_of_children(&self) -> usize {
        heap_size_of(self.as_ptr() as *const c_void)
    }
}

impl<T: HeapSizeOf> HeapSizeOf for Option<T> {
    fn heap_size_of_children(&self) -> usize {
        match *self {
            None => 0,
            Some(ref x) => x.heap_size_of_children()
        }
    }
}

impl HeapSizeOf for url::Url {
    fn heap_size_of_children(&self) -> usize {
        let &url::Url { ref scheme, ref scheme_data, ref query, ref fragment } = self;
        scheme.heap_size_of_children() +
        scheme_data.heap_size_of_children() +
        query.heap_size_of_children() +
        fragment.heap_size_of_children()
    }
}

impl HeapSizeOf for url::SchemeData {
    fn heap_size_of_children(&self) -> usize {
        match self {
            &url::SchemeData::Relative(ref data) => data.heap_size_of_children(),
            &url::SchemeData::NonRelative(ref str) => str.heap_size_of_children()
        }
    }
}

impl HeapSizeOf for url::RelativeSchemeData {
    fn heap_size_of_children(&self) -> usize {
        let &url::RelativeSchemeData { ref username, ref password, ref host,
                                       ref port, ref default_port, ref path } = self;
        username.heap_size_of_children() +
        password.heap_size_of_children() +
        host.heap_size_of_children() +
        port.heap_size_of_children() +
        default_port.heap_size_of_children() +
        path.heap_size_of_children()
    }
}

impl HeapSizeOf for url::Host {
    fn heap_size_of_children(&self) -> usize {
        match self {
            &url::Host::Domain(ref str) => str.heap_size_of_children(),
            &url::Host::Ipv6(_) => 0
        }
    }
}

impl<T: HeapSizeOf> HeapSizeOf for Arc<T> {
    fn heap_size_of_children(&self) -> usize {
        (**self).heap_size_of_children()
    }
}

impl<T: HeapSizeOf> HeapSizeOf for RefCell<T> {
    fn heap_size_of_children(&self) -> usize {
        self.borrow().heap_size_of_children()
    }
}

impl<T: HeapSizeOf> HeapSizeOf for Vec<T> {
    fn heap_size_of_children(&self) -> usize {
        heap_size_of(self.as_ptr() as *const c_void) +
            self.iter().fold(0, |n, elem| n + elem.heap_size_of_children())
    }
}

// FIXME(njn): We can't implement HeapSizeOf accurately for LinkedList because it requires access
// to the private Node type. Eventually we'll want to add HeapSizeOf (or equivalent) to Rust
// itself. In the meantime, we use the dirty hack of transmuting LinkedList into an identical type
// (LinkedList2) and measuring that.
impl<T: HeapSizeOf> HeapSizeOf for LinkedList<T> {
    fn heap_size_of_children(&self) -> usize {
        let list2: &LinkedList2<T> = unsafe { transmute(self) };
        list2.heap_size_of_children()
    }
}

struct LinkedList2<T> {
    _length: usize,
    list_head: Link<T>,
    _list_tail: Rawlink<Node<T>>,
}

type Link<T> = Option<Box<Node<T>>>;

struct Rawlink<T> {
    _p: *mut T,
}

struct Node<T> {
    next: Link<T>,
    _prev: Rawlink<Node<T>>,
    value: T,
}

impl<T: HeapSizeOf> HeapSizeOf for Node<T> {
    // Unlike most heap_size_of_children() functions, this one does *not* measure descendents.
    // Instead, LinkedList2<T>::heap_size_of_children() handles that, so that it can use iteration
    // instead of recursion, which avoids potentially blowing the stack.
    fn heap_size_of_children(&self) -> usize {
        self.value.heap_size_of_children()
    }
}

impl<T: HeapSizeOf> HeapSizeOf for LinkedList2<T> {
    fn heap_size_of_children(&self) -> usize {
        let mut size = 0;
        let mut curr: &Link<T> = &self.list_head;
        while curr.is_some() {
            size += (*curr).heap_size_of_children();
            curr = &curr.as_ref().unwrap().next;
        }
        size
    }
}

// This is a basic sanity check. If the representation of LinkedList changes such that it becomes a
// different size to LinkedList2, this will fail at compile-time.
#[allow(dead_code)]
unsafe fn linked_list2_check() {
    transmute::<LinkedList<i32>, LinkedList2<i32>>(panic!());
}

// Currently, types that implement the Drop type are larger than those that don't. Because
// LinkedList implements Drop, LinkedList2 must also so that linked_list2_check() doesn't fail.
impl<T> Drop for LinkedList2<T> {
    fn drop(&mut self) {}
}

/// For use on types defined in external crates
/// with known heap sizes.
#[macro_export]
macro_rules! known_heap_size(
    ($size:expr, $($ty:ident),+) => (
        $(
            impl $crate::mem::HeapSizeOf for $ty {
                #[inline(always)]
                fn heap_size_of_children(&self) -> usize {
                    $size
                }
            }
        )+
    );
    ($size: expr, $($ty:ident<$($gen:ident),+>),+) => (
        $(
        impl<$($gen: $crate::mem::HeapSizeOf),+> $crate::mem::HeapSizeOf for $ty<$($gen),+> {
            #[inline(always)]
            fn heap_size_of_children(&self) -> usize {
                $size
            }
        }
        )+
    );
);

known_heap_size!(0, u8, u16, u32, u64, usize);
known_heap_size!(0, i8, i16, i32, i64, isize);
known_heap_size!(0, bool, f32, f64);

known_heap_size!(0, Rect<T>, Point2D<T>, Size2D<T>, Matrix2D<T>, SideOffsets2D<T>);

known_heap_size!(0, Au, Color, Cursor, Matrix4);
known_heap_size!(0, Range<T>);
<|endoftext|>