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

#[allow(missing_doc)];

use digest::DigestUtil;
use json;
use sha1::Sha1;
use serialize::{Encoder, Encodable, Decoder, Decodable};
use treemap::TreeMap;

use std::cell::Cell;
use std::comm::{PortOne, oneshot, send_one, recv_one};
use std::either::{Either, Left, Right};
use std::hashmap::HashMap;
use std::io;
use std::result;
use std::run;
use std::task;

/**
*
* This is a loose clone of the [fbuild build system](https://github.com/felix-lang/fbuild),
* made a touch more generic (not wired to special cases on files) and much
* less metaprogram-y due to rust's comparative weakness there, relative to
* python.
*
* It's based around _imperative builds_ that happen to have some function
* calls cached. That is, it's _just_ a mechanism for describing cached
* functions. This makes it much simpler and smaller than a "build system"
* that produces an IR and evaluates it. The evaluation order is normal
* function calls. Some of them just return really quickly.
*
* A cached function consumes and produces a set of _works_. A work has a
* name, a kind (that determines how the value is to be checked for
* freshness) and a value. Works must also be (de)serializable. Some
* examples of works:
*
*    kind   name    value
*   ------------------------
*    cfg    os      linux
*    file   foo.c   <sha1>
*    url    foo.com <etag>
*
* Works are conceptually single units, but we store them most of the time
* in maps of the form (type,name) => value. These are WorkMaps.
*
* A cached function divides the works it's interested in into inputs and
* outputs, and subdivides those into declared (input) works and
* discovered (input and output) works.
*
* A _declared_ input or is one that is given to the workcache before
* any work actually happens, in the "prep" phase. Even when a function's
* work-doing part (the "exec" phase) never gets called, it has declared
* inputs, which can be checked for freshness (and potentially
* used to determine that the function can be skipped).
*
* The workcache checks _all_ works for freshness, but uses the set of
* discovered outputs from the _previous_ exec (which it will re-discover
* and re-record each time the exec phase runs).
*
* Therefore the discovered works cached in the db might be a
* mis-approximation of the current discoverable works, but this is ok for
* the following reason: we assume that if an artifact A changed from
* depending on B,C,D to depending on B,C,D,E, then A itself changed (as
* part of the change-in-dependencies), so we will be ok.
*
* Each function has a single discriminated output work called its _result_.
* This is only different from other works in that it is returned, by value,
* from a call to the cacheable function; the other output works are used in
* passing to invalidate dependencies elsewhere in the cache, but do not
* otherwise escape from a function invocation. Most functions only have one
* output work anyways.
*
* A database (the central store of a workcache) stores a mappings:
*
* (fn_name,{declared_input}) => ({discovered_input},
*                                {discovered_output},result)
*
* (Note: fbuild, which workcache is based on, has the concept of a declared
* output as separate from a discovered output. This distinction exists only
* as an artifact of how fbuild works: via annotations on function types
* and metaprogramming, with explicit dependency declaration as a fallback.
* Workcache is more explicit about dependencies, and as such treats all
* outputs the same, as discovered-during-the-last-run.)
*
*/

#[deriving(Clone, Eq, Encodable, Decodable, TotalOrd, TotalEq)]
struct WorkKey {
    kind: ~str,
    name: ~str
}

impl WorkKey {
    pub fn new(kind: &str, name: &str) -> WorkKey {
        WorkKey {
            kind: kind.to_owned(),
            name: name.to_owned(),
        }
    }
}

#[deriving(Clone, Eq, Encodable, Decodable)]
struct WorkMap(TreeMap<WorkKey, ~str>);

impl WorkMap {
    fn new() -> WorkMap { WorkMap(TreeMap::new()) }
}

struct Database {
    db_filename: Path,
    db_cache: TreeMap<~str, ~str>,
    db_dirty: bool
}

impl Database {
    pub fn prepare(&mut self,
                   fn_name: &str,
                   declared_inputs: &WorkMap)
                   -> Option<(WorkMap, WorkMap, ~str)> {
        let k = json_encode(&(fn_name, declared_inputs));
        match self.db_cache.find(&k) {
            None => None,
            Some(v) => Some(json_decode(*v))
        }
    }

    pub fn cache(&mut self,
                 fn_name: &str,
                 declared_inputs: &WorkMap,
                 discovered_inputs: &WorkMap,
                 discovered_outputs: &WorkMap,
                 result: &str) {
        let k = json_encode(&(fn_name, declared_inputs));
        let v = json_encode(&(discovered_inputs,
                              discovered_outputs,
                              result));
        self.db_cache.insert(k,v);
        self.db_dirty = true
    }
}

struct Logger {
    // FIXME #4432: Fill in
    a: ()
}

impl Logger {
    pub fn info(&self, i: &str) {
        io::println(~"workcache: " + i);
    }
}

struct Context {
    db: @mut Database,
    logger: @mut Logger,
    cfg: @json::Object,
    freshness: TreeMap<~str,@fn(&str,&str)->bool>
}

#[deriving(Clone)]
struct Prep {
    ctxt: @Context,
    fn_name: ~str,
    declared_inputs: WorkMap,
}

struct Exec {
    discovered_inputs: WorkMap,
    discovered_outputs: WorkMap
}

struct Work<T> {
    prep: @mut Prep,
    res: Option<Either<T,PortOne<(Exec,T)>>>
}

fn json_encode<T:Encodable<json::Encoder>>(t: &T) -> ~str {
    do io::with_str_writer |wr| {
        let mut encoder = json::Encoder(wr);
        t.encode(&mut encoder);
    }
}

// FIXME(#5121)
fn json_decode<T:Decodable<json::Decoder>>(s: &str) -> T {
    do io::with_str_reader(s) |rdr| {
        let j = result::unwrap(json::from_reader(rdr));
        let mut decoder = json::Decoder(j);
        Decodable::decode(&mut decoder)
    }
}

fn digest<T:Encodable<json::Encoder>>(t: &T) -> ~str {
    let mut sha = ~Sha1::new();
    (*sha).input_str(json_encode(t));
    (*sha).result_str()
}

fn digest_file(path: &Path) -> ~str {
    let mut sha = ~Sha1::new();
    let s = io::read_whole_file_str(path);
    (*sha).input_str(*s.get_ref());
    (*sha).result_str()
}

impl Context {
    pub fn new(db: @mut Database, lg: @mut Logger, cfg: @json::Object)
               -> Context {
        Context {
            db: db,
            logger: lg,
            cfg: cfg,
            freshness: TreeMap::new()
        }
    }

    pub fn prep<T:Send +
                  Encodable<json::Encoder> +
                  Decodable<json::Decoder>>(@self, // FIXME(#5121)
                                            fn_name:&str,
                                            blk: &fn(@mut Prep)->Work<T>)
                                            -> Work<T> {
        let p = @mut Prep {
            ctxt: self,
            fn_name: fn_name.to_owned(),
            declared_inputs: WorkMap::new()
        };
        blk(p)
    }
}

trait TPrep {
    fn declare_input(&mut self, kind:&str, name:&str, val:&str);
    fn is_fresh(&self, cat:&str, kind:&str, name:&str, val:&str) -> bool;
    fn all_fresh(&self, cat:&str, map:&WorkMap) -> bool;
    fn exec<T:Send +
              Encodable<json::Encoder> +
              Decodable<json::Decoder>>( // FIXME(#5121)
        &self, blk: ~fn(&Exec) -> T) -> Work<T>;
}

impl TPrep for Prep {
    fn declare_input(&mut self, kind:&str, name:&str, val:&str) {
        self.declared_inputs.insert(WorkKey::new(kind, name),
                                 val.to_owned());
    }

    fn is_fresh(&self, cat: &str, kind: &str,
                name: &str, val: &str) -> bool {
        let k = kind.to_owned();
        let f = self.ctxt.freshness.find(&k);
        let fresh = match f {
            None => fail!("missing freshness-function for '%s'", kind),
            Some(f) => (*f)(name, val)
        };
        let lg = self.ctxt.logger;
        if fresh {
            lg.info(fmt!("%s %s:%s is fresh",
                         cat, kind, name));
        } else {
            lg.info(fmt!("%s %s:%s is not fresh",
                         cat, kind, name))
        }
        fresh
    }

    fn all_fresh(&self, cat: &str, map: &WorkMap) -> bool {
        for map.iter().advance |(k, v)| {
            if ! self.is_fresh(cat, k.kind, k.name, *v) {
                return false;
            }
        }
        return true;
    }

    fn exec<T:Send +
              Encodable<json::Encoder> +
              Decodable<json::Decoder>>( // FIXME(#5121)
            &self, blk: ~fn(&Exec) -> T) -> Work<T> {
        let mut bo = Some(blk);

        let cached = self.ctxt.db.prepare(self.fn_name, &self.declared_inputs);

        match cached {
            Some((ref disc_in, ref disc_out, ref res))
            if self.all_fresh("declared input",
                              &self.declared_inputs) &&
            self.all_fresh("discovered input", disc_in) &&
            self.all_fresh("discovered output", disc_out) => {
                Work::new(@mut (*self).clone(), Left(json_decode(*res)))
            }

            _ => {
                let (port, chan) = oneshot();
                let blk = bo.take_unwrap();
                let chan = Cell::new(chan);

                do task::spawn {
                    let exe = Exec {
                        discovered_inputs: WorkMap::new(),
                        discovered_outputs: WorkMap::new(),
                    };
                    let chan = chan.take();
                    let v = blk(&exe);
                    send_one(chan, (exe, v));
                }
                Work::new(@mut (*self).clone(), Right(port))
            }
        }
    }
}

impl<T:Send +
       Encodable<json::Encoder> +
       Decodable<json::Decoder>> Work<T> { // FIXME(#5121)
    pub fn new(p: @mut Prep, e: Either<T,PortOne<(Exec,T)>>) -> Work<T> {
        Work { prep: p, res: Some(e) }
    }
}

// FIXME (#3724): movable self. This should be in impl Work.
fn unwrap<T:Send +
            Encodable<json::Encoder> +
            Decodable<json::Decoder>>( // FIXME(#5121)
        w: Work<T>) -> T {
    let mut ww = w;
    let s = ww.res.take();

    match s {
        None => fail!(),
        Some(Left(v)) => v,
        Some(Right(port)) => {
            let (exe, v) = recv_one(port);

            let s = json_encode(&v);

            let p = &*ww.prep;
            let db = p.ctxt.db;
            db.cache(p.fn_name,
                 &p.declared_inputs,
                 &exe.discovered_inputs,
                 &exe.discovered_outputs,
                 s);
            v
        }
    }
}

//#[test]
fn test() {
    use std::io::WriterUtil;

    let db = @mut Database { db_filename: Path("db.json"),
                             db_cache: TreeMap::new(),
                             db_dirty: false };
    let lg = @mut Logger { a: () };
    let cfg = @HashMap::new();
    let cx = @Context::new(db, lg, cfg);
    let w:Work<~str> = do cx.prep("test1") |prep| {
        let pth = Path("foo.c");
        {
            let file = io::file_writer(&pth, [io::Create]).unwrap();
            file.write_str("int main() { return 0; }");
        }

        prep.declare_input("file", pth.to_str(), digest_file(&pth));
        do prep.exec |_exe| {
            let out = Path("foo.o");
            run::process_status("gcc", [~"foo.c", ~"-o", out.to_str()]);
            out.to_str()
        }
    };
    let s = unwrap(w);
    io::println(s);
}
<commit_msg>extra: access workcache db via RWARC.<commit_after>// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#[allow(missing_doc)];

use digest::DigestUtil;
use json;
use sha1::Sha1;
use serialize::{Encoder, Encodable, Decoder, Decodable};
use arc::RWARC;
use treemap::TreeMap;

use std::cell::Cell;
use std::comm::{PortOne, oneshot, send_one, recv_one};
use std::either::{Either, Left, Right};
use std::hashmap::HashMap;
use std::io;
use std::result;
use std::run;
use std::task;

/**
*
* This is a loose clone of the [fbuild build system](https://github.com/felix-lang/fbuild),
* made a touch more generic (not wired to special cases on files) and much
* less metaprogram-y due to rust's comparative weakness there, relative to
* python.
*
* It's based around _imperative builds_ that happen to have some function
* calls cached. That is, it's _just_ a mechanism for describing cached
* functions. This makes it much simpler and smaller than a "build system"
* that produces an IR and evaluates it. The evaluation order is normal
* function calls. Some of them just return really quickly.
*
* A cached function consumes and produces a set of _works_. A work has a
* name, a kind (that determines how the value is to be checked for
* freshness) and a value. Works must also be (de)serializable. Some
* examples of works:
*
*    kind   name    value
*   ------------------------
*    cfg    os      linux
*    file   foo.c   <sha1>
*    url    foo.com <etag>
*
* Works are conceptually single units, but we store them most of the time
* in maps of the form (type,name) => value. These are WorkMaps.
*
* A cached function divides the works it's interested in into inputs and
* outputs, and subdivides those into declared (input) works and
* discovered (input and output) works.
*
* A _declared_ input or is one that is given to the workcache before
* any work actually happens, in the "prep" phase. Even when a function's
* work-doing part (the "exec" phase) never gets called, it has declared
* inputs, which can be checked for freshness (and potentially
* used to determine that the function can be skipped).
*
* The workcache checks _all_ works for freshness, but uses the set of
* discovered outputs from the _previous_ exec (which it will re-discover
* and re-record each time the exec phase runs).
*
* Therefore the discovered works cached in the db might be a
* mis-approximation of the current discoverable works, but this is ok for
* the following reason: we assume that if an artifact A changed from
* depending on B,C,D to depending on B,C,D,E, then A itself changed (as
* part of the change-in-dependencies), so we will be ok.
*
* Each function has a single discriminated output work called its _result_.
* This is only different from other works in that it is returned, by value,
* from a call to the cacheable function; the other output works are used in
* passing to invalidate dependencies elsewhere in the cache, but do not
* otherwise escape from a function invocation. Most functions only have one
* output work anyways.
*
* A database (the central store of a workcache) stores a mappings:
*
* (fn_name,{declared_input}) => ({discovered_input},
*                                {discovered_output},result)
*
* (Note: fbuild, which workcache is based on, has the concept of a declared
* output as separate from a discovered output. This distinction exists only
* as an artifact of how fbuild works: via annotations on function types
* and metaprogramming, with explicit dependency declaration as a fallback.
* Workcache is more explicit about dependencies, and as such treats all
* outputs the same, as discovered-during-the-last-run.)
*
*/

#[deriving(Clone, Eq, Encodable, Decodable, TotalOrd, TotalEq)]
struct WorkKey {
    kind: ~str,
    name: ~str
}

impl WorkKey {
    pub fn new(kind: &str, name: &str) -> WorkKey {
        WorkKey {
            kind: kind.to_owned(),
            name: name.to_owned(),
        }
    }
}

#[deriving(Clone, Eq, Encodable, Decodable)]
struct WorkMap(TreeMap<WorkKey, ~str>);

impl WorkMap {
    fn new() -> WorkMap { WorkMap(TreeMap::new()) }
}

struct Database {
    db_filename: Path,
    db_cache: TreeMap<~str, ~str>,
    db_dirty: bool
}

impl Database {
    pub fn prepare(&self,
                   fn_name: &str,
                   declared_inputs: &WorkMap)
                   -> Option<(WorkMap, WorkMap, ~str)> {
        let k = json_encode(&(fn_name, declared_inputs));
        match self.db_cache.find(&k) {
            None => None,
            Some(v) => Some(json_decode(*v))
        }
    }

    pub fn cache(&mut self,
                 fn_name: &str,
                 declared_inputs: &WorkMap,
                 discovered_inputs: &WorkMap,
                 discovered_outputs: &WorkMap,
                 result: &str) {
        let k = json_encode(&(fn_name, declared_inputs));
        let v = json_encode(&(discovered_inputs,
                              discovered_outputs,
                              result));
        self.db_cache.insert(k,v);
        self.db_dirty = true
    }
}

struct Logger {
    // FIXME #4432: Fill in
    a: ()
}

impl Logger {
    pub fn info(&self, i: &str) {
        io::println(~"workcache: " + i);
    }
}

struct Context {
    db: RWARC<Database>,
    logger: @mut Logger,
    cfg: @json::Object,
    freshness: TreeMap<~str,@fn(&str,&str)->bool>
}

#[deriving(Clone)]
struct Prep {
    ctxt: @Context,
    fn_name: ~str,
    declared_inputs: WorkMap,
}

struct Exec {
    discovered_inputs: WorkMap,
    discovered_outputs: WorkMap
}

struct Work<T> {
    prep: @mut Prep,
    res: Option<Either<T,PortOne<(Exec,T)>>>
}

fn json_encode<T:Encodable<json::Encoder>>(t: &T) -> ~str {
    do io::with_str_writer |wr| {
        let mut encoder = json::Encoder(wr);
        t.encode(&mut encoder);
    }
}

// FIXME(#5121)
fn json_decode<T:Decodable<json::Decoder>>(s: &str) -> T {
    do io::with_str_reader(s) |rdr| {
        let j = result::unwrap(json::from_reader(rdr));
        let mut decoder = json::Decoder(j);
        Decodable::decode(&mut decoder)
    }
}

fn digest<T:Encodable<json::Encoder>>(t: &T) -> ~str {
    let mut sha = ~Sha1::new();
    (*sha).input_str(json_encode(t));
    (*sha).result_str()
}

fn digest_file(path: &Path) -> ~str {
    let mut sha = ~Sha1::new();
    let s = io::read_whole_file_str(path);
    (*sha).input_str(*s.get_ref());
    (*sha).result_str()
}

impl Context {
    pub fn new(db: RWARC<Database>, lg: @mut Logger, cfg: @json::Object)
               -> Context {
        Context {
            db: db,
            logger: lg,
            cfg: cfg,
            freshness: TreeMap::new()
        }
    }

    pub fn prep<T:Send +
                  Encodable<json::Encoder> +
                  Decodable<json::Decoder>>(@self, // FIXME(#5121)
                                            fn_name:&str,
                                            blk: &fn(@mut Prep)->Work<T>)
                                            -> Work<T> {
        let p = @mut Prep {
            ctxt: self,
            fn_name: fn_name.to_owned(),
            declared_inputs: WorkMap::new()
        };
        blk(p)
    }
}

trait TPrep {
    fn declare_input(&mut self, kind:&str, name:&str, val:&str);
    fn is_fresh(&self, cat:&str, kind:&str, name:&str, val:&str) -> bool;
    fn all_fresh(&self, cat:&str, map:&WorkMap) -> bool;
    fn exec<T:Send +
              Encodable<json::Encoder> +
              Decodable<json::Decoder>>( // FIXME(#5121)
        &self, blk: ~fn(&Exec) -> T) -> Work<T>;
}

impl TPrep for Prep {
    fn declare_input(&mut self, kind:&str, name:&str, val:&str) {
        self.declared_inputs.insert(WorkKey::new(kind, name),
                                 val.to_owned());
    }

    fn is_fresh(&self, cat: &str, kind: &str,
                name: &str, val: &str) -> bool {
        let k = kind.to_owned();
        let f = self.ctxt.freshness.find(&k);
        let fresh = match f {
            None => fail!("missing freshness-function for '%s'", kind),
            Some(f) => (*f)(name, val)
        };
        let lg = self.ctxt.logger;
        if fresh {
            lg.info(fmt!("%s %s:%s is fresh",
                         cat, kind, name));
        } else {
            lg.info(fmt!("%s %s:%s is not fresh",
                         cat, kind, name))
        }
        fresh
    }

    fn all_fresh(&self, cat: &str, map: &WorkMap) -> bool {
        for map.iter().advance |(k, v)| {
            if ! self.is_fresh(cat, k.kind, k.name, *v) {
                return false;
            }
        }
        return true;
    }

    fn exec<T:Send +
              Encodable<json::Encoder> +
              Decodable<json::Decoder>>( // FIXME(#5121)
            &self, blk: ~fn(&Exec) -> T) -> Work<T> {
        let mut bo = Some(blk);

        let cached = do self.ctxt.db.read |db| {
            db.prepare(self.fn_name, &self.declared_inputs)
        };

        match cached {
            Some((ref disc_in, ref disc_out, ref res))
            if self.all_fresh("declared input",
                              &self.declared_inputs) &&
            self.all_fresh("discovered input", disc_in) &&
            self.all_fresh("discovered output", disc_out) => {
                Work::new(@mut (*self).clone(), Left(json_decode(*res)))
            }

            _ => {
                let (port, chan) = oneshot();
                let blk = bo.take_unwrap();
                let chan = Cell::new(chan);

                do task::spawn {
                    let exe = Exec {
                        discovered_inputs: WorkMap::new(),
                        discovered_outputs: WorkMap::new(),
                    };
                    let chan = chan.take();
                    let v = blk(&exe);
                    send_one(chan, (exe, v));
                }
                Work::new(@mut (*self).clone(), Right(port))
            }
        }
    }
}

impl<T:Send +
       Encodable<json::Encoder> +
       Decodable<json::Decoder>> Work<T> { // FIXME(#5121)
    pub fn new(p: @mut Prep, e: Either<T,PortOne<(Exec,T)>>) -> Work<T> {
        Work { prep: p, res: Some(e) }
    }
}

// FIXME (#3724): movable self. This should be in impl Work.
fn unwrap<T:Send +
            Encodable<json::Encoder> +
            Decodable<json::Decoder>>( // FIXME(#5121)
        w: Work<T>) -> T {
    let mut ww = w;
    let s = ww.res.take();

    match s {
        None => fail!(),
        Some(Left(v)) => v,
        Some(Right(port)) => {
            let (exe, v) = recv_one(port);

            let s = json_encode(&v);

            let p = &*ww.prep;
            do p.ctxt.db.write |db| {
                db.cache(p.fn_name,
                         &p.declared_inputs,
                         &exe.discovered_inputs,
                         &exe.discovered_outputs,
                         s);
            }
            v
        }
    }
}

//#[test]
fn test() {
    use std::io::WriterUtil;

    let db = RWARC(Database { db_filename: Path("db.json"),
                              db_cache: TreeMap::new(),
                              db_dirty: false });
    let lg = @mut Logger { a: () };
    let cfg = @HashMap::new();
    let cx = @Context::new(db, lg, cfg);
    let w:Work<~str> = do cx.prep("test1") |prep| {
        let pth = Path("foo.c");
        {
            let file = io::file_writer(&pth, [io::Create]).unwrap();
            file.write_str("int main() { return 0; }");
        }

        prep.declare_input("file", pth.to_str(), digest_file(&pth));
        do prep.exec |_exe| {
            let out = Path("foo.o");
            run::process_status("gcc", [~"foo.c", ~"-o", out.to_str()]);
            out.to_str()
        }
    };
    let s = unwrap(w);
    io::println(s);
}
<|endoftext|>


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

//! A wrapper around any Read to treat it as an RNG.

#![allow(dead_code)]

use io::prelude::*;
use rand::Rng;

/// An RNG that reads random bytes straight from a `Read`. This will
/// work best with an infinite reader, but this is not required.
///
/// # Panics
///
/// It will panic if it there is insufficient data to fulfill a request.
pub struct ReaderRng<R> {
    reader: R
}

impl<R: Read> ReaderRng<R> {
    /// Create a new `ReaderRng` from a `Read`.
    pub fn new(r: R) -> ReaderRng<R> {
        ReaderRng {
            reader: r
        }
    }
}

impl<R: Read> Rng for ReaderRng<R> {
    fn next_u32(&mut self) -> u32 {
        // This is designed for speed: reading a LE integer on a LE
        // platform just involves blitting the bytes into the memory
        // of the u32, similarly for BE on BE; avoiding byteswapping.
        let mut bytes = [0; 4];
        self.fill_bytes(&mut bytes);
        unsafe { *(bytes.as_ptr() as *const u32) }
    }
    fn next_u64(&mut self) -> u64 {
        // see above for explanation.
        let mut bytes = [0; 8];
        self.fill_bytes(&mut bytes);
        unsafe { *(bytes.as_ptr() as *const u64) }
    }
    fn fill_bytes(&mut self, mut v: &mut [u8]) {
        while !v.is_empty() {
            let t = v;
            match self.reader.read(t) {
                Ok(0) => panic!("ReaderRng.fill_bytes: EOF reached"),
                Ok(n) => v = t.split_at_mut(n).1,
                Err(e) => panic!("ReaderRng.fill_bytes: {}", e),
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use super::ReaderRng;
    use rand::Rng;

    #[test]
    fn test_reader_rng_u64() {
        // transmute from the target to avoid endianness concerns.
        let v = &[0, 0, 0, 0, 0, 0, 0, 1,
                  0, 0, 0, 0, 0, 0, 0, 2,
                  0, 0, 0, 0, 0, 0, 0, 3][..];
        let mut rng = ReaderRng::new(v);

        assert_eq!(rng.next_u64(), 1u64.to_be());
        assert_eq!(rng.next_u64(), 2u64.to_be());
        assert_eq!(rng.next_u64(), 3u64.to_be());
    }
    #[test]
    fn test_reader_rng_u32() {
        let v = &[0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3][..];
        let mut rng = ReaderRng::new(v);

        assert_eq!(rng.next_u32(), 1u32.to_be());
        assert_eq!(rng.next_u32(), 2u32.to_be());
        assert_eq!(rng.next_u32(), 3u32.to_be());
    }
    #[test]
    fn test_reader_rng_fill_bytes() {
        let v = [1, 2, 3, 4, 5, 6, 7, 8];
        let mut w = [0; 8];

        let mut rng = ReaderRng::new(&v[..]);
        rng.fill_bytes(&mut w);

        assert!(v == w);
    }

    #[test]
    #[should_panic]
    fn test_reader_rng_insufficient_bytes() {
        let mut rng = ReaderRng::new(&[][..]);
        let mut v = [0; 3];
        rng.fill_bytes(&mut v);
    }
}
<commit_msg>Remove leftover Rand stuff<commit_after><|endoftext|>


<commit_before><commit_msg>getting rid of sliding motion looks a lot better<commit_after><|endoftext|>


<commit_before><commit_msg>chore: implement BFS<commit_after><|endoftext|>


<commit_before><commit_msg>Regression test for rust-lang/rust#22323.<commit_after>// rust-lang/rust#22323: regression test demonstrating that NLL
// precisely tracks temporary destruction order.

// compile-pass

#![feature(nll)]

fn main() {
    let _s = construct().borrow().consume_borrowed();
}

fn construct() -> Value { Value }

pub struct Value;

impl Value {
    fn borrow<'a>(&'a self) -> Borrowed<'a> { unimplemented!() }
}

pub struct Borrowed<'a> {
    _inner: Guard<'a, Value>,
}

impl<'a> Borrowed<'a> {
    fn consume_borrowed(self) -> String { unimplemented!() }
}

pub struct Guard<'a, T: ?Sized + 'a> {
    _lock: &'a T,
}

impl<'a, T: ?Sized> Drop for Guard<'a, T> { fn drop(&mut self) {} }
<|endoftext|>


<commit_before><commit_msg>(doc) Documented the modifiers module.<commit_after><|endoftext|>


<commit_before><commit_msg>Fix the name of the temporary file for the unoptimised SPIR-V<commit_after><|endoftext|>


<commit_before><commit_msg>Add tests.<commit_after>extern crate simd;
extern crate simdty;

use simd::{Vector,Bitcast,Convert};
use simdty::*;

#[test]
fn bitcast() {
    let a = f32x4(1.0, 2.0, 3.0, 4.0);
    let b: i32x4 = a.bitcast();
    let c: u8x16 = b.bitcast();
    let d: f32x4 = c.bitcast();

    assert_eq!(a.0, d.0);
    assert_eq!(a.1, d.1);
    assert_eq!(a.2, d.2);
    assert_eq!(a.3, d.3);
}

#[test]
fn convert() {
    let a = f32x4(1.0, 2.0, 3.0, 4.0);
    let b: i32x4 = a.convert();
    let c: f32x4 = b.convert();

    assert_eq!(a.0, c.0);
    assert_eq!(a.1, c.1);
    assert_eq!(a.2, c.2);
    assert_eq!(a.3, c.3);

    let a = f32x8(1e9, 1.0, 2.0, 3.0, -1e9, -5.0, -100.0, 20.0);
    let b: i32x8 = a.convert();
    let c: f32x8 = b.convert();
    assert_eq!(a.0, c.0);
    assert_eq!(a.1, c.1);
    assert_eq!(a.2, c.2);
    assert_eq!(a.3, c.3);
    assert_eq!(a.4, c.4);
    assert_eq!(a.5, c.5);
    assert_eq!(a.6, c.6);
    assert_eq!(a.7, c.7);
}
<|endoftext|>


<commit_before><commit_msg>add checkbox component<commit_after>use Widget;
use CTX;
use Event;

#[deriving(Clone, Show)]
pub enum CheckboxEvent{
    Change(bool),//click event on mouse down
}

///a checkbox which can either be checked or not
#[deriving(Clone, Show)]
pub struct Checkbox{
    pub value: bool,
    pub width: f64,
    pub height: f64,
}

impl Checkbox{
    pub fn new(value: bool, width: f64, height: f64) -> Checkbox{
        Checkbox{
            value: value,
            width: width,
            height: height,
        }
    }
}

impl Widget<CheckboxEvent> for Checkbox{
    fn render(&mut self, ctx: &mut CTX<CheckboxEvent>) -> (f64, f64) {
        ctx.mouseover((self.width, self.height), |event, ctx|{
            match event{
                &Event::MouseButtonDown(_, _, _, _, _, _) => {
                    ctx.emit(CheckboxEvent::Change(!self.value));
                },
                _ => {}
            }
        });
        ctx.draw(|c|{
            c.set_source_rgb(0.55, 0.55, 0.55);
            c.rectangle(0.0, 0.0, self.width, self.height);
            if self.value{
                c.fill();
            }
            c.stroke();
        });
        (self.width, self.height)
    }
    fn size(&self) -> (f64, f64) {
        (self.width, self.height)
    }
}
<|endoftext|>


<commit_before><commit_msg>Added support for blocks. I'm on a roll! :D<commit_after><|endoftext|>


<commit_before><commit_msg>mini_max_sum<commit_after>//https://www.hackerrank.com/challenges/mini-max-sum

use std::io;
use std::io::prelude::*;

fn main() {
    let stdin = io::stdin();

    let values: Vec<i64> = stdin.lock()
        .lines()
        .next()
        .unwrap()
        .unwrap()
        .trim()
        .split(' ')
        //https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.map
        .map(|x| x.parse::<i64>().unwrap())
        .collect();
    let sum: i64 = values.iter().sum();
    let min = values.iter().min().unwrap();
    let max = values.iter().max().unwrap();

    println!("{} {}", sum - max, sum - min);
}<|endoftext|>


<commit_before><commit_msg>Allow dead_code in main.rs<commit_after><|endoftext|>


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

#![allow(non_camel_case_types)]

use std::cell::{RefCell, Cell};
use std::collections::HashMap;
use std::fmt::Debug;
use std::hash::Hash;
use std::iter::repeat;
use std::time::Duration;
use std::collections::hash_state::HashState;

use syntax::ast;
use syntax::visit;
use syntax::visit::Visitor;

// The name of the associated type for `Fn` return types
pub const FN_OUTPUT_NAME: &'static str = "Output";

// Useful type to use with `Result<>` indicate that an error has already
// been reported to the user, so no need to continue checking.
#[derive(Clone, Copy, Debug)]
pub struct ErrorReported;

pub fn time<T, U, F>(do_it: bool, what: &str, u: U, f: F) -> T where
    F: FnOnce(U) -> T,
{
    thread_local!(static DEPTH: Cell<uint> = Cell::new(0));
    if !do_it { return f(u); }

    let old = DEPTH.with(|slot| {
        let r = slot.get();
        slot.set(r + 1);
        r
    });

    let mut u = Some(u);
    let mut rv = None;
    let dur = {
        let ref mut rvp = rv;

        Duration::span(move || {
            *rvp = Some(f(u.take().unwrap()))
        })
    };
    let rv = rv.unwrap();

    println!("{}time: {}.{:03} \t{}", repeat("  ").take(old).collect::<String>(),
             dur.num_seconds(), dur.num_milliseconds() % 1000, what);
    DEPTH.with(|slot| slot.set(old));

    rv
}

pub fn indent<R, F>(op: F) -> R where
    R: Debug,
    F: FnOnce() -> R,
{
    // Use in conjunction with the log post-processor like `src/etc/indenter`
    // to make debug output more readable.
    debug!(">>");
    let r = op();
    debug!("<< (Result = {:?})", r);
    r
}

pub struct Indenter {
    _cannot_construct_outside_of_this_module: ()
}

impl Drop for Indenter {
    fn drop(&mut self) { debug!("<<"); }
}

pub fn indenter() -> Indenter {
    debug!(">>");
    Indenter { _cannot_construct_outside_of_this_module: () }
}

struct LoopQueryVisitor<P> where P: FnMut(&ast::Expr_) -> bool {
    p: P,
    flag: bool,
}

impl<'v, P> Visitor<'v> for LoopQueryVisitor<P> where P: FnMut(&ast::Expr_) -> bool {
    fn visit_expr(&mut self, e: &ast::Expr) {
        self.flag |= (self.p)(&e.node);
        match e.node {
          // Skip inner loops, since a break in the inner loop isn't a
          // break inside the outer loop
          ast::ExprLoop(..) | ast::ExprWhile(..) => {}
          _ => visit::walk_expr(self, e)
        }
    }
}

// Takes a predicate p, returns true iff p is true for any subexpressions
// of b -- skipping any inner loops (loop, while, loop_body)
pub fn loop_query<P>(b: &ast::Block, p: P) -> bool where P: FnMut(&ast::Expr_) -> bool {
    let mut v = LoopQueryVisitor {
        p: p,
        flag: false,
    };
    visit::walk_block(&mut v, b);
    return v.flag;
}

struct BlockQueryVisitor<P> where P: FnMut(&ast::Expr) -> bool {
    p: P,
    flag: bool,
}

impl<'v, P> Visitor<'v> for BlockQueryVisitor<P> where P: FnMut(&ast::Expr) -> bool {
    fn visit_expr(&mut self, e: &ast::Expr) {
        self.flag |= (self.p)(e);
        visit::walk_expr(self, e)
    }
}

// Takes a predicate p, returns true iff p is true for any subexpressions
// of b -- skipping any inner loops (loop, while, loop_body)
pub fn block_query<P>(b: &ast::Block, p: P) -> bool where P: FnMut(&ast::Expr) -> bool {
    let mut v = BlockQueryVisitor {
        p: p,
        flag: false,
    };
    visit::walk_block(&mut v, &*b);
    return v.flag;
}

/// K: Eq + Hash<S>, V, S, H: Hasher<S>
///
/// Determines whether there exists a path from `source` to `destination`.  The
/// graph is defined by the `edges_map`, which maps from a node `S` to a list of
/// its adjacent nodes `T`.
///
/// Efficiency note: This is implemented in an inefficient way because it is
/// typically invoked on very small graphs. If the graphs become larger, a more
/// efficient graph representation and algorithm would probably be advised.
pub fn can_reach<T, S>(edges_map: &HashMap<T, Vec<T>, S>, source: T,
                       destination: T) -> bool
    where S: HashState, T: Hash + Eq + Clone,
{
    if source == destination {
        return true;
    }

    // Do a little breadth-first-search here.  The `queue` list
    // doubles as a way to detect if we've seen a particular FR
    // before.  Note that we expect this graph to be an *extremely
    // shallow* tree.
    let mut queue = vec!(source);
    let mut i = 0;
    while i < queue.len() {
        match edges_map.get(&queue[i]) {
            Some(edges) => {
                for target in edges {
                    if *target == destination {
                        return true;
                    }

                    if !queue.iter().any(|x| x == target) {
                        queue.push((*target).clone());
                    }
                }
            }
            None => {}
        }
        i += 1;
    }
    return false;
}

/// Memoizes a one-argument closure using the given RefCell containing
/// a type implementing MutableMap to serve as a cache.
///
/// In the future the signature of this function is expected to be:
/// ```
/// pub fn memoized<T: Clone, U: Clone, M: MutableMap<T, U>>(
///    cache: &RefCell<M>,
///    f: &|T| -> U
/// ) -> impl |T| -> U {
/// ```
/// but currently it is not possible.
///
/// # Example
/// ```
/// struct Context {
///    cache: RefCell<HashMap<uint, uint>>
/// }
///
/// fn factorial(ctxt: &Context, n: uint) -> uint {
///     memoized(&ctxt.cache, n, |n| match n {
///         0 | 1 => n,
///         _ => factorial(ctxt, n - 2) + factorial(ctxt, n - 1)
///     })
/// }
/// ```
#[inline(always)]
pub fn memoized<T, U, S, F>(cache: &RefCell<HashMap<T, U, S>>, arg: T, f: F) -> U
    where T: Clone + Hash + Eq,
          U: Clone,
          S: HashState,
          F: FnOnce(T) -> U,
{
    let key = arg.clone();
    let result = cache.borrow().get(&key).map(|result| result.clone());
    match result {
        Some(result) => result,
        None => {
            let result = f(arg);
            cache.borrow_mut().insert(key, result.clone());
            result
        }
    }
}
<commit_msg>Fix another occurrence of #22243<commit_after>// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(non_camel_case_types)]

use std::cell::{RefCell, Cell};
use std::collections::HashMap;
use std::fmt::Debug;
use std::hash::Hash;
use std::iter::repeat;
use std::time::Duration;
use std::collections::hash_state::HashState;

use syntax::ast;
use syntax::visit;
use syntax::visit::Visitor;

// The name of the associated type for `Fn` return types
pub const FN_OUTPUT_NAME: &'static str = "Output";

// Useful type to use with `Result<>` indicate that an error has already
// been reported to the user, so no need to continue checking.
#[derive(Clone, Copy, Debug)]
pub struct ErrorReported;

pub fn time<T, U, F>(do_it: bool, what: &str, u: U, f: F) -> T where
    F: FnOnce(U) -> T,
{
    thread_local!(static DEPTH: Cell<uint> = Cell::new(0));
    if !do_it { return f(u); }

    let old = DEPTH.with(|slot| {
        let r = slot.get();
        slot.set(r + 1);
        r
    });

    let mut u = Some(u);
    let mut rv = None;
    let dur = {
        let ref mut rvp = rv;

        Duration::span(move || {
            *rvp = Some(f(u.take().unwrap()))
        })
    };
    let rv = rv.unwrap();

    println!("{}time: {}.{:03} \t{}", repeat("  ").take(old).collect::<String>(),
             dur.num_seconds(), dur.num_milliseconds() % 1000, what);
    DEPTH.with(|slot| slot.set(old));

    rv
}

pub fn indent<R, F>(op: F) -> R where
    R: Debug,
    F: FnOnce() -> R,
{
    // Use in conjunction with the log post-processor like `src/etc/indenter`
    // to make debug output more readable.
    debug!(">>");
    let r = op();
    debug!("<< (Result = {:?})", r);
    r
}

pub struct Indenter {
    _cannot_construct_outside_of_this_module: ()
}

impl Drop for Indenter {
    fn drop(&mut self) { debug!("<<"); }
}

pub fn indenter() -> Indenter {
    debug!(">>");
    Indenter { _cannot_construct_outside_of_this_module: () }
}

struct LoopQueryVisitor<P> where P: FnMut(&ast::Expr_) -> bool {
    p: P,
    flag: bool,
}

impl<'v, P> Visitor<'v> for LoopQueryVisitor<P> where P: FnMut(&ast::Expr_) -> bool {
    fn visit_expr(&mut self, e: &ast::Expr) {
        self.flag |= (self.p)(&e.node);
        match e.node {
          // Skip inner loops, since a break in the inner loop isn't a
          // break inside the outer loop
          ast::ExprLoop(..) | ast::ExprWhile(..) => {}
          _ => visit::walk_expr(self, e)
        }
    }
}

// Takes a predicate p, returns true iff p is true for any subexpressions
// of b -- skipping any inner loops (loop, while, loop_body)
pub fn loop_query<P>(b: &ast::Block, p: P) -> bool where P: FnMut(&ast::Expr_) -> bool {
    let mut v = LoopQueryVisitor {
        p: p,
        flag: false,
    };
    visit::walk_block(&mut v, b);
    return v.flag;
}

struct BlockQueryVisitor<P> where P: FnMut(&ast::Expr) -> bool {
    p: P,
    flag: bool,
}

impl<'v, P> Visitor<'v> for BlockQueryVisitor<P> where P: FnMut(&ast::Expr) -> bool {
    fn visit_expr(&mut self, e: &ast::Expr) {
        self.flag |= (self.p)(e);
        visit::walk_expr(self, e)
    }
}

// Takes a predicate p, returns true iff p is true for any subexpressions
// of b -- skipping any inner loops (loop, while, loop_body)
pub fn block_query<P>(b: &ast::Block, p: P) -> bool where P: FnMut(&ast::Expr) -> bool {
    let mut v = BlockQueryVisitor {
        p: p,
        flag: false,
    };
    visit::walk_block(&mut v, &*b);
    return v.flag;
}

/// K: Eq + Hash<S>, V, S, H: Hasher<S>
///
/// Determines whether there exists a path from `source` to `destination`.  The
/// graph is defined by the `edges_map`, which maps from a node `S` to a list of
/// its adjacent nodes `T`.
///
/// Efficiency note: This is implemented in an inefficient way because it is
/// typically invoked on very small graphs. If the graphs become larger, a more
/// efficient graph representation and algorithm would probably be advised.
pub fn can_reach<T, S>(edges_map: &HashMap<T, Vec<T>, S>, source: T,
                       destination: T) -> bool
    where S: HashState, T: Hash + Eq + Clone,
{
    if source == destination {
        return true;
    }

    // Do a little breadth-first-search here.  The `queue` list
    // doubles as a way to detect if we've seen a particular FR
    // before.  Note that we expect this graph to be an *extremely
    // shallow* tree.
    let mut queue = vec!(source);
    let mut i = 0;
    while i < queue.len() {
        match edges_map.get(&queue[i]) {
            Some(edges) => {
                for target in edges {
                    if *target == destination {
                        return true;
                    }

                    if !queue.iter().any(|x| x == target) {
                        queue.push((*target).clone());
                    }
                }
            }
            None => {}
        }
        i += 1;
    }
    return false;
}

/// Memoizes a one-argument closure using the given RefCell containing
/// a type implementing MutableMap to serve as a cache.
///
/// In the future the signature of this function is expected to be:
/// ```
/// pub fn memoized<T: Clone, U: Clone, M: MutableMap<T, U>>(
///    cache: &RefCell<M>,
///    f: &|T| -> U
/// ) -> impl |T| -> U {
/// ```
/// but currently it is not possible.
///
/// # Example
/// ```
/// struct Context {
///    cache: RefCell<HashMap<uint, uint>>
/// }
///
/// fn factorial(ctxt: &Context, n: uint) -> uint {
///     memoized(&ctxt.cache, n, |n| match n {
///         0 | 1 => n,
///         _ => factorial(ctxt, n - 2) + factorial(ctxt, n - 1)
///     })
/// }
/// ```
#[inline(always)]
pub fn memoized<T, U, S, F>(cache: &RefCell<HashMap<T, U, S>>, arg: T, f: F) -> U
    where T: Clone + Hash + Eq,
          U: Clone,
          S: HashState,
          F: FnOnce(T) -> U,
{
    let key = arg.clone();
    let result = cache.borrow().get(&key).cloned();
    match result {
        Some(result) => result,
        None => {
            let result = f(arg);
            cache.borrow_mut().insert(key, result.clone());
            result
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>event_driven example<commit_after>extern crate timely;

// use timely::dataflow::{InputHandle, ProbeHandle};
use timely::dataflow::operators::{Input, Map, Probe};

fn main() {
    // initializes and runs a timely dataflow.
    timely::execute_from_args(std::env::args(), |worker| {

        let timer = std::time::Instant::now();

        let mut args = std::env::args();
        args.next();

        let dataflows = args.next().unwrap().parse::<usize>().unwrap();
        let length = args.next().unwrap().parse::<usize>().unwrap();

        let mut inputs = Vec::new();
        let mut probes = Vec::new();

        // create a new input, exchange data, and inspect its output
        for _dataflow in 0 .. dataflows {
            worker.dataflow(|scope| {
                let (input, mut stream) = scope.new_input();
                for _step in 0 .. length {
                    stream = stream.map(|x: ()| x);
                }
                let probe = stream.probe();
                inputs.push(input);
                probes.push(probe);
            });
        }

        println!("{:?}\tdataflows built ({} x {})", timer.elapsed(), dataflows, length);

        for round in 0 .. {
            let dataflow = round % dataflows;
            inputs[dataflow].send(());
            inputs[dataflow].advance_to(round);
            let mut steps = 0;
            while probes[dataflow].less_than(&round) {
                worker.step();
                steps += 1;
            }
            println!("{:?}\tround {} complete in {} steps", timer.elapsed(), round, steps);
        }

    }).unwrap();
}
<|endoftext|>


<commit_before><commit_msg>Remove some unnecessary directives and fix up resultant warnings<commit_after><|endoftext|>


<commit_before><commit_msg>print bin<commit_after>extern crate graph_map;
use graph_map::GraphMMap;

fn main() {
    println!("usage: print <source>");

    let filename = std::env::args().skip(1).next().unwrap();
    let graph = GraphMMap::new(&filename);
    for node in 0 .. graph.nodes() {
        for &edge in graph.edges(node) {
            println!("{}\t{}", node, edge);
        }
    }
}<|endoftext|>


<commit_before><commit_msg>Remove dead read_binary_file()<commit_after><|endoftext|>


<commit_before><commit_msg>Remove unused imports<commit_after><|endoftext|>


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

use std::rc::Rc;

use attributes;
use arena::TypedArena;
use back::symbol_names;
use llvm::{ValueRef, get_params};
use rustc::hir::def_id::DefId;
use rustc::ty::subst::{Subst, Substs};
use rustc::traits::{self, Reveal};
use abi::FnType;
use base::*;
use build::*;
use callee::{Callee, Virtual, trans_fn_pointer_shim};
use closure;
use common::*;
use consts;
use debuginfo::DebugLoc;
use declare;
use glue;
use machine;
use type_::Type;
use type_of::*;
use value::Value;
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};

use syntax::ast::Name;
use syntax_pos::DUMMY_SP;

// drop_glue pointer, size, align.
const VTABLE_OFFSET: usize = 3;

/// Extracts a method from a trait object's vtable, at the specified index.
pub fn get_virtual_method<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                      llvtable: ValueRef,
                                      vtable_index: usize)
                                      -> ValueRef {
    // Load the data pointer from the object.
    debug!("get_virtual_method(vtable_index={}, llvtable={:?})",
           vtable_index, Value(llvtable));

    Load(bcx, GEPi(bcx, llvtable, &[vtable_index + VTABLE_OFFSET]))
}

/// Generate a shim function that allows an object type like `SomeTrait` to
/// implement the type `SomeTrait`. Imagine a trait definition:
///
///    trait SomeTrait { fn get(&self) -> i32; ... }
///
/// And a generic bit of code:
///
///    fn foo<T:SomeTrait>(t: &T) {
///        let x = SomeTrait::get;
///        x(t)
///    }
///
/// What is the value of `x` when `foo` is invoked with `T=SomeTrait`?
/// The answer is that it is a shim function generated by this routine:
///
///    fn shim(t: &SomeTrait) -> i32 {
///        // ... call t.get() virtually ...
///    }
///
/// In fact, all virtual calls can be thought of as normal trait calls
/// that go through this shim function.
pub fn trans_object_shim<'a, 'tcx>(ccx: &'a CrateContext<'a, 'tcx>,
                                   method_ty: Ty<'tcx>,
                                   vtable_index: usize)
                                   -> ValueRef {
    let _icx = push_ctxt("trans_object_shim");
    let tcx = ccx.tcx();

    debug!("trans_object_shim(vtable_index={}, method_ty={:?})",
           vtable_index,
           method_ty);

    let sig = tcx.erase_late_bound_regions(&method_ty.fn_sig());
    let sig = tcx.normalize_associated_type(&sig);
    let fn_ty = FnType::new(ccx, method_ty.fn_abi(), &sig, &[]);

    let function_name =
        symbol_names::internal_name_from_type_and_suffix(ccx, method_ty, "object_shim");
    let llfn = declare::define_internal_fn(ccx, &function_name, method_ty);
    attributes::set_frame_pointer_elimination(ccx, llfn);

    let (block_arena, fcx): (TypedArena<_>, FunctionContext);
    block_arena = TypedArena::new();
    fcx = FunctionContext::new(ccx, llfn, fn_ty, None, &block_arena);
    let mut bcx = fcx.init(false);

    let dest = fcx.llretslotptr.get();

    debug!("trans_object_shim: method_offset_in_vtable={}",
           vtable_index);

    let llargs = get_params(fcx.llfn);

    let callee = Callee {
        data: Virtual(vtable_index),
        ty: method_ty
    };
    bcx = callee.call(bcx, DebugLoc::None,
                      &llargs[fcx.fn_ty.ret.is_indirect() as usize..], dest).bcx;

    fcx.finish(bcx, DebugLoc::None);

    llfn
}

/// Creates a returns a dynamic vtable for the given type and vtable origin.
/// This is used only for objects.
///
/// The `trait_ref` encodes the erased self type. Hence if we are
/// making an object `Foo<Trait>` from a value of type `Foo<T>`, then
/// `trait_ref` would map `T:Trait`.
pub fn get_vtable<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                            trait_ref: ty::PolyTraitRef<'tcx>)
                            -> ValueRef
{
    let tcx = ccx.tcx();
    let _icx = push_ctxt("meth::get_vtable");

    debug!("get_vtable(trait_ref={:?})", trait_ref);

    // Check the cache.
    match ccx.vtables().borrow().get(&trait_ref) {
        Some(&val) => { return val }
        None => { }
    }

    // Not in the cache. Build it.
    let methods = traits::supertraits(tcx, trait_ref.clone()).flat_map(|trait_ref| {
        let vtable = fulfill_obligation(ccx.shared(), DUMMY_SP, trait_ref.clone());
        match vtable {
            // Should default trait error here?
            traits::VtableDefaultImpl(_) |
            traits::VtableBuiltin(_) => {
                Vec::new().into_iter()
            }
            traits::VtableImpl(
                traits::VtableImplData {
                    impl_def_id: id,
                    substs,
                    nested: _ }) => {
                let nullptr = C_null(Type::nil(ccx).ptr_to());
                get_vtable_methods(tcx, id, substs)
                    .into_iter()
                    .map(|opt_mth| opt_mth.map_or(nullptr, |mth| {
                        Callee::def(ccx, mth.method.def_id, &mth.substs).reify(ccx)
                    }))
                    .collect::<Vec<_>>()
                    .into_iter()
            }
            traits::VtableClosure(
                traits::VtableClosureData {
                    closure_def_id,
                    substs,
                    nested: _ }) => {
                let trait_closure_kind = tcx.lang_items.fn_trait_kind(trait_ref.def_id()).unwrap();
                let llfn = closure::trans_closure_method(ccx,
                                                         closure_def_id,
                                                         substs,
                                                         trait_closure_kind);
                vec![llfn].into_iter()
            }
            traits::VtableFnPointer(
                traits::VtableFnPointerData {
                    fn_ty: bare_fn_ty,
                    nested: _ }) => {
                let trait_closure_kind = tcx.lang_items.fn_trait_kind(trait_ref.def_id()).unwrap();
                vec![trans_fn_pointer_shim(ccx, trait_closure_kind, bare_fn_ty)].into_iter()
            }
            traits::VtableObject(ref data) => {
                // this would imply that the Self type being erased is
                // an object type; this cannot happen because we
                // cannot cast an unsized type into a trait object
                bug!("cannot get vtable for an object type: {:?}",
                     data);
            }
            traits::VtableParam(..) => {
                bug!("resolved vtable for {:?} to bad vtable {:?} in trans",
                     trait_ref,
                     vtable);
            }
        }
    });

    let size_ty = sizing_type_of(ccx, trait_ref.self_ty());
    let size = machine::llsize_of_alloc(ccx, size_ty);
    let align = align_of(ccx, trait_ref.self_ty());

    let components: Vec<_> = vec![
        // Generate a destructor for the vtable.
        glue::get_drop_glue(ccx, trait_ref.self_ty()),
        C_uint(ccx, size),
        C_uint(ccx, align)
    ].into_iter().chain(methods).collect();

    let vtable_const = C_struct(ccx, &components, false);
    let align = machine::llalign_of_pref(ccx, val_ty(vtable_const));
    let vtable = consts::addr_of(ccx, vtable_const, align, "vtable");

    ccx.vtables().borrow_mut().insert(trait_ref, vtable);
    vtable
}

pub fn get_vtable_methods<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                    impl_id: DefId,
                                    substs: &'tcx Substs<'tcx>)
                                    -> Vec<Option<ImplMethod<'tcx>>>
{
    debug!("get_vtable_methods(impl_id={:?}, substs={:?}", impl_id, substs);

    let trait_id = match tcx.impl_trait_ref(impl_id) {
        Some(t_id) => t_id.def_id,
        None       => bug!("make_impl_vtable: don't know how to \
                            make a vtable for a type impl!")
    };

    tcx.populate_implementations_for_trait_if_necessary(trait_id);

    let trait_item_def_ids = tcx.trait_item_def_ids(trait_id);
    trait_item_def_ids
        .iter()

        // Filter out non-method items.
        .filter_map(|item_def_id| {
            match *item_def_id {
                ty::MethodTraitItemId(def_id) => Some(def_id),
                _ => None,
            }
        })

        // Now produce pointers for each remaining method. If the
        // method could never be called from this object, just supply
        // null.
        .map(|trait_method_def_id| {
            debug!("get_vtable_methods: trait_method_def_id={:?}",
                   trait_method_def_id);

            let trait_method_type = match tcx.impl_or_trait_item(trait_method_def_id) {
                ty::MethodTraitItem(m) => m,
                _ => bug!("should be a method, not other assoc item"),
            };
            let name = trait_method_type.name;

            // Some methods cannot be called on an object; skip those.
            if !tcx.is_vtable_safe_method(trait_id, &trait_method_type) {
                debug!("get_vtable_methods: not vtable safe");
                return None;
            }

            debug!("get_vtable_methods: trait_method_type={:?}",
                   trait_method_type);

            // the method may have some early-bound lifetimes, add
            // regions for those
            let method_substs = Substs::for_item(tcx, trait_method_def_id,
                                                 |_, _| tcx.mk_region(ty::ReErased),
                                                 |_, _| tcx.types.err);

            // The substitutions we have are on the impl, so we grab
            // the method type from the impl to substitute into.
            let mth = get_impl_method(tcx, method_substs, impl_id, substs, name);

            debug!("get_vtable_methods: mth={:?}", mth);

            // If this is a default method, it's possible that it
            // relies on where clauses that do not hold for this
            // particular set of type parameters. Note that this
            // method could then never be called, so we do not want to
            // try and trans it, in that case. Issue #23435.
            if mth.is_provided {
                let predicates = mth.method.predicates.predicates.subst(tcx, &mth.substs);
                if !normalize_and_test_predicates(tcx, predicates) {
                    debug!("get_vtable_methods: predicates do not hold");
                    return None;
                }
            }

            Some(mth)
        })
        .collect()
}

#[derive(Debug)]
pub struct ImplMethod<'tcx> {
    pub method: Rc<ty::Method<'tcx>>,
    pub substs: &'tcx Substs<'tcx>,
    pub is_provided: bool
}

/// Locates the applicable definition of a method, given its name.
pub fn get_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                 substs: &'tcx Substs<'tcx>,
                                 impl_def_id: DefId,
                                 impl_substs: &'tcx Substs<'tcx>,
                                 name: Name)
                                 -> ImplMethod<'tcx>
{
    assert!(!substs.needs_infer());

    let trait_def_id = tcx.trait_id_of_impl(impl_def_id).unwrap();
    let trait_def = tcx.lookup_trait_def(trait_def_id);

    match trait_def.ancestors(impl_def_id).fn_defs(tcx, name).next() {
        Some(node_item) => {
            let substs = tcx.infer_ctxt(None, None, Reveal::All).enter(|infcx| {
                let substs = substs.rebase_onto(tcx, trait_def_id, impl_substs);
                let substs = traits::translate_substs(&infcx, impl_def_id,
                                                      substs, node_item.node);
                tcx.lift(&substs).unwrap_or_else(|| {
                    bug!("trans::meth::get_impl_method: translate_substs \
                          returned {:?} which contains inference types/regions",
                         substs);
                })
            });
            ImplMethod {
                method: node_item.item,
                substs: substs,
                is_provided: node_item.node.is_from_trait(),
            }
        }
        None => {
            bug!("method {:?} not found in {:?}", name, impl_def_id)
        }
    }
}
<commit_msg>Rollup merge of #36346 - oli-obk:patch-1, r=arielb1<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::rc::Rc;

use attributes;
use arena::TypedArena;
use back::symbol_names;
use llvm::{ValueRef, get_params};
use rustc::hir::def_id::DefId;
use rustc::ty::subst::{Subst, Substs};
use rustc::traits::{self, Reveal};
use abi::FnType;
use base::*;
use build::*;
use callee::{Callee, Virtual, trans_fn_pointer_shim};
use closure;
use common::*;
use consts;
use debuginfo::DebugLoc;
use declare;
use glue;
use machine;
use type_::Type;
use type_of::*;
use value::Value;
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};

use syntax::ast::Name;
use syntax_pos::DUMMY_SP;

// drop_glue pointer, size, align.
const VTABLE_OFFSET: usize = 3;

/// Extracts a method from a trait object's vtable, at the specified index.
pub fn get_virtual_method<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                      llvtable: ValueRef,
                                      vtable_index: usize)
                                      -> ValueRef {
    // Load the data pointer from the object.
    debug!("get_virtual_method(vtable_index={}, llvtable={:?})",
           vtable_index, Value(llvtable));

    Load(bcx, GEPi(bcx, llvtable, &[vtable_index + VTABLE_OFFSET]))
}

/// Generate a shim function that allows an object type like `SomeTrait` to
/// implement the type `SomeTrait`. Imagine a trait definition:
///
///    trait SomeTrait { fn get(&self) -> i32; ... }
///
/// And a generic bit of code:
///
///    fn foo<T:SomeTrait>(t: &T) {
///        let x = SomeTrait::get;
///        x(t)
///    }
///
/// What is the value of `x` when `foo` is invoked with `T=SomeTrait`?
/// The answer is that it is a shim function generated by this routine:
///
///    fn shim(t: &SomeTrait) -> i32 {
///        // ... call t.get() virtually ...
///    }
///
/// In fact, all virtual calls can be thought of as normal trait calls
/// that go through this shim function.
pub fn trans_object_shim<'a, 'tcx>(ccx: &'a CrateContext<'a, 'tcx>,
                                   method_ty: Ty<'tcx>,
                                   vtable_index: usize)
                                   -> ValueRef {
    let _icx = push_ctxt("trans_object_shim");
    let tcx = ccx.tcx();

    debug!("trans_object_shim(vtable_index={}, method_ty={:?})",
           vtable_index,
           method_ty);

    let sig = tcx.erase_late_bound_regions(&method_ty.fn_sig());
    let sig = tcx.normalize_associated_type(&sig);
    let fn_ty = FnType::new(ccx, method_ty.fn_abi(), &sig, &[]);

    let function_name =
        symbol_names::internal_name_from_type_and_suffix(ccx, method_ty, "object_shim");
    let llfn = declare::define_internal_fn(ccx, &function_name, method_ty);
    attributes::set_frame_pointer_elimination(ccx, llfn);

    let (block_arena, fcx): (TypedArena<_>, FunctionContext);
    block_arena = TypedArena::new();
    fcx = FunctionContext::new(ccx, llfn, fn_ty, None, &block_arena);
    let mut bcx = fcx.init(false);

    let dest = fcx.llretslotptr.get();

    debug!("trans_object_shim: method_offset_in_vtable={}",
           vtable_index);

    let llargs = get_params(fcx.llfn);

    let callee = Callee {
        data: Virtual(vtable_index),
        ty: method_ty
    };
    bcx = callee.call(bcx, DebugLoc::None,
                      &llargs[fcx.fn_ty.ret.is_indirect() as usize..], dest).bcx;

    fcx.finish(bcx, DebugLoc::None);

    llfn
}

/// Creates a dynamic vtable for the given type and vtable origin.
/// This is used only for objects.
///
/// The vtables are cached instead of created on every call.
///
/// The `trait_ref` encodes the erased self type. Hence if we are
/// making an object `Foo<Trait>` from a value of type `Foo<T>`, then
/// `trait_ref` would map `T:Trait`.
pub fn get_vtable<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                            trait_ref: ty::PolyTraitRef<'tcx>)
                            -> ValueRef
{
    let tcx = ccx.tcx();
    let _icx = push_ctxt("meth::get_vtable");

    debug!("get_vtable(trait_ref={:?})", trait_ref);

    // Check the cache.
    match ccx.vtables().borrow().get(&trait_ref) {
        Some(&val) => { return val }
        None => { }
    }

    // Not in the cache. Build it.
    let methods = traits::supertraits(tcx, trait_ref.clone()).flat_map(|trait_ref| {
        let vtable = fulfill_obligation(ccx.shared(), DUMMY_SP, trait_ref.clone());
        match vtable {
            // Should default trait error here?
            traits::VtableDefaultImpl(_) |
            traits::VtableBuiltin(_) => {
                Vec::new().into_iter()
            }
            traits::VtableImpl(
                traits::VtableImplData {
                    impl_def_id: id,
                    substs,
                    nested: _ }) => {
                let nullptr = C_null(Type::nil(ccx).ptr_to());
                get_vtable_methods(tcx, id, substs)
                    .into_iter()
                    .map(|opt_mth| opt_mth.map_or(nullptr, |mth| {
                        Callee::def(ccx, mth.method.def_id, &mth.substs).reify(ccx)
                    }))
                    .collect::<Vec<_>>()
                    .into_iter()
            }
            traits::VtableClosure(
                traits::VtableClosureData {
                    closure_def_id,
                    substs,
                    nested: _ }) => {
                let trait_closure_kind = tcx.lang_items.fn_trait_kind(trait_ref.def_id()).unwrap();
                let llfn = closure::trans_closure_method(ccx,
                                                         closure_def_id,
                                                         substs,
                                                         trait_closure_kind);
                vec![llfn].into_iter()
            }
            traits::VtableFnPointer(
                traits::VtableFnPointerData {
                    fn_ty: bare_fn_ty,
                    nested: _ }) => {
                let trait_closure_kind = tcx.lang_items.fn_trait_kind(trait_ref.def_id()).unwrap();
                vec![trans_fn_pointer_shim(ccx, trait_closure_kind, bare_fn_ty)].into_iter()
            }
            traits::VtableObject(ref data) => {
                // this would imply that the Self type being erased is
                // an object type; this cannot happen because we
                // cannot cast an unsized type into a trait object
                bug!("cannot get vtable for an object type: {:?}",
                     data);
            }
            traits::VtableParam(..) => {
                bug!("resolved vtable for {:?} to bad vtable {:?} in trans",
                     trait_ref,
                     vtable);
            }
        }
    });

    let size_ty = sizing_type_of(ccx, trait_ref.self_ty());
    let size = machine::llsize_of_alloc(ccx, size_ty);
    let align = align_of(ccx, trait_ref.self_ty());

    let components: Vec<_> = vec![
        // Generate a destructor for the vtable.
        glue::get_drop_glue(ccx, trait_ref.self_ty()),
        C_uint(ccx, size),
        C_uint(ccx, align)
    ].into_iter().chain(methods).collect();

    let vtable_const = C_struct(ccx, &components, false);
    let align = machine::llalign_of_pref(ccx, val_ty(vtable_const));
    let vtable = consts::addr_of(ccx, vtable_const, align, "vtable");

    ccx.vtables().borrow_mut().insert(trait_ref, vtable);
    vtable
}

pub fn get_vtable_methods<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                    impl_id: DefId,
                                    substs: &'tcx Substs<'tcx>)
                                    -> Vec<Option<ImplMethod<'tcx>>>
{
    debug!("get_vtable_methods(impl_id={:?}, substs={:?}", impl_id, substs);

    let trait_id = match tcx.impl_trait_ref(impl_id) {
        Some(t_id) => t_id.def_id,
        None       => bug!("make_impl_vtable: don't know how to \
                            make a vtable for a type impl!")
    };

    tcx.populate_implementations_for_trait_if_necessary(trait_id);

    let trait_item_def_ids = tcx.trait_item_def_ids(trait_id);
    trait_item_def_ids
        .iter()

        // Filter out non-method items.
        .filter_map(|item_def_id| {
            match *item_def_id {
                ty::MethodTraitItemId(def_id) => Some(def_id),
                _ => None,
            }
        })

        // Now produce pointers for each remaining method. If the
        // method could never be called from this object, just supply
        // null.
        .map(|trait_method_def_id| {
            debug!("get_vtable_methods: trait_method_def_id={:?}",
                   trait_method_def_id);

            let trait_method_type = match tcx.impl_or_trait_item(trait_method_def_id) {
                ty::MethodTraitItem(m) => m,
                _ => bug!("should be a method, not other assoc item"),
            };
            let name = trait_method_type.name;

            // Some methods cannot be called on an object; skip those.
            if !tcx.is_vtable_safe_method(trait_id, &trait_method_type) {
                debug!("get_vtable_methods: not vtable safe");
                return None;
            }

            debug!("get_vtable_methods: trait_method_type={:?}",
                   trait_method_type);

            // the method may have some early-bound lifetimes, add
            // regions for those
            let method_substs = Substs::for_item(tcx, trait_method_def_id,
                                                 |_, _| tcx.mk_region(ty::ReErased),
                                                 |_, _| tcx.types.err);

            // The substitutions we have are on the impl, so we grab
            // the method type from the impl to substitute into.
            let mth = get_impl_method(tcx, method_substs, impl_id, substs, name);

            debug!("get_vtable_methods: mth={:?}", mth);

            // If this is a default method, it's possible that it
            // relies on where clauses that do not hold for this
            // particular set of type parameters. Note that this
            // method could then never be called, so we do not want to
            // try and trans it, in that case. Issue #23435.
            if mth.is_provided {
                let predicates = mth.method.predicates.predicates.subst(tcx, &mth.substs);
                if !normalize_and_test_predicates(tcx, predicates) {
                    debug!("get_vtable_methods: predicates do not hold");
                    return None;
                }
            }

            Some(mth)
        })
        .collect()
}

#[derive(Debug)]
pub struct ImplMethod<'tcx> {
    pub method: Rc<ty::Method<'tcx>>,
    pub substs: &'tcx Substs<'tcx>,
    pub is_provided: bool
}

/// Locates the applicable definition of a method, given its name.
pub fn get_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                 substs: &'tcx Substs<'tcx>,
                                 impl_def_id: DefId,
                                 impl_substs: &'tcx Substs<'tcx>,
                                 name: Name)
                                 -> ImplMethod<'tcx>
{
    assert!(!substs.needs_infer());

    let trait_def_id = tcx.trait_id_of_impl(impl_def_id).unwrap();
    let trait_def = tcx.lookup_trait_def(trait_def_id);

    match trait_def.ancestors(impl_def_id).fn_defs(tcx, name).next() {
        Some(node_item) => {
            let substs = tcx.infer_ctxt(None, None, Reveal::All).enter(|infcx| {
                let substs = substs.rebase_onto(tcx, trait_def_id, impl_substs);
                let substs = traits::translate_substs(&infcx, impl_def_id,
                                                      substs, node_item.node);
                tcx.lift(&substs).unwrap_or_else(|| {
                    bug!("trans::meth::get_impl_method: translate_substs \
                          returned {:?} which contains inference types/regions",
                         substs);
                })
            });
            ImplMethod {
                method: node_item.item,
                substs: substs,
                is_provided: node_item.node.is_from_trait(),
            }
        }
        None => {
            bug!("method {:?} not found in {:?}", name, impl_def_id)
        }
    }
}
<|endoftext|>


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

//! Haiku-specific raw type definitions

#![stable(feature = "raw_ext", since = "1.1.0")]

#![allow(deprecated)]

use os::raw::{c_long};
use os::unix::raw::{uid_t, gid_t};

// Use the direct definition of usize, instead of uintptr_t like in libc
#[unstable(feature = "pthread_t", issue = "29791")] pub type pthread_t = usize;

#[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = i64;
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = i32;
#[stable(feature = "raw_ext", since = "1.1.0")] pub type dev_t = i32;
#[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = i64;
#[stable(feature = "raw_ext", since = "1.1.0")] pub type mode_t = u32;
#[stable(feature = "raw_ext", since = "1.1.0")] pub type nlink_t = i32;
#[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = i64;
#[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i32;

#[repr(C)]
#[derive(Clone)]
#[stable(feature = "raw_ext", since = "1.1.0")]
pub struct stat {
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_dev: dev_t,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_ino: ino_t,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_mode: mode_t,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_nlink: nlink_t,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_uid: uid_t,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_gid: gid_t,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_size: off_t,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_rdev: dev_t,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_blksize: blksize_t,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_atime: time_t,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_atime_nsec: c_long,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_mtime: time_t,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_mtime_nsec: c_long,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_ctime: time_t,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_ctime_nsec: c_long,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_crtime: time_t,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_crtime_nsec: c_long,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_type: u32,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_blocks: blkcnt_t,
}
<commit_msg>Haiku: Fix pthread_t typesize set to stable 1.8.0 post #29791<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Haiku-specific raw type definitions

#![stable(feature = "raw_ext", since = "1.1.0")]

#![allow(deprecated)]

use os::raw::{c_long};
use os::unix::raw::{uid_t, gid_t};

// Use the direct definition of usize, instead of uintptr_t like in libc
#[stable(feature = "pthread_t", since = "1.8.0")] pub type pthread_t = usize;

#[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = i64;
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = i32;
#[stable(feature = "raw_ext", since = "1.1.0")] pub type dev_t = i32;
#[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = i64;
#[stable(feature = "raw_ext", since = "1.1.0")] pub type mode_t = u32;
#[stable(feature = "raw_ext", since = "1.1.0")] pub type nlink_t = i32;
#[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = i64;
#[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i32;

#[repr(C)]
#[derive(Clone)]
#[stable(feature = "raw_ext", since = "1.1.0")]
pub struct stat {
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_dev: dev_t,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_ino: ino_t,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_mode: mode_t,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_nlink: nlink_t,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_uid: uid_t,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_gid: gid_t,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_size: off_t,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_rdev: dev_t,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_blksize: blksize_t,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_atime: time_t,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_atime_nsec: c_long,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_mtime: time_t,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_mtime_nsec: c_long,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_ctime: time_t,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_ctime_nsec: c_long,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_crtime: time_t,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_crtime_nsec: c_long,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_type: u32,
    #[stable(feature = "raw_ext", since = "1.1.0")]
    pub st_blocks: blkcnt_t,
}
<|endoftext|>


<commit_before><commit_msg>refactor: consolidate usages of mem::zeroed()<commit_after><|endoftext|>