<commit_before>use std::io::Cursor;
use std::io::prelude::*;
use std::net::TcpStream;
use byteorder::{BigEndian, WriteBytesExt, ReadBytesExt};

const RECV_BUF_SIZE: usize = 8192;
const GQTP_HEADER_SIZE: usize = 24;

#[derive(Debug)]
pub enum GQTPError {
    InvalidProtocol,
    InvalidBodySize,
    StatusError(u16),
}

/// Request [GQTP protocol](http://groonga.org/docs/spec/gqtp.html) over TcpStream
pub struct GQTPRequest<'a> {
    addr: &'a str,
}

impl<'a> Default for GQTPRequest<'a> {
    fn default() -> GQTPRequest<'a> {
        GQTPRequest { addr: "127.0.0.1:10043" }
    }
}

impl<'a> GQTPRequest<'a> {
    /// Create a GQTP client.
    pub fn new() -> GQTPRequest<'a> {
        GQTPRequest::default()
    }

    /// Set host address for GQTP server.
    ///
    /// # Examples
    ///
    /// ```
    /// extern crate ruroonga_client as groonga;
    ///
    /// groonga::GQTPRequest::new().with_addr("127.0.0.1:20043");
    /// ```
    pub fn with_addr(mut self, addr: &'a str) -> GQTPRequest<'a> {
        self.addr = addr;
        self
    }

    /// Send request and Receive response.
    pub fn call<C>(&self, command: C) -> Result<String, GQTPError>
        where C: AsRef<str>
    {
        // send
        let mut stream = TcpStream::connect(self.addr).unwrap();
        let mut send_buf = vec![];
        send_buf.write_u8(0xc7).unwrap();
        send_buf.write_u8(0).unwrap();
        send_buf.write_i16::<BigEndian>(0).unwrap();
        send_buf.write_u8(0).unwrap();
        send_buf.write_u8(0x02).unwrap();   // flags
        send_buf.write_u16::<BigEndian>(0).unwrap();
        send_buf.write_u32::<BigEndian>(command.as_ref().len() as u32).unwrap();
        send_buf.write_u32::<BigEndian>(0).unwrap();
        send_buf.write_u64::<BigEndian>(0).unwrap();
        send_buf.extend_from_slice(command.as_ref().as_bytes());
        let _ = stream.write_all(send_buf.as_slice());

        // receive and check protocol header value
        let mut read_buf = vec![0; RECV_BUF_SIZE];
        let _ = stream.read(&mut read_buf);
        let mut buf = Cursor::new(read_buf);

        let protocol = buf.read_u8().unwrap();
        let query_type = buf.read_u8().unwrap();
        if protocol != 0xc7 || query_type > 5 {
            return Err(GQTPError::InvalidProtocol);
        }
        let _ = buf.read_i16::<BigEndian>().unwrap();
        let _ = buf.read_u8().unwrap();

        let flags = buf.read_u8().unwrap();
        if !((flags & 0x01) == 0x01 || (flags & 0x02) == 0x02) {
            return Err(GQTPError::InvalidProtocol);
        }

        let status = buf.read_u16::<BigEndian>().unwrap();
        if status != 0 && status != 1 {
            return Err(GQTPError::StatusError(status));
        }
        let size = buf.read_i32::<BigEndian>().unwrap();
        let _ = buf.read_i32::<BigEndian>().unwrap();    // opaque
        let _ = buf.read_i64::<BigEndian>().unwrap();    // cas

        // read body
        let mut msg_buf_len = if (size as usize + GQTP_HEADER_SIZE) > RECV_BUF_SIZE {
            RECV_BUF_SIZE - GQTP_HEADER_SIZE
        } else {
            size as usize
        };
        let mut msg = vec![0; msg_buf_len];
        let _ = buf.read(&mut msg).unwrap();
        if (size as usize + GQTP_HEADER_SIZE) > RECV_BUF_SIZE {
            loop {
                let mut read_buf = vec![0; RECV_BUF_SIZE];
                let rsize = stream.read(&mut read_buf).unwrap();
                msg.extend_from_slice(read_buf.as_ref());
                msg_buf_len += rsize;
                if msg_buf_len >= size as usize {
                    break;
                }
            }
        }

        Ok(String::from_utf8(msg).unwrap())
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn smoke_gqtp() {
        let req = GQTPRequest::new();
        assert_eq!("127.0.0.1:10043", req.addr)
    }

    #[test]
    fn smoke_gqtp_with_addr() {
        let req = GQTPRequest::new().with_addr("127.0.0.1:20043");
        assert_eq!("127.0.0.1:20043", req.addr)
    }
}
<commit_msg>gqtp_request: Use try! for write error hanlding<commit_after>use std::io;
use std::io::Cursor;
use std::io::prelude::*;
use std::net::TcpStream;
use byteorder::{BigEndian, WriteBytesExt, ReadBytesExt};

const RECV_BUF_SIZE: usize = 8192;
const GQTP_HEADER_SIZE: usize = 24;

#[derive(Debug)]
pub enum GQTPError {
    InvalidProtocol,
    InvalidBodySize,
    StatusError(u16),
    IO(io::Error)
}

impl From<io::Error> for GQTPError {
    fn from(err: io::Error) -> GQTPError {
        GQTPError::IO(err)
    }
}

/// Request [GQTP protocol](http://groonga.org/docs/spec/gqtp.html) over TcpStream
pub struct GQTPRequest<'a> {
    addr: &'a str,
}

impl<'a> Default for GQTPRequest<'a> {
    fn default() -> GQTPRequest<'a> {
        GQTPRequest { addr: "127.0.0.1:10043" }
    }
}

impl<'a> GQTPRequest<'a> {
    /// Create a GQTP client.
    pub fn new() -> GQTPRequest<'a> {
        GQTPRequest::default()
    }

    /// Set host address for GQTP server.
    ///
    /// # Examples
    ///
    /// ```
    /// extern crate ruroonga_client as groonga;
    ///
    /// groonga::GQTPRequest::new().with_addr("127.0.0.1:20043");
    /// ```
    pub fn with_addr(mut self, addr: &'a str) -> GQTPRequest<'a> {
        self.addr = addr;
        self
    }

    /// Send request and Receive response.
    pub fn call<C>(&self, command: C) -> Result<String, GQTPError>
        where C: AsRef<str>
    {
        // send
        let mut stream = TcpStream::connect(self.addr).unwrap();
        let mut send_buf = vec![];
        try!(send_buf.write_u8(0xc7));
        try!(send_buf.write_u8(0));
        try!(send_buf.write_i16::<BigEndian>(0));
        try!(send_buf.write_u8(0));
        try!(send_buf.write_u8(0x02));   // flags
        try!(send_buf.write_u16::<BigEndian>(0));
        try!(send_buf.write_u32::<BigEndian>(command.as_ref().len() as u32));
        try!(send_buf.write_u32::<BigEndian>(0));
        try!(send_buf.write_u64::<BigEndian>(0));
        send_buf.extend_from_slice(command.as_ref().as_bytes());
        let _ = stream.write_all(send_buf.as_slice());

        // receive and check protocol header value
        let mut read_buf = vec![0; RECV_BUF_SIZE];
        let _ = stream.read(&mut read_buf);
        let mut buf = Cursor::new(read_buf);

        let protocol = buf.read_u8().unwrap();
        let query_type = buf.read_u8().unwrap();
        if protocol != 0xc7 || query_type > 5 {
            return Err(GQTPError::InvalidProtocol);
        }
        let _ = buf.read_i16::<BigEndian>().unwrap();
        let _ = buf.read_u8().unwrap();

        let flags = buf.read_u8().unwrap();
        if !((flags & 0x01) == 0x01 || (flags & 0x02) == 0x02) {
            return Err(GQTPError::InvalidProtocol);
        }

        let status = buf.read_u16::<BigEndian>().unwrap();
        if status != 0 && status != 1 {
            return Err(GQTPError::StatusError(status));
        }
        let size = buf.read_i32::<BigEndian>().unwrap();
        let _ = buf.read_i32::<BigEndian>().unwrap();    // opaque
        let _ = buf.read_i64::<BigEndian>().unwrap();    // cas

        // read body
        let mut msg_buf_len = if (size as usize + GQTP_HEADER_SIZE) > RECV_BUF_SIZE {
            RECV_BUF_SIZE - GQTP_HEADER_SIZE
        } else {
            size as usize
        };
        let mut msg = vec![0; msg_buf_len];
        let _ = buf.read(&mut msg).unwrap();
        if (size as usize + GQTP_HEADER_SIZE) > RECV_BUF_SIZE {
            loop {
                let mut read_buf = vec![0; RECV_BUF_SIZE];
                let rsize = stream.read(&mut read_buf).unwrap();
                msg.extend_from_slice(read_buf.as_ref());
                msg_buf_len += rsize;
                if msg_buf_len >= size as usize {
                    break;
                }
            }
        }

        Ok(String::from_utf8(msg).unwrap())
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn smoke_gqtp() {
        let req = GQTPRequest::new();
        assert_eq!("127.0.0.1:10043", req.addr)
    }

    #[test]
    fn smoke_gqtp_with_addr() {
        let req = GQTPRequest::new().with_addr("127.0.0.1:20043");
        assert_eq!("127.0.0.1:20043", req.addr)
    }
}
<|endoftext|>


<commit_before>use std::io;

use byteorder::{ReadBytesExt, LittleEndian};

const EXT4_BLOCK_GROUP_INODES_UNUSED: u16 = 0b1;
const EXT4_BLOCK_GROUP_BLOCKS_UNUSED: u16 = 0b10;

#[derive(Debug)]
struct Entry {
    inode_table_block: u64,
    inodes: u32,
}

#[derive(Debug)]
pub struct BlockGroups{
    groups: Vec<Entry>,
    inodes_per_group: u32,
    pub block_size: u32,
    pub inode_size: u16,
}

impl BlockGroups {
    pub fn new<R>(
        mut inner: R,
        blocks_count: u64,
        s_desc_size: u16,
        s_inodes_per_group: u32,
        block_size: u32,
        inode_size: u16) -> io::Result<BlockGroups>
    where R: io::Read + io::Seek {
        let blocks_count = ::usize_check(blocks_count)?;

        let mut groups = Vec::with_capacity(blocks_count);

        for block in 0..blocks_count {
//            let bg_block_bitmap_lo =
                inner.read_u32::<LittleEndian>()?; /* Blocks bitmap block */
//            let bg_inode_bitmap_lo =
                inner.read_u32::<LittleEndian>()?; /* Inodes bitmap block */
            let bg_inode_table_lo =
                inner.read_u32::<LittleEndian>()?; /* Inodes table block */
//            let bg_free_blocks_count_lo =
                inner.read_u16::<LittleEndian>()?; /* Free blocks count */
            let bg_free_inodes_count_lo =
                inner.read_u16::<LittleEndian>()?; /* Free inodes count */
//            let bg_used_dirs_count_lo =
                inner.read_u16::<LittleEndian>()?; /* Directories count */
            let bg_flags =
                inner.read_u16::<LittleEndian>()?; /* EXT4_BG_flags (INODE_UNINIT, etc) */
//            let bg_exclude_bitmap_lo =
                inner.read_u32::<LittleEndian>()?; /* Exclude bitmap for snapshots */
//            let bg_block_bitmap_csum_lo =
                inner.read_u16::<LittleEndian>()?; /* crc32c(s_uuid+grp_num+bbitmap) LE */
//            let bg_inode_bitmap_csum_lo =
                inner.read_u16::<LittleEndian>()?; /* crc32c(s_uuid+grp_num+ibitmap) LE */
//            let bg_itable_unused_lo =
                inner.read_u16::<LittleEndian>()?; /* Unused inodes count */
//            let bg_checksum =
                inner.read_u16::<LittleEndian>()?; /* crc16(sb_uuid+group+desc) */

//            let bg_block_bitmap_hi =
                if s_desc_size < 4 { None } else {
                    Some(inner.read_u32::<LittleEndian>()?) /* Blocks bitmap block MSB */
                };
//            let bg_inode_bitmap_hi =
                if s_desc_size < 4 + 4 { None } else {
                    Some(inner.read_u32::<LittleEndian>()?) /* Inodes bitmap block MSB */
                };
            let bg_inode_table_hi =
                if s_desc_size < 4 + 4 + 4 { None } else {
                    Some(inner.read_u32::<LittleEndian>()?) /* Inodes table block MSB */
                };
//            let bg_free_blocks_count_hi =
                if s_desc_size < 4 + 4 + 4 + 2 { None } else {
                    Some(inner.read_u16::<LittleEndian>()?) /* Free blocks count MSB */
                };
            let bg_free_inodes_count_hi =
                if s_desc_size < 4 + 4 + 4 + 2 + 2 { None } else {
                    Some(inner.read_u16::<LittleEndian>()?) /* Free inodes count MSB */
                };

//          let bg_used_dirs_count_hi =
//              inner.read_u16::<LittleEndian>()?; /* Directories count MSB */
//          let bg_itable_unused_hi =
//              inner.read_u16::<LittleEndian>()?; /* Unused inodes count MSB */
//          let bg_exclude_bitmap_hi =
//              inner.read_u32::<LittleEndian>()?; /* Exclude bitmap block MSB */
//          let bg_block_bitmap_csum_hi =
//              inner.read_u16::<LittleEndian>()?; /* crc32c(s_uuid+grp_num+bbitmap) BE */
//          let bg_inode_bitmap_csum_hi =
//              inner.read_u16::<LittleEndian>()?; /* crc32c(s_uuid+grp_num+ibitmap) BE */

            if s_desc_size > 16 + 32 {
                inner.seek(io::SeekFrom::Current((s_desc_size - 32 - 16) as i64))?;
            }

            let inode_table_block = bg_inode_table_lo as u64
                | ((bg_inode_table_hi.unwrap_or(0) as u64) << 32);
            let free_inodes_count = bg_free_inodes_count_lo as u32
                | ((bg_free_inodes_count_hi.unwrap_or(0) as u32) << 16);

            let unallocated = bg_flags & EXT4_BLOCK_GROUP_INODES_UNUSED != 0 || bg_flags & EXT4_BLOCK_GROUP_BLOCKS_UNUSED != 0;

            if free_inodes_count > s_inodes_per_group {
                return Err(::parse_error(format!("too many free inodes in group {}: {} > {}",
                                               block, free_inodes_count, s_inodes_per_group)));
            }

            let inodes = if unallocated {
                0
            } else {
                s_inodes_per_group - free_inodes_count
            };

            groups.push(Entry {
                inode_table_block,
                inodes,
            });
        }

        Ok(BlockGroups {
            groups,
            inodes_per_group: s_inodes_per_group,
            block_size,
            inode_size
        })
    }

    pub fn index_of(&self, inode: u32) -> u64 {
        assert_ne!(0, inode);

        let inode = inode - 1;
        let group_number = inode / self.inodes_per_group;
        let group = &self.groups[group_number as usize];
        let inode_index_in_group = inode % self.inodes_per_group;
        assert!(inode_index_in_group < group.inodes,
                "inode <{}> number must fit in group: {} is greater than {} for group {}",
                inode + 1,
                inode_index_in_group, group.inodes, group_number);
        let block = group.inode_table_block;
        block * self.block_size as u64 + inode_index_in_group as u64 * self.inode_size as u64
    }
}
<commit_msg>can't use free inodes to compute max inode in a block<commit_after>use std::io;

use byteorder::{ReadBytesExt, LittleEndian};

const EXT4_BLOCK_GROUP_INODES_UNUSED: u16 = 0b1;
const EXT4_BLOCK_GROUP_BLOCKS_UNUSED: u16 = 0b10;

#[derive(Debug)]
struct Entry {
    inode_table_block: u64,
    max_inode_number: u32,
}

#[derive(Debug)]
pub struct BlockGroups{
    groups: Vec<Entry>,
    inodes_per_group: u32,
    pub block_size: u32,
    pub inode_size: u16,
}

impl BlockGroups {
    pub fn new<R>(
        mut inner: R,
        blocks_count: u64,
        s_desc_size: u16,
        s_inodes_per_group: u32,
        block_size: u32,
        inode_size: u16) -> io::Result<BlockGroups>
    where R: io::Read + io::Seek {
        let blocks_count = ::usize_check(blocks_count)?;

        let mut groups = Vec::with_capacity(blocks_count);

        for block in 0..blocks_count {
//            let bg_block_bitmap_lo =
                inner.read_u32::<LittleEndian>()?; /* Blocks bitmap block */
//            let bg_inode_bitmap_lo =
                inner.read_u32::<LittleEndian>()?; /* Inodes bitmap block */
            let bg_inode_table_lo =
                inner.read_u32::<LittleEndian>()?; /* Inodes table block */
//            let bg_free_blocks_count_lo =
                inner.read_u16::<LittleEndian>()?; /* Free blocks count */
            let bg_free_inodes_count_lo =
                inner.read_u16::<LittleEndian>()?; /* Free inodes count */
//            let bg_used_dirs_count_lo =
                inner.read_u16::<LittleEndian>()?; /* Directories count */
            let bg_flags =
                inner.read_u16::<LittleEndian>()?; /* EXT4_BG_flags (INODE_UNINIT, etc) */
//            let bg_exclude_bitmap_lo =
                inner.read_u32::<LittleEndian>()?; /* Exclude bitmap for snapshots */
//            let bg_block_bitmap_csum_lo =
                inner.read_u16::<LittleEndian>()?; /* crc32c(s_uuid+grp_num+bbitmap) LE */
//            let bg_inode_bitmap_csum_lo =
                inner.read_u16::<LittleEndian>()?; /* crc32c(s_uuid+grp_num+ibitmap) LE */
//            let bg_itable_unused_lo =
                inner.read_u16::<LittleEndian>()?; /* Unused inodes count */
//            let bg_checksum =
                inner.read_u16::<LittleEndian>()?; /* crc16(sb_uuid+group+desc) */

//            let bg_block_bitmap_hi =
                if s_desc_size < 4 { None } else {
                    Some(inner.read_u32::<LittleEndian>()?) /* Blocks bitmap block MSB */
                };
//            let bg_inode_bitmap_hi =
                if s_desc_size < 4 + 4 { None } else {
                    Some(inner.read_u32::<LittleEndian>()?) /* Inodes bitmap block MSB */
                };
            let bg_inode_table_hi =
                if s_desc_size < 4 + 4 + 4 { None } else {
                    Some(inner.read_u32::<LittleEndian>()?) /* Inodes table block MSB */
                };
//            let bg_free_blocks_count_hi =
                if s_desc_size < 4 + 4 + 4 + 2 { None } else {
                    Some(inner.read_u16::<LittleEndian>()?) /* Free blocks count MSB */
                };
            let bg_free_inodes_count_hi =
                if s_desc_size < 4 + 4 + 4 + 2 + 2 { None } else {
                    Some(inner.read_u16::<LittleEndian>()?) /* Free inodes count MSB */
                };

//          let bg_used_dirs_count_hi =
//              inner.read_u16::<LittleEndian>()?; /* Directories count MSB */
//          let bg_itable_unused_hi =
//              inner.read_u16::<LittleEndian>()?; /* Unused inodes count MSB */
//          let bg_exclude_bitmap_hi =
//              inner.read_u32::<LittleEndian>()?; /* Exclude bitmap block MSB */
//          let bg_block_bitmap_csum_hi =
//              inner.read_u16::<LittleEndian>()?; /* crc32c(s_uuid+grp_num+bbitmap) BE */
//          let bg_inode_bitmap_csum_hi =
//              inner.read_u16::<LittleEndian>()?; /* crc32c(s_uuid+grp_num+ibitmap) BE */

            if s_desc_size > 16 + 32 {
                inner.seek(io::SeekFrom::Current((s_desc_size - 32 - 16) as i64))?;
            }

            let inode_table_block = bg_inode_table_lo as u64
                | ((bg_inode_table_hi.unwrap_or(0) as u64) << 32);
            let free_inodes_count = bg_free_inodes_count_lo as u32
                | ((bg_free_inodes_count_hi.unwrap_or(0) as u32) << 16);

            let unallocated = bg_flags & EXT4_BLOCK_GROUP_INODES_UNUSED != 0 || bg_flags & EXT4_BLOCK_GROUP_BLOCKS_UNUSED != 0;

            if free_inodes_count > s_inodes_per_group {
                return Err(::parse_error(format!("too many free inodes in group {}: {} > {}",
                                               block, free_inodes_count, s_inodes_per_group)));
            }

            let max_inode_number = if unallocated {
                0
            } else {
                // can't use free inodes here, as there can be unallocated ranges in the middle;
                // would have to parse the bitmap to work that out and it doesn't seem worth
                // the effort
                s_inodes_per_group
            };

            groups.push(Entry {
                inode_table_block,
                max_inode_number,
            });
        }

        Ok(BlockGroups {
            groups,
            inodes_per_group: s_inodes_per_group,
            block_size,
            inode_size
        })
    }

    pub fn index_of(&self, inode: u32) -> u64 {
        assert_ne!(0, inode);

        let inode = inode - 1;
        let group_number = inode / self.inodes_per_group;
        let group = &self.groups[group_number as usize];
        let inode_index_in_group = inode % self.inodes_per_group;
        assert!(inode_index_in_group < group.max_inode_number,
                "inode <{}> number must fit in group: {} is greater than {} for group {}",
                inode + 1,
                inode_index_in_group, group.max_inode_number, group_number);
        let block = group.inode_table_block;
        block * self.block_size as u64 + inode_index_in_group as u64 * self.inode_size as u64
    }
}
<|endoftext|>


<commit_before>// Copyright 2013 The CGMath Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Angle units for type-safe, self-documenting code.

use std::fmt;
use std::num::{One, one, Zero, zero, cast};

use approx::ApproxEq;

#[deriving(Clone, Eq, Ord, Hash)] pub struct Rad<S> { pub s: S }
#[deriving(Clone, Eq, Ord, Hash)] pub struct Deg<S> { pub s: S }

#[inline] pub fn rad<S: Float>(s: S) -> Rad<S> { Rad { s: s } }
#[inline] pub fn deg<S: Float>(s: S) -> Deg<S> { Deg { s: s } }

pub trait ToRad<S: Float> { fn to_rad(&self) -> Rad<S>; }
pub trait ToDeg<S: Float> { fn to_deg(&self) -> Deg<S>; }

impl<S: Float> ToRad<S> for Rad<S> { #[inline] fn to_rad(&self) -> Rad<S> { self.clone() } }
impl<S: Float> ToRad<S> for Deg<S> { #[inline] fn to_rad(&self) -> Rad<S> { rad(self.s.to_radians()) } }

impl<S: Float> ToDeg<S> for Rad<S> { #[inline] fn to_deg(&self) -> Deg<S> { deg(self.s.to_degrees()) } }
impl<S: Float> ToDeg<S> for Deg<S> { #[inline] fn to_deg(&self) -> Deg<S> { self.clone() } }

/// Private utility functions for converting to/from scalars
trait ScalarConv<S> {
    fn from(s: S) -> Self;
    fn s<'a>(&'a self) -> &'a S;
    fn mut_s<'a>(&'a mut self) -> &'a mut S;
}

impl<S: Float> ScalarConv<S> for Rad<S> {
    #[inline] fn from(s: S) -> Rad<S> { rad(s) }
    #[inline] fn s<'a>(&'a self) -> &'a S { &'a self.s }
    #[inline] fn mut_s<'a>(&'a mut self) -> &'a mut S { &'a mut self.s }
}

impl<S: Float> ScalarConv<S> for Deg<S> {
    #[inline] fn from(s: S) -> Deg<S> { deg(s) }
    #[inline] fn s<'a>(&'a self) -> &'a S { &'a self.s }
    #[inline] fn mut_s<'a>(&'a mut self) -> &'a mut S { &'a mut self.s }
}

pub trait Angle
<
    S: Float
>
:   Clone + Zero
+   Eq + Equiv<Self> + Ord
+   ApproxEq<S>
+   Neg<Self>
+   ToRad<S>
+   ToDeg<S>
+   ScalarConv<S>
{
    fn from<A: Angle<S>>(theta: A) -> Self;

    #[inline] fn neg_self(&mut self) { *self = -*self }

    #[inline] fn add_a(&self, other: Self) -> Self { ScalarConv::from(*self.s() + *other.s()) }
    #[inline] fn sub_a(&self, other: Self) -> Self { ScalarConv::from(*self.s() - *other.s()) }
    #[inline] fn div_a(&self, other: Self) -> S { *self.s() / *other.s() }
    #[inline] fn rem_a(&self, other: Self) -> S { *self.s() % *other.s() }
    #[inline] fn mul_s(&self, s: S) -> Self { ScalarConv::from(*self.s() * s) }
    #[inline] fn div_s(&self, s: S) -> Self { ScalarConv::from(*self.s() / s) }
    #[inline] fn rem_s(&self, s: S) -> Self { ScalarConv::from(*self.s() % s) }

    #[inline] fn add_self_a(&mut self, other: Self) { *self.mut_s() = *self.s() + *other.s() }
    #[inline] fn sub_self_a(&mut self, other: Self) { *self.mut_s() = *self.s() - *other.s() }
    #[inline] fn mul_self_s(&mut self, s: S) { *self.mut_s() = *self.s() * s }
    #[inline] fn div_self_s(&mut self, s: S) { *self.mut_s() = *self.s() / s }
    #[inline] fn rem_self_s(&mut self, s: S) { *self.mut_s() = *self.s() % s }

    /// Return the angle, normalized to the range `[0, full_turn)`.
    #[inline]
    fn normalize(&self) -> Self {
        let mut a = self.clone();
        a.normalize_self();
        a
    }

    /// Normalize the angle to the range `[0, full_turn)`.
    #[inline]
    fn normalize_self(&mut self) {
        let full_turn: Self = Angle::full_turn();
        self.rem_self_s(full_turn.s().clone());
        if *self < zero() { self.add_self_a(full_turn) };
    }

    /// Return the angle rotated by half a turn
    #[inline]
    fn opposite(&self) -> Self {
        self.add_a(Angle::turn_div_2()).normalize()
    }

    /// Returns the interior bisector of the two angles
    #[inline]
    fn bisect(&self, other: Self) -> Self {
        self.add_a(self.sub_a(other).mul_s(cast(0.5).unwrap())).normalize()
    }

    fn full_turn() -> Self;

    #[inline] fn turn_div_2() -> Self { let full_turn: Self = Angle::full_turn(); full_turn.div_s(cast(2).unwrap()) }
    #[inline] fn turn_div_3() -> Self { let full_turn: Self = Angle::full_turn(); full_turn.div_s(cast(3).unwrap()) }
    #[inline] fn turn_div_4() -> Self { let full_turn: Self = Angle::full_turn(); full_turn.div_s(cast(4).unwrap()) }
    #[inline] fn turn_div_6() -> Self { let full_turn: Self = Angle::full_turn(); full_turn.div_s(cast(6).unwrap()) }
}

#[inline] pub fn bisect<S: Float, A: Angle<S>>(a: A, b: A) -> A { a.bisect(b) }

impl<S: Float + ApproxEq<S>>
Rad<S> {
    #[inline] pub fn zero() -> Rad<S> { zero() }
    #[inline] pub fn full_turn() -> Rad<S> { Angle::full_turn() }
    #[inline] pub fn turn_div_2() -> Rad<S> { Angle::turn_div_2() }
    #[inline] pub fn turn_div_3() -> Rad<S> { Angle::turn_div_3() }
    #[inline] pub fn turn_div_4() -> Rad<S> { Angle::turn_div_4() }
    #[inline] pub fn turn_div_6() -> Rad<S> { Angle::turn_div_6() }
}

impl<S: Float + ApproxEq<S>>
Deg<S> {
    #[inline] pub fn zero() -> Deg<S> { zero() }
    #[inline] pub fn full_turn() -> Deg<S> { Angle::full_turn() }
    #[inline] pub fn turn_div_2() -> Deg<S> { Angle::turn_div_2() }
    #[inline] pub fn turn_div_3() -> Deg<S> { Angle::turn_div_3() }
    #[inline] pub fn turn_div_4() -> Deg<S> { Angle::turn_div_4() }
    #[inline] pub fn turn_div_6() -> Deg<S> { Angle::turn_div_6() }
}

impl<S: Float> Add<Rad<S>, Rad<S>> for Rad<S> { #[inline] fn add(&self, other: &Rad<S>) -> Rad<S> { rad(self.s + other.s) } }
impl<S: Float> Add<Deg<S>, Deg<S>> for Deg<S> { #[inline] fn add(&self, other: &Deg<S>) -> Deg<S> { deg(self.s + other.s) } }

impl<S: Float> Sub<Rad<S>, Rad<S>> for Rad<S> { #[inline] fn sub(&self, other: &Rad<S>) -> Rad<S> { rad(self.s - other.s) } }
impl<S: Float> Sub<Deg<S>, Deg<S>> for Deg<S> { #[inline] fn sub(&self, other: &Deg<S>) -> Deg<S> { deg(self.s - other.s) } }

impl<S: Float> Neg<Rad<S>> for Rad<S> { #[inline] fn neg(&self) -> Rad<S> { rad(-self.s) } }
impl<S: Float> Neg<Deg<S>> for Deg<S> { #[inline] fn neg(&self) -> Deg<S> { deg(-self.s) } }

impl<S: Float> Zero for Rad<S> { #[inline] fn zero() -> Rad<S> { rad(zero()) } #[inline] fn is_zero(&self) -> bool { *self == zero() } }
impl<S: Float> Zero for Deg<S> { #[inline] fn zero() -> Deg<S> { deg(zero()) } #[inline] fn is_zero(&self) -> bool { *self == zero() } }

impl<S: Float> Mul<Rad<S>, Rad<S>> for Rad<S> { #[inline] fn mul(&self, other: &Rad<S>) -> Rad<S> { rad(self.s * other.s) } }
impl<S: Float> Mul<Deg<S>, Deg<S>> for Deg<S> { #[inline] fn mul(&self, other: &Deg<S>) -> Deg<S> { deg(self.s * other.s) } }

impl<S: Float> One for Rad<S> { #[inline] fn one() -> Rad<S> { rad(one()) } }
impl<S: Float> One for Deg<S> { #[inline] fn one() -> Deg<S> { deg(one()) } }

impl<S: Float + ApproxEq<S>>
Equiv<Rad<S>> for Rad<S> {
    fn equiv(&self, other: &Rad<S>) -> bool {
        self.normalize() == other.normalize()
    }
}

impl<S: Float + ApproxEq<S>>
Equiv<Deg<S>> for Deg<S> {
    fn equiv(&self, other: &Deg<S>) -> bool {
        self.normalize() == other.normalize()
    }
}

impl<S: Float + ApproxEq<S>>
Angle<S> for Rad<S> {
    #[inline] fn from<A: Angle<S>>(theta: A) -> Rad<S> { theta.to_rad() }
    #[inline] fn full_turn() -> Rad<S> { rad(Float::two_pi()) }
}

impl<S: Float + ApproxEq<S>>
Angle<S> for Deg<S> {
    #[inline] fn from<A: Angle<S>>(theta: A) -> Deg<S> { theta.to_deg() }
    #[inline] fn full_turn() -> Deg<S> { deg(cast(360).unwrap()) }
}

#[inline] pub fn sin<S: FloatMath>(theta: Rad<S>) -> S { theta.s.sin() }
#[inline] pub fn cos<S: FloatMath>(theta: Rad<S>) -> S { theta.s.cos() }
#[inline] pub fn tan<S: FloatMath>(theta: Rad<S>) -> S { theta.s.tan() }
#[inline] pub fn sin_cos<S: FloatMath>(theta: Rad<S>) -> (S, S) { theta.s.sin_cos() }

#[inline] pub fn cot<S: FloatMath>(theta: Rad<S>) -> S { tan(theta).recip() }
#[inline] pub fn sec<S: FloatMath>(theta: Rad<S>) -> S { cos(theta).recip() }
#[inline] pub fn csc<S: FloatMath>(theta: Rad<S>) -> S { sin(theta).recip() }

#[inline] pub fn asin<S: FloatMath>(s: S) -> Rad<S> { rad(s.asin()) }
#[inline] pub fn acos<S: FloatMath>(s: S) -> Rad<S> { rad(s.acos()) }
#[inline] pub fn atan<S: FloatMath>(s: S) -> Rad<S> { rad(s.atan()) }
#[inline] pub fn atan2<S: FloatMath>(a: S, b: S) -> Rad<S> { rad(a.atan2(b)) }

impl<S: Float + fmt::Show>
fmt::Show for Rad<S> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{} rad", self.s)
    }
}

impl<S: Float + fmt::Show>
fmt::Show for Deg<S> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}°", self.s)
    }
}

impl<S: Float + ApproxEq<S>>
ApproxEq<S> for Rad<S> {
    #[inline]
    fn approx_eq_eps(&self, other: &Rad<S>, epsilon: &S) -> bool {
        self.s.approx_eq_eps(&other.s, epsilon)
    }
}

impl<S: Float + ApproxEq<S>>
ApproxEq<S> for Deg<S> {
    #[inline]
    fn approx_eq_eps(&self, other: &Deg<S>, epsilon: &S) -> bool {
        self.s.approx_eq_eps(&other.s, epsilon)
    }
}
<commit_msg>Add some docs for Angle<commit_after>// Copyright 2013 The CGMath Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Angle units for type-safe, self-documenting code.

use std::fmt;
use std::num::{One, one, Zero, zero, cast};

use approx::ApproxEq;

/// An angle, in radians
#[deriving(Clone, Eq, Ord, Hash)] pub struct Rad<S> { pub s: S }
/// An angle, in degrees
#[deriving(Clone, Eq, Ord, Hash)] pub struct Deg<S> { pub s: S }

/// Create a new angle, in radians
#[inline] pub fn rad<S: Float>(s: S) -> Rad<S> { Rad { s: s } }
/// Create a new angle, in degrees
#[inline] pub fn deg<S: Float>(s: S) -> Deg<S> { Deg { s: s } }

/// Represents types that can be converted to radians.
pub trait ToRad<S: Float> {
    /// Convert this value to radians.
    fn to_rad(&self) -> Rad<S>;
}

/// Represents types that can be converted to degrees.
pub trait ToDeg<S: Float> {
    /// Convert this value to degrees.
    fn to_deg(&self) -> Deg<S>;
}

impl<S: Float> ToRad<S> for Rad<S> { #[inline] fn to_rad(&self) -> Rad<S> { self.clone() } }
impl<S: Float> ToRad<S> for Deg<S> { #[inline] fn to_rad(&self) -> Rad<S> { rad(self.s.to_radians()) } }

impl<S: Float> ToDeg<S> for Rad<S> { #[inline] fn to_deg(&self) -> Deg<S> { deg(self.s.to_degrees()) } }
impl<S: Float> ToDeg<S> for Deg<S> { #[inline] fn to_deg(&self) -> Deg<S> { self.clone() } }

/// Private utility functions for converting to/from scalars
trait ScalarConv<S> {
    fn from(s: S) -> Self;
    fn s<'a>(&'a self) -> &'a S;
    fn mut_s<'a>(&'a mut self) -> &'a mut S;
}

impl<S: Float> ScalarConv<S> for Rad<S> {
    #[inline] fn from(s: S) -> Rad<S> { rad(s) }
    #[inline] fn s<'a>(&'a self) -> &'a S { &'a self.s }
    #[inline] fn mut_s<'a>(&'a mut self) -> &'a mut S { &'a mut self.s }
}

impl<S: Float> ScalarConv<S> for Deg<S> {
    #[inline] fn from(s: S) -> Deg<S> { deg(s) }
    #[inline] fn s<'a>(&'a self) -> &'a S { &'a self.s }
    #[inline] fn mut_s<'a>(&'a mut self) -> &'a mut S { &'a mut self.s }
}

/// Operations on angles.
pub trait Angle
<
    S: Float
>
:   Clone + Zero
+   Eq + Equiv<Self> + Ord
+   ApproxEq<S>
+   Neg<Self>
+   ToRad<S>
+   ToDeg<S>
+   ScalarConv<S>
{
    /// Create a new angle from any other valid angle.
    fn from<A: Angle<S>>(theta: A) -> Self;

    /// Negate this angle, in-place.
    #[inline] fn neg_self(&mut self) { *self = -*self }

    /// Add this angle with another, returning the new angle.
    #[inline] fn add_a(&self, other: Self) -> Self { ScalarConv::from(*self.s() + *other.s()) }
    /// Subtract another angle from this one, returning the new angle.
    #[inline] fn sub_a(&self, other: Self) -> Self { ScalarConv::from(*self.s() - *other.s()) }
    /// Divide this angle by another, returning the ratio.
    #[inline] fn div_a(&self, other: Self) -> S { *self.s() / *other.s() }
    /// Take the remainder of this angle with another.
    #[inline] fn rem_a(&self, other: Self) -> S { *self.s() % *other.s() }

    /// Multiply this angle by a scalar, returning the new angle.
    #[inline] fn mul_s(&self, s: S) -> Self { ScalarConv::from(*self.s() * s) }
    /// Divide this angle by a scalar, returing the new angle.
    #[inline] fn div_s(&self, s: S) -> Self { ScalarConv::from(*self.s() / s) }
    /// Take the remainder of this angle by a scalar, returning the new angle.
    #[inline] fn rem_s(&self, s: S) -> Self { ScalarConv::from(*self.s() % s) }

    /// Add this angle with another, in-place.
    #[inline] fn add_self_a(&mut self, other: Self) { *self.mut_s() = *self.s() + *other.s() }
    /// Subtract another angle from this one, in-place.
    #[inline] fn sub_self_a(&mut self, other: Self) { *self.mut_s() = *self.s() - *other.s() }

    /// Multiply this angle by a scalar, in-place.
    #[inline] fn mul_self_s(&mut self, s: S) { *self.mut_s() = *self.s() * s }
    /// Divide this angle by a scalar, in-place.
    #[inline] fn div_self_s(&mut self, s: S) { *self.mut_s() = *self.s() / s }
    /// Take the remainder of this angle by a scalar, in-place.
    #[inline] fn rem_self_s(&mut self, s: S) { *self.mut_s() = *self.s() % s }

    /// Return the angle, normalized to the range `[0, full_turn)`.
    #[inline]
    fn normalize(&self) -> Self {
        let mut a = self.clone();
        a.normalize_self();
        a
    }

    /// Normalize the angle to the range `[0, full_turn)`.
    #[inline]
    fn normalize_self(&mut self) {
        let full_turn: Self = Angle::full_turn();
        self.rem_self_s(full_turn.s().clone());
        if *self < zero() { self.add_self_a(full_turn) };
    }

    /// Return the angle rotated by half a turn
    #[inline]
    fn opposite(&self) -> Self {
        self.add_a(Angle::turn_div_2()).normalize()
    }

    /// Returns the interior bisector of the two angles
    #[inline]
    fn bisect(&self, other: Self) -> Self {
        self.add_a(self.sub_a(other).mul_s(cast(0.5).unwrap())).normalize()
    }

    fn full_turn() -> Self;

    #[inline] fn turn_div_2() -> Self { let full_turn: Self = Angle::full_turn(); full_turn.div_s(cast(2).unwrap()) }
    #[inline] fn turn_div_3() -> Self { let full_turn: Self = Angle::full_turn(); full_turn.div_s(cast(3).unwrap()) }
    #[inline] fn turn_div_4() -> Self { let full_turn: Self = Angle::full_turn(); full_turn.div_s(cast(4).unwrap()) }
    #[inline] fn turn_div_6() -> Self { let full_turn: Self = Angle::full_turn(); full_turn.div_s(cast(6).unwrap()) }
}

#[inline] pub fn bisect<S: Float, A: Angle<S>>(a: A, b: A) -> A { a.bisect(b) }

impl<S: Float + ApproxEq<S>>
Rad<S> {
    #[inline] pub fn zero() -> Rad<S> { zero() }
    #[inline] pub fn full_turn() -> Rad<S> { Angle::full_turn() }
    #[inline] pub fn turn_div_2() -> Rad<S> { Angle::turn_div_2() }
    #[inline] pub fn turn_div_3() -> Rad<S> { Angle::turn_div_3() }
    #[inline] pub fn turn_div_4() -> Rad<S> { Angle::turn_div_4() }
    #[inline] pub fn turn_div_6() -> Rad<S> { Angle::turn_div_6() }
}

impl<S: Float + ApproxEq<S>>
Deg<S> {
    #[inline] pub fn zero() -> Deg<S> { zero() }
    #[inline] pub fn full_turn() -> Deg<S> { Angle::full_turn() }
    #[inline] pub fn turn_div_2() -> Deg<S> { Angle::turn_div_2() }
    #[inline] pub fn turn_div_3() -> Deg<S> { Angle::turn_div_3() }
    #[inline] pub fn turn_div_4() -> Deg<S> { Angle::turn_div_4() }
    #[inline] pub fn turn_div_6() -> Deg<S> { Angle::turn_div_6() }
}

impl<S: Float> Add<Rad<S>, Rad<S>> for Rad<S> { #[inline] fn add(&self, other: &Rad<S>) -> Rad<S> { rad(self.s + other.s) } }
impl<S: Float> Add<Deg<S>, Deg<S>> for Deg<S> { #[inline] fn add(&self, other: &Deg<S>) -> Deg<S> { deg(self.s + other.s) } }

impl<S: Float> Sub<Rad<S>, Rad<S>> for Rad<S> { #[inline] fn sub(&self, other: &Rad<S>) -> Rad<S> { rad(self.s - other.s) } }
impl<S: Float> Sub<Deg<S>, Deg<S>> for Deg<S> { #[inline] fn sub(&self, other: &Deg<S>) -> Deg<S> { deg(self.s - other.s) } }

impl<S: Float> Neg<Rad<S>> for Rad<S> { #[inline] fn neg(&self) -> Rad<S> { rad(-self.s) } }
impl<S: Float> Neg<Deg<S>> for Deg<S> { #[inline] fn neg(&self) -> Deg<S> { deg(-self.s) } }

impl<S: Float> Zero for Rad<S> { #[inline] fn zero() -> Rad<S> { rad(zero()) } #[inline] fn is_zero(&self) -> bool { *self == zero() } }
impl<S: Float> Zero for Deg<S> { #[inline] fn zero() -> Deg<S> { deg(zero()) } #[inline] fn is_zero(&self) -> bool { *self == zero() } }

impl<S: Float> Mul<Rad<S>, Rad<S>> for Rad<S> { #[inline] fn mul(&self, other: &Rad<S>) -> Rad<S> { rad(self.s * other.s) } }
impl<S: Float> Mul<Deg<S>, Deg<S>> for Deg<S> { #[inline] fn mul(&self, other: &Deg<S>) -> Deg<S> { deg(self.s * other.s) } }

impl<S: Float> One for Rad<S> { #[inline] fn one() -> Rad<S> { rad(one()) } }
impl<S: Float> One for Deg<S> { #[inline] fn one() -> Deg<S> { deg(one()) } }

impl<S: Float + ApproxEq<S>>
Equiv<Rad<S>> for Rad<S> {
    fn equiv(&self, other: &Rad<S>) -> bool {
        self.normalize() == other.normalize()
    }
}

impl<S: Float + ApproxEq<S>>
Equiv<Deg<S>> for Deg<S> {
    fn equiv(&self, other: &Deg<S>) -> bool {
        self.normalize() == other.normalize()
    }
}

impl<S: Float + ApproxEq<S>>
Angle<S> for Rad<S> {
    #[inline] fn from<A: Angle<S>>(theta: A) -> Rad<S> { theta.to_rad() }
    #[inline] fn full_turn() -> Rad<S> { rad(Float::two_pi()) }
}

impl<S: Float + ApproxEq<S>>
Angle<S> for Deg<S> {
    #[inline] fn from<A: Angle<S>>(theta: A) -> Deg<S> { theta.to_deg() }
    #[inline] fn full_turn() -> Deg<S> { deg(cast(360).unwrap()) }
}

#[inline] pub fn sin<S: FloatMath>(theta: Rad<S>) -> S { theta.s.sin() }
#[inline] pub fn cos<S: FloatMath>(theta: Rad<S>) -> S { theta.s.cos() }
#[inline] pub fn tan<S: FloatMath>(theta: Rad<S>) -> S { theta.s.tan() }
#[inline] pub fn sin_cos<S: FloatMath>(theta: Rad<S>) -> (S, S) { theta.s.sin_cos() }

#[inline] pub fn cot<S: FloatMath>(theta: Rad<S>) -> S { tan(theta).recip() }
#[inline] pub fn sec<S: FloatMath>(theta: Rad<S>) -> S { cos(theta).recip() }
#[inline] pub fn csc<S: FloatMath>(theta: Rad<S>) -> S { sin(theta).recip() }

#[inline] pub fn asin<S: FloatMath>(s: S) -> Rad<S> { rad(s.asin()) }
#[inline] pub fn acos<S: FloatMath>(s: S) -> Rad<S> { rad(s.acos()) }
#[inline] pub fn atan<S: FloatMath>(s: S) -> Rad<S> { rad(s.atan()) }
#[inline] pub fn atan2<S: FloatMath>(a: S, b: S) -> Rad<S> { rad(a.atan2(b)) }

impl<S: Float + fmt::Show>
fmt::Show for Rad<S> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{} rad", self.s)
    }
}

impl<S: Float + fmt::Show>
fmt::Show for Deg<S> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}°", self.s)
    }
}

impl<S: Float + ApproxEq<S>>
ApproxEq<S> for Rad<S> {
    #[inline]
    fn approx_eq_eps(&self, other: &Rad<S>, epsilon: &S) -> bool {
        self.s.approx_eq_eps(&other.s, epsilon)
    }
}

impl<S: Float + ApproxEq<S>>
ApproxEq<S> for Deg<S> {
    #[inline]
    fn approx_eq_eps(&self, other: &Deg<S>, epsilon: &S) -> bool {
        self.s.approx_eq_eps(&other.s, epsilon)
    }
}
<|endoftext|>


<commit_before>// Copyright 2017 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 borrow_check::borrow_set::BorrowSet;
use borrow_check::location::{LocationIndex, LocationTable};
use borrow_check::nll::facts::AllFactsExt;
use dataflow::indexes::BorrowIndex;
use dataflow::move_paths::MoveData;
use dataflow::FlowAtLocation;
use dataflow::MaybeInitializedPlaces;
use rustc::hir::def_id::DefId;
use rustc::infer::InferCtxt;
use rustc::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, Mir};
use rustc::ty::{self, RegionKind, RegionVid};
use rustc::util::nodemap::FxHashMap;
use std::collections::BTreeSet;
use std::fmt::Debug;
use std::env;
use std::io;
use std::path::PathBuf;
use std::rc::Rc;
use std::str::FromStr;
use transform::MirSource;
use util::liveness::{LivenessResults, LocalSet};

use self::mir_util::PassWhere;
use polonius_engine::{Algorithm, Output};
use util as mir_util;
use util::pretty::{self, ALIGN};

mod constraint_generation;
pub mod explain_borrow;
mod facts;
mod invalidation;
crate mod region_infer;
mod renumber;
mod subtype_constraint_generation;
crate mod type_check;
mod universal_regions;

use self::facts::AllFacts;
use self::region_infer::RegionInferenceContext;
use self::universal_regions::UniversalRegions;

/// Rewrites the regions in the MIR to use NLL variables, also
/// scraping out the set of universal regions (e.g., region parameters)
/// declared on the function. That set will need to be given to
/// `compute_regions`.
pub(in borrow_check) fn replace_regions_in_mir<'cx, 'gcx, 'tcx>(
    infcx: &InferCtxt<'cx, 'gcx, 'tcx>,
    def_id: DefId,
    param_env: ty::ParamEnv<'tcx>,
    mir: &mut Mir<'tcx>,
) -> UniversalRegions<'tcx> {
    debug!("replace_regions_in_mir(def_id={:?})", def_id);

    // Compute named region information. This also renumbers the inputs/outputs.
    let universal_regions = UniversalRegions::new(infcx, def_id, param_env);

    // Replace all remaining regions with fresh inference variables.
    renumber::renumber_mir(infcx, mir);

    let source = MirSource::item(def_id);
    mir_util::dump_mir(infcx.tcx, None, "renumber", &0, source, mir, |_, _| Ok(()));

    universal_regions
}

/// Computes the (non-lexical) regions from the input MIR.
///
/// This may result in errors being reported.
pub(in borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>(
    infcx: &InferCtxt<'cx, 'gcx, 'tcx>,
    def_id: DefId,
    universal_regions: UniversalRegions<'tcx>,
    mir: &Mir<'tcx>,
    location_table: &LocationTable,
    param_env: ty::ParamEnv<'gcx>,
    flow_inits: &mut FlowAtLocation<MaybeInitializedPlaces<'cx, 'gcx, 'tcx>>,
    move_data: &MoveData<'tcx>,
    borrow_set: &BorrowSet<'tcx>,
) -> (
    RegionInferenceContext<'tcx>,
    Option<Rc<Output<RegionVid, BorrowIndex, LocationIndex>>>,
    Option<ClosureRegionRequirements<'gcx>>,
) {
    // Run the MIR type-checker.
    let liveness = &LivenessResults::compute(mir);
    let constraint_sets = &type_check::type_check(
        infcx,
        param_env,
        mir,
        def_id,
        &universal_regions,
        &liveness,
        flow_inits,
        move_data,
    );

    let mut all_facts = if infcx.tcx.sess.opts.debugging_opts.nll_facts
        || infcx.tcx.sess.opts.debugging_opts.polonius
    {
        Some(AllFacts::default())
    } else {
        None
    };

    if let Some(all_facts) = &mut all_facts {
        all_facts
            .universal_region
            .extend(universal_regions.universal_regions());
    }

    // Create the region inference context, taking ownership of the region inference
    // data that was contained in `infcx`.
    let var_origins = infcx.take_region_var_origins();
    let mut regioncx = RegionInferenceContext::new(var_origins, universal_regions, mir);

    // Generate various constraints.
    subtype_constraint_generation::generate(
        &mut regioncx,
        &mut all_facts,
        location_table,
        mir,
        constraint_sets,
    );
    constraint_generation::generate_constraints(
        infcx,
        &mut regioncx,
        &mut all_facts,
        location_table,
        &mir,
        borrow_set,
    );
    invalidation::generate_invalidates(
        infcx,
        &mut all_facts,
        location_table,
        &mir,
        def_id,
        borrow_set,
    );

    // Dump facts if requested.
    let polonius_output = all_facts.and_then(|all_facts| {
        if infcx.tcx.sess.opts.debugging_opts.nll_facts {
            let def_path = infcx.tcx.hir.def_path(def_id);
            let dir_path =
                PathBuf::from("nll-facts").join(def_path.to_filename_friendly_no_crate());
            all_facts.write_to_dir(dir_path, location_table).unwrap();
        }

        if infcx.tcx.sess.opts.debugging_opts.polonius {
            let algorithm = env::var("POLONIUS_ALGORITHM")
                .unwrap_or(String::from("DatafrogOpt"));
            let algorithm = Algorithm::from_str(&algorithm).unwrap();
            info!("Using Polonius algorithm: {:?}", algorithm);
            Some(Rc::new(Output::compute(
                &all_facts,
                algorithm,
                false,
            )))
        } else {
            None
        }
    });

    // Solve the region constraints.
    let closure_region_requirements = regioncx.solve(infcx, &mir, def_id);

    // Dump MIR results into a file, if that is enabled. This let us
    // write unit-tests, as well as helping with debugging.
    dump_mir_results(
        infcx,
        liveness,
        MirSource::item(def_id),
        &mir,
        &regioncx,
        &closure_region_requirements,
    );

    // We also have a `#[rustc_nll]` annotation that causes us to dump
    // information
    dump_annotation(infcx, &mir, def_id, &regioncx, &closure_region_requirements);

    (regioncx, polonius_output, closure_region_requirements)
}

fn dump_mir_results<'a, 'gcx, 'tcx>(
    infcx: &InferCtxt<'a, 'gcx, 'tcx>,
    liveness: &LivenessResults,
    source: MirSource,
    mir: &Mir<'tcx>,
    regioncx: &RegionInferenceContext,
    closure_region_requirements: &Option<ClosureRegionRequirements>,
) {
    if !mir_util::dump_enabled(infcx.tcx, "nll", source) {
        return;
    }

    let regular_liveness_per_location: FxHashMap<_, _> = mir
        .basic_blocks()
        .indices()
        .flat_map(|bb| {
            let mut results = vec![];
            liveness
                .regular
                .simulate_block(&mir, bb, |location, local_set| {
                    results.push((location, local_set.clone()));
                });
            results
        })
        .collect();

    let drop_liveness_per_location: FxHashMap<_, _> = mir
        .basic_blocks()
        .indices()
        .flat_map(|bb| {
            let mut results = vec![];
            liveness
                .drop
                .simulate_block(&mir, bb, |location, local_set| {
                    results.push((location, local_set.clone()));
                });
            results
        })
        .collect();

    mir_util::dump_mir(
        infcx.tcx,
        None,
        "nll",
        &0,
        source,
        mir,
        |pass_where, out| {
            match pass_where {
                // Before the CFG, dump out the values for each region variable.
                PassWhere::BeforeCFG => {
                    regioncx.dump_mir(out)?;

                    if let Some(closure_region_requirements) = closure_region_requirements {
                        writeln!(out, "|")?;
                        writeln!(out, "| Free Region Constraints")?;
                        for_each_region_constraint(closure_region_requirements, &mut |msg| {
                            writeln!(out, "| {}", msg)
                        })?;
                    }
                }

                // Before each basic block, dump out the values
                // that are live on entry to the basic block.
                PassWhere::BeforeBlock(bb) => {
                    let s = live_variable_set(&liveness.regular.ins[bb], &liveness.drop.ins[bb]);
                    writeln!(out, "    | Live variables on entry to {:?}: {}", bb, s)?;
                }

                PassWhere::BeforeLocation(location) => {
                    let s = live_variable_set(
                        &regular_liveness_per_location[&location],
                        &drop_liveness_per_location[&location],
                    );
                    writeln!(
                        out,
                        "{:ALIGN$} | Live variables on entry to {:?}: {}",
                        "",
                        location,
                        s,
                        ALIGN = ALIGN
                    )?;
                }

                PassWhere::AfterLocation(_) | PassWhere::AfterCFG => {}
            }
            Ok(())
        },
    );

    // Also dump the inference graph constraints as a graphviz file.
    let _: io::Result<()> = do catch {
        let mut file =
            pretty::create_dump_file(infcx.tcx, "regioncx.dot", None, "nll", &0, source)?;
        regioncx.dump_graphviz(&mut file)?;
    };
}

fn dump_annotation<'a, 'gcx, 'tcx>(
    infcx: &InferCtxt<'a, 'gcx, 'tcx>,
    mir: &Mir<'tcx>,
    mir_def_id: DefId,
    regioncx: &RegionInferenceContext,
    closure_region_requirements: &Option<ClosureRegionRequirements>,
) {
    let tcx = infcx.tcx;
    let base_def_id = tcx.closure_base_def_id(mir_def_id);
    if !tcx.has_attr(base_def_id, "rustc_regions") {
        return;
    }

    // When the enclosing function is tagged with `#[rustc_regions]`,
    // we dump out various bits of state as warnings. This is useful
    // for verifying that the compiler is behaving as expected.  These
    // warnings focus on the closure region requirements -- for
    // viewing the intraprocedural state, the -Zdump-mir output is
    // better.

    if let Some(closure_region_requirements) = closure_region_requirements {
        let mut err = tcx
            .sess
            .diagnostic()
            .span_note_diag(mir.span, "External requirements");

        regioncx.annotate(&mut err);

        err.note(&format!(
            "number of external vids: {}",
            closure_region_requirements.num_external_vids
        ));

        // Dump the region constraints we are imposing *between* those
        // newly created variables.
        for_each_region_constraint(closure_region_requirements, &mut |msg| {
            err.note(msg);
            Ok(())
        }).unwrap();

        err.emit();
    } else {
        let mut err = tcx
            .sess
            .diagnostic()
            .span_note_diag(mir.span, "No external requirements");
        regioncx.annotate(&mut err);
        err.emit();
    }
}

fn for_each_region_constraint(
    closure_region_requirements: &ClosureRegionRequirements,
    with_msg: &mut dyn FnMut(&str) -> io::Result<()>,
) -> io::Result<()> {
    for req in &closure_region_requirements.outlives_requirements {
        let subject: &dyn Debug = match &req.subject {
            ClosureOutlivesSubject::Region(subject) => subject,
            ClosureOutlivesSubject::Ty(ty) => ty,
        };
        with_msg(&format!(
            "where {:?}: {:?}",
            subject, req.outlived_free_region,
        ))?;
    }
    Ok(())
}

/// Right now, we piggy back on the `ReVar` to store our NLL inference
/// regions. These are indexed with `RegionVid`. This method will
/// assert that the region is a `ReVar` and extract its internal index.
/// This is reasonable because in our MIR we replace all universal regions
/// with inference variables.
pub trait ToRegionVid {
    fn to_region_vid(self) -> RegionVid;
}

impl<'tcx> ToRegionVid for &'tcx RegionKind {
    fn to_region_vid(self) -> RegionVid {
        if let ty::ReVar(vid) = self {
            *vid
        } else {
            bug!("region is not an ReVar: {:?}", self)
        }
    }
}

impl ToRegionVid for RegionVid {
    fn to_region_vid(self) -> RegionVid {
        self
    }
}

fn live_variable_set(regular: &LocalSet, drops: &LocalSet) -> String {
    // sort and deduplicate:
    let all_locals: BTreeSet<_> = regular.iter().chain(drops.iter()).collect();

    // construct a string with each local, including `(drop)` if it is
    // only dropped, versus a regular use.
    let mut string = String::new();
    for local in all_locals {
        string.push_str(&format!("{:?}", local));

        if !regular.contains(&local) {
            assert!(drops.contains(&local));
            string.push_str(" (drop)");
        }

        string.push_str(", ");
    }

    let len = if string.is_empty() {
        0
    } else {
        string.len() - 2
    };

    format!("[{}]", &string[..len])
}
<commit_msg>Change the log level of the message reporting the selected Polonius algorithm to debug.<commit_after>// Copyright 2017 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 borrow_check::borrow_set::BorrowSet;
use borrow_check::location::{LocationIndex, LocationTable};
use borrow_check::nll::facts::AllFactsExt;
use dataflow::indexes::BorrowIndex;
use dataflow::move_paths::MoveData;
use dataflow::FlowAtLocation;
use dataflow::MaybeInitializedPlaces;
use rustc::hir::def_id::DefId;
use rustc::infer::InferCtxt;
use rustc::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, Mir};
use rustc::ty::{self, RegionKind, RegionVid};
use rustc::util::nodemap::FxHashMap;
use std::collections::BTreeSet;
use std::fmt::Debug;
use std::env;
use std::io;
use std::path::PathBuf;
use std::rc::Rc;
use std::str::FromStr;
use transform::MirSource;
use util::liveness::{LivenessResults, LocalSet};

use self::mir_util::PassWhere;
use polonius_engine::{Algorithm, Output};
use util as mir_util;
use util::pretty::{self, ALIGN};

mod constraint_generation;
pub mod explain_borrow;
mod facts;
mod invalidation;
crate mod region_infer;
mod renumber;
mod subtype_constraint_generation;
crate mod type_check;
mod universal_regions;

use self::facts::AllFacts;
use self::region_infer::RegionInferenceContext;
use self::universal_regions::UniversalRegions;

/// Rewrites the regions in the MIR to use NLL variables, also
/// scraping out the set of universal regions (e.g., region parameters)
/// declared on the function. That set will need to be given to
/// `compute_regions`.
pub(in borrow_check) fn replace_regions_in_mir<'cx, 'gcx, 'tcx>(
    infcx: &InferCtxt<'cx, 'gcx, 'tcx>,
    def_id: DefId,
    param_env: ty::ParamEnv<'tcx>,
    mir: &mut Mir<'tcx>,
) -> UniversalRegions<'tcx> {
    debug!("replace_regions_in_mir(def_id={:?})", def_id);

    // Compute named region information. This also renumbers the inputs/outputs.
    let universal_regions = UniversalRegions::new(infcx, def_id, param_env);

    // Replace all remaining regions with fresh inference variables.
    renumber::renumber_mir(infcx, mir);

    let source = MirSource::item(def_id);
    mir_util::dump_mir(infcx.tcx, None, "renumber", &0, source, mir, |_, _| Ok(()));

    universal_regions
}

/// Computes the (non-lexical) regions from the input MIR.
///
/// This may result in errors being reported.
pub(in borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>(
    infcx: &InferCtxt<'cx, 'gcx, 'tcx>,
    def_id: DefId,
    universal_regions: UniversalRegions<'tcx>,
    mir: &Mir<'tcx>,
    location_table: &LocationTable,
    param_env: ty::ParamEnv<'gcx>,
    flow_inits: &mut FlowAtLocation<MaybeInitializedPlaces<'cx, 'gcx, 'tcx>>,
    move_data: &MoveData<'tcx>,
    borrow_set: &BorrowSet<'tcx>,
) -> (
    RegionInferenceContext<'tcx>,
    Option<Rc<Output<RegionVid, BorrowIndex, LocationIndex>>>,
    Option<ClosureRegionRequirements<'gcx>>,
) {
    // Run the MIR type-checker.
    let liveness = &LivenessResults::compute(mir);
    let constraint_sets = &type_check::type_check(
        infcx,
        param_env,
        mir,
        def_id,
        &universal_regions,
        &liveness,
        flow_inits,
        move_data,
    );

    let mut all_facts = if infcx.tcx.sess.opts.debugging_opts.nll_facts
        || infcx.tcx.sess.opts.debugging_opts.polonius
    {
        Some(AllFacts::default())
    } else {
        None
    };

    if let Some(all_facts) = &mut all_facts {
        all_facts
            .universal_region
            .extend(universal_regions.universal_regions());
    }

    // Create the region inference context, taking ownership of the region inference
    // data that was contained in `infcx`.
    let var_origins = infcx.take_region_var_origins();
    let mut regioncx = RegionInferenceContext::new(var_origins, universal_regions, mir);

    // Generate various constraints.
    subtype_constraint_generation::generate(
        &mut regioncx,
        &mut all_facts,
        location_table,
        mir,
        constraint_sets,
    );
    constraint_generation::generate_constraints(
        infcx,
        &mut regioncx,
        &mut all_facts,
        location_table,
        &mir,
        borrow_set,
    );
    invalidation::generate_invalidates(
        infcx,
        &mut all_facts,
        location_table,
        &mir,
        def_id,
        borrow_set,
    );

    // Dump facts if requested.
    let polonius_output = all_facts.and_then(|all_facts| {
        if infcx.tcx.sess.opts.debugging_opts.nll_facts {
            let def_path = infcx.tcx.hir.def_path(def_id);
            let dir_path =
                PathBuf::from("nll-facts").join(def_path.to_filename_friendly_no_crate());
            all_facts.write_to_dir(dir_path, location_table).unwrap();
        }

        if infcx.tcx.sess.opts.debugging_opts.polonius {
            let algorithm = env::var("POLONIUS_ALGORITHM")
                .unwrap_or(String::from("DatafrogOpt"));
            let algorithm = Algorithm::from_str(&algorithm).unwrap();
            debug!("compute_regions: using polonius algorithm {:?}", algorithm);
            Some(Rc::new(Output::compute(
                &all_facts,
                algorithm,
                false,
            )))
        } else {
            None
        }
    });

    // Solve the region constraints.
    let closure_region_requirements = regioncx.solve(infcx, &mir, def_id);

    // Dump MIR results into a file, if that is enabled. This let us
    // write unit-tests, as well as helping with debugging.
    dump_mir_results(
        infcx,
        liveness,
        MirSource::item(def_id),
        &mir,
        &regioncx,
        &closure_region_requirements,
    );

    // We also have a `#[rustc_nll]` annotation that causes us to dump
    // information
    dump_annotation(infcx, &mir, def_id, &regioncx, &closure_region_requirements);

    (regioncx, polonius_output, closure_region_requirements)
}

fn dump_mir_results<'a, 'gcx, 'tcx>(
    infcx: &InferCtxt<'a, 'gcx, 'tcx>,
    liveness: &LivenessResults,
    source: MirSource,
    mir: &Mir<'tcx>,
    regioncx: &RegionInferenceContext,
    closure_region_requirements: &Option<ClosureRegionRequirements>,
) {
    if !mir_util::dump_enabled(infcx.tcx, "nll", source) {
        return;
    }

    let regular_liveness_per_location: FxHashMap<_, _> = mir
        .basic_blocks()
        .indices()
        .flat_map(|bb| {
            let mut results = vec![];
            liveness
                .regular
                .simulate_block(&mir, bb, |location, local_set| {
                    results.push((location, local_set.clone()));
                });
            results
        })
        .collect();

    let drop_liveness_per_location: FxHashMap<_, _> = mir
        .basic_blocks()
        .indices()
        .flat_map(|bb| {
            let mut results = vec![];
            liveness
                .drop
                .simulate_block(&mir, bb, |location, local_set| {
                    results.push((location, local_set.clone()));
                });
            results
        })
        .collect();

    mir_util::dump_mir(
        infcx.tcx,
        None,
        "nll",
        &0,
        source,
        mir,
        |pass_where, out| {
            match pass_where {
                // Before the CFG, dump out the values for each region variable.
                PassWhere::BeforeCFG => {
                    regioncx.dump_mir(out)?;

                    if let Some(closure_region_requirements) = closure_region_requirements {
                        writeln!(out, "|")?;
                        writeln!(out, "| Free Region Constraints")?;
                        for_each_region_constraint(closure_region_requirements, &mut |msg| {
                            writeln!(out, "| {}", msg)
                        })?;
                    }
                }

                // Before each basic block, dump out the values
                // that are live on entry to the basic block.
                PassWhere::BeforeBlock(bb) => {
                    let s = live_variable_set(&liveness.regular.ins[bb], &liveness.drop.ins[bb]);
                    writeln!(out, "    | Live variables on entry to {:?}: {}", bb, s)?;
                }

                PassWhere::BeforeLocation(location) => {
                    let s = live_variable_set(
                        &regular_liveness_per_location[&location],
                        &drop_liveness_per_location[&location],
                    );
                    writeln!(
                        out,
                        "{:ALIGN$} | Live variables on entry to {:?}: {}",
                        "",
                        location,
                        s,
                        ALIGN = ALIGN
                    )?;
                }

                PassWhere::AfterLocation(_) | PassWhere::AfterCFG => {}
            }
            Ok(())
        },
    );

    // Also dump the inference graph constraints as a graphviz file.
    let _: io::Result<()> = do catch {
        let mut file =
            pretty::create_dump_file(infcx.tcx, "regioncx.dot", None, "nll", &0, source)?;
        regioncx.dump_graphviz(&mut file)?;
    };
}

fn dump_annotation<'a, 'gcx, 'tcx>(
    infcx: &InferCtxt<'a, 'gcx, 'tcx>,
    mir: &Mir<'tcx>,
    mir_def_id: DefId,
    regioncx: &RegionInferenceContext,
    closure_region_requirements: &Option<ClosureRegionRequirements>,
) {
    let tcx = infcx.tcx;
    let base_def_id = tcx.closure_base_def_id(mir_def_id);
    if !tcx.has_attr(base_def_id, "rustc_regions") {
        return;
    }

    // When the enclosing function is tagged with `#[rustc_regions]`,
    // we dump out various bits of state as warnings. This is useful
    // for verifying that the compiler is behaving as expected.  These
    // warnings focus on the closure region requirements -- for
    // viewing the intraprocedural state, the -Zdump-mir output is
    // better.

    if let Some(closure_region_requirements) = closure_region_requirements {
        let mut err = tcx
            .sess
            .diagnostic()
            .span_note_diag(mir.span, "External requirements");

        regioncx.annotate(&mut err);

        err.note(&format!(
            "number of external vids: {}",
            closure_region_requirements.num_external_vids
        ));

        // Dump the region constraints we are imposing *between* those
        // newly created variables.
        for_each_region_constraint(closure_region_requirements, &mut |msg| {
            err.note(msg);
            Ok(())
        }).unwrap();

        err.emit();
    } else {
        let mut err = tcx
            .sess
            .diagnostic()
            .span_note_diag(mir.span, "No external requirements");
        regioncx.annotate(&mut err);
        err.emit();
    }
}

fn for_each_region_constraint(
    closure_region_requirements: &ClosureRegionRequirements,
    with_msg: &mut dyn FnMut(&str) -> io::Result<()>,
) -> io::Result<()> {
    for req in &closure_region_requirements.outlives_requirements {
        let subject: &dyn Debug = match &req.subject {
            ClosureOutlivesSubject::Region(subject) => subject,
            ClosureOutlivesSubject::Ty(ty) => ty,
        };
        with_msg(&format!(
            "where {:?}: {:?}",
            subject, req.outlived_free_region,
        ))?;
    }
    Ok(())
}

/// Right now, we piggy back on the `ReVar` to store our NLL inference
/// regions. These are indexed with `RegionVid`. This method will
/// assert that the region is a `ReVar` and extract its internal index.
/// This is reasonable because in our MIR we replace all universal regions
/// with inference variables.
pub trait ToRegionVid {
    fn to_region_vid(self) -> RegionVid;
}

impl<'tcx> ToRegionVid for &'tcx RegionKind {
    fn to_region_vid(self) -> RegionVid {
        if let ty::ReVar(vid) = self {
            *vid
        } else {
            bug!("region is not an ReVar: {:?}", self)
        }
    }
}

impl ToRegionVid for RegionVid {
    fn to_region_vid(self) -> RegionVid {
        self
    }
}

fn live_variable_set(regular: &LocalSet, drops: &LocalSet) -> String {
    // sort and deduplicate:
    let all_locals: BTreeSet<_> = regular.iter().chain(drops.iter()).collect();

    // construct a string with each local, including `(drop)` if it is
    // only dropped, versus a regular use.
    let mut string = String::new();
    for local in all_locals {
        string.push_str(&format!("{:?}", local));

        if !regular.contains(&local) {
            assert!(drops.contains(&local));
            string.push_str(" (drop)");
        }

        string.push_str(", ");
    }

    let len = if string.is_empty() {
        0
    } else {
        string.len() - 2
    };

    format!("[{}]", &string[..len])
}
<|endoftext|>


<commit_before>#![crate_name = "kernel"]
#![crate_type = "staticlib"]
#![no_std]
#![feature(no_std, asm, lang_items)]
#![feature(core)]

#[macro_use] extern crate core;
extern crate rlibc;

#[path = "arch/x86/"]
pub mod platform {
	pub mod vga;
	pub mod cpu;
	pub mod mmu;
	mod io;
	pub mod keyboard;
}

pub mod kernel {
	pub mod main;
	pub mod interrupts;
	mod stdio;
	mod keyboard;
}

// Remove this when https://github.com/rust-lang/rust/issues/21827 is solved
mod std {
    pub mod option {
        pub use core::option::*;
    }
    pub mod iter {
        pub use core::iter::*;
    }
}

#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
#[lang = "eh_personality"] extern fn eh_personality() {}
<commit_msg>rust-lang/rust#21827 is solved<commit_after>#![crate_name = "kernel"]
#![crate_type = "staticlib"]
#![no_std]
#![feature(no_std, asm, lang_items)]
#![feature(core)]

#[macro_use] extern crate core;
extern crate rlibc;

#[path = "arch/x86/"]
pub mod platform {
	pub mod vga;
	pub mod cpu;
	pub mod mmu;
	mod io;
	pub mod keyboard;
}

pub mod kernel {
	pub mod main;
	pub mod interrupts;
	mod stdio;
	mod keyboard;
}

#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
#[lang = "eh_personality"] extern fn eh_personality() {}
<|endoftext|>


<commit_before>use std::thread;
use std::net::SocketAddr;
use std::net::ToSocketAddrs;
use std::collections::HashMap;
use std::sync::mpsc;
use std::sync::Arc;
use std::sync::Mutex;
use std::io;

use tokio_core::reactor;
use tokio_core::net::TcpListener;

use futures;
use futures::Stream;
use futures::Future;

use solicit::http::HttpError;

use futures_misc::*;
use solicit_async::*;

use super::server_conn::*;
use super::http_common::*;

struct LoopToServer {
    // used only once to send shutdown signal
    shutdown_tx: futures::sync::mpsc::UnboundedSender<()>,
    local_addr: SocketAddr,
}

pub struct Http2Server {
    state: Arc<Mutex<HttpServerState>>,
    loop_to_server: LoopToServer,
    thread_join_handle: Option<thread::JoinHandle<()>>,
}

struct ConnHandle {
}

#[derive(Default)]
struct HttpServerState {
    last_conn_id: u64,
    conns: HashMap<u64, ConnHandle>,
}

impl HttpServerState {
    fn snapshot(&self) -> HttpFutureSend<HttpServerStateSnapshot> {
        Box::new(futures::finished(HttpServerStateSnapshot {
            conns: self.conns.iter().map(|(&id, _h)| (id, ())).collect()
        }))
    }
}

pub struct HttpServerStateSnapshot {
    pub conns: HashMap<u64, ()>,
}

fn run_server_event_loop<S>(
    listen_addr: SocketAddr,
    state: Arc<Mutex<HttpServerState>>,
    service: S,
    send_to_back: mpsc::Sender<LoopToServer>)
        where S : HttpService,
{
    let service = Arc::new(service);

    let mut lp = reactor::Core::new().expect("http2server");

    let (shutdown_tx, shutdown_rx) = futures::sync::mpsc::unbounded();

    let shutdown_rx = shutdown_rx.map_err(|()| HttpError::IoError(io::Error::new(io::ErrorKind::Other, "shutdown_rx")));

    let listen = TcpListener::bind(&listen_addr, &lp.handle()).unwrap();

    let stuff = stream_repeat((lp.handle(), service, state));

    let local_addr = listen.local_addr().unwrap();
    send_to_back
        .send(LoopToServer { shutdown_tx: shutdown_tx, local_addr: local_addr })
        .expect("send back");

    let loop_run = listen.incoming().map_err(HttpError::from).zip(stuff).for_each(move |((socket, peer_addr), (loop_handle, service, state))| {
        let conn_id = {
            let mut g = state.lock().expect("lock");
            g.last_conn_id += 1;
            let conn_id = g.last_conn_id;
            let prev = g.conns.insert(conn_id, ConnHandle {
            });
            assert!(prev.is_none());
            conn_id
        };
        info!("accepted connection from {}", peer_addr);
        loop_handle.spawn(HttpServerConnectionAsync::new_plain(&loop_handle, socket, service).1
            .then(move |r| {
                let mut g = state.lock().expect("lock");
                let removed = g.conns.remove(&conn_id);
                assert!(removed.is_some());
                r
            })
            .map_err(|e| { warn!("connection end: {:?}", e); () }));
        Ok(())
    });

    let shutdown = shutdown_rx.into_future().map_err(|(e, _)| HttpError::from(e)).and_then(|_| {
        // Must complete with error,
        // so `join` with this future cancels another future.
        futures::failed::<(), _>(HttpError::IoError(io::Error::new(io::ErrorKind::Other, "shutdown_rx")))
    });

    // Wait for either completion of connection (i. e. error)
    // or shutdown signal.
    let done = loop_run.join(shutdown);

    // TODO: do not ignore error
    lp.run(done).ok();
}

impl Http2Server {
    pub fn new<S>(port: u16, service: S) -> Http2Server
        where S : HttpService
    {
        let listen_addr = ("::", port).to_socket_addrs().unwrap().next().unwrap();

        let (get_from_loop_tx, get_from_loop_rx) = mpsc::channel();

        let state: Arc<Mutex<HttpServerState>> = Default::default();

        let state_copy = state.clone();

        let join_handle = thread::spawn(move || {
            run_server_event_loop(listen_addr, state_copy, service, get_from_loop_tx);
        });

        let loop_to_server = get_from_loop_rx.recv().unwrap();

        Http2Server {
            state: state,
            loop_to_server: loop_to_server,
            thread_join_handle: Some(join_handle),
        }
    }

    pub fn local_addr(&self) -> &SocketAddr {
        &self.loop_to_server.local_addr
    }

    // for tests
    pub fn dump_state(&self) -> HttpFutureSend<HttpServerStateSnapshot> {
        let g = self.state.lock().expect("lock");
        g.snapshot()
    }
}

// We shutdown the server in the destructor.
impl Drop for Http2Server {
    fn drop(&mut self) {
        // ignore error because even loop may be already dead
        self.loop_to_server.shutdown_tx.send(()).ok();

        // do not ignore errors of take
        // ignore errors of join, it means that server event loop crashed
        drop(self.thread_join_handle.take().unwrap().join());
    }
}

<commit_msg>dump server all connection states<commit_after>use std::thread;
use std::net::SocketAddr;
use std::net::ToSocketAddrs;
use std::collections::HashMap;
use std::sync::mpsc;
use std::sync::Arc;
use std::sync::Mutex;
use std::io;

use tokio_core::reactor;
use tokio_core::net::TcpListener;

use futures;
use futures::Stream;
use futures::Future;
use futures::future::join_all;

use solicit::http::HttpError;

use futures_misc::*;
use solicit_async::*;

use super::server_conn::*;
use super::http_common::*;

struct LoopToServer {
    // used only once to send shutdown signal
    shutdown_tx: futures::sync::mpsc::UnboundedSender<()>,
    local_addr: SocketAddr,
}

pub struct Http2Server {
    state: Arc<Mutex<HttpServerState>>,
    loop_to_server: LoopToServer,
    thread_join_handle: Option<thread::JoinHandle<()>>,
}

#[derive(Default)]
struct HttpServerState {
    last_conn_id: u64,
    conns: HashMap<u64, HttpServerConnectionAsync>,
}

impl HttpServerState {
    fn snapshot(&self) -> HttpFutureSend<HttpServerStateSnapshot> {
        let futures: Vec<_> = self.conns.iter()
            .map(|(&id, conn)| conn.dump_state().map(move |state| (id, state)))
            .collect();

        Box::new(join_all(futures)
            .map(|states| HttpServerStateSnapshot {
                conns: states.into_iter().collect(),
            }))
    }
}

pub struct HttpServerStateSnapshot {
    pub conns: HashMap<u64, ConnectionStateSnapshot>,
}

fn run_server_event_loop<S>(
    listen_addr: SocketAddr,
    state: Arc<Mutex<HttpServerState>>,
    service: S,
    send_to_back: mpsc::Sender<LoopToServer>)
        where S : HttpService,
{
    let service = Arc::new(service);

    let mut lp = reactor::Core::new().expect("http2server");

    let (shutdown_tx, shutdown_rx) = futures::sync::mpsc::unbounded();

    let shutdown_rx = shutdown_rx.map_err(|()| HttpError::IoError(io::Error::new(io::ErrorKind::Other, "shutdown_rx")));

    let listen = TcpListener::bind(&listen_addr, &lp.handle()).unwrap();

    let stuff = stream_repeat((lp.handle(), service, state));

    let local_addr = listen.local_addr().unwrap();
    send_to_back
        .send(LoopToServer { shutdown_tx: shutdown_tx, local_addr: local_addr })
        .expect("send back");

    let loop_run = listen.incoming().map_err(HttpError::from).zip(stuff).for_each(move |((socket, peer_addr), (loop_handle, service, state))| {
        info!("accepted connection from {}", peer_addr);

        let (conn, future) = HttpServerConnectionAsync::new_plain(&loop_handle, socket, service);

        let conn_id = {
            let mut g = state.lock().expect("lock");
            g.last_conn_id += 1;
            let conn_id = g.last_conn_id;
            let prev = g.conns.insert(conn_id, conn);
            assert!(prev.is_none());
            conn_id
        };

        loop_handle.spawn(future
            .then(move |r| {
                let mut g = state.lock().expect("lock");
                let removed = g.conns.remove(&conn_id);
                assert!(removed.is_some());
                r
            })
            .map_err(|e| { warn!("connection end: {:?}", e); () }));
        Ok(())
    });

    let shutdown = shutdown_rx.into_future().map_err(|(e, _)| HttpError::from(e)).and_then(|_| {
        // Must complete with error,
        // so `join` with this future cancels another future.
        futures::failed::<(), _>(HttpError::IoError(io::Error::new(io::ErrorKind::Other, "shutdown_rx")))
    });

    // Wait for either completion of connection (i. e. error)
    // or shutdown signal.
    let done = loop_run.join(shutdown);

    // TODO: do not ignore error
    lp.run(done).ok();
}

impl Http2Server {
    pub fn new<S>(port: u16, service: S) -> Http2Server
        where S : HttpService
    {
        let listen_addr = ("::", port).to_socket_addrs().unwrap().next().unwrap();

        let (get_from_loop_tx, get_from_loop_rx) = mpsc::channel();

        let state: Arc<Mutex<HttpServerState>> = Default::default();

        let state_copy = state.clone();

        let join_handle = thread::spawn(move || {
            run_server_event_loop(listen_addr, state_copy, service, get_from_loop_tx);
        });

        let loop_to_server = get_from_loop_rx.recv().unwrap();

        Http2Server {
            state: state,
            loop_to_server: loop_to_server,
            thread_join_handle: Some(join_handle),
        }
    }

    pub fn local_addr(&self) -> &SocketAddr {
        &self.loop_to_server.local_addr
    }

    // for tests
    pub fn dump_state(&self) -> HttpFutureSend<HttpServerStateSnapshot> {
        let g = self.state.lock().expect("lock");
        g.snapshot()
    }
}

// We shutdown the server in the destructor.
impl Drop for Http2Server {
    fn drop(&mut self) {
        // ignore error because even loop may be already dead
        self.loop_to_server.shutdown_tx.send(()).ok();

        // do not ignore errors of take
        // ignore errors of join, it means that server event loop crashed
        drop(self.thread_join_handle.take().unwrap().join());
    }
}

<|endoftext|>


<commit_before>use std::iter::repeat;
use std::io::Read;
use byteorder::ReadBytesExt;

use image;
use image::ImageResult;

#[derive(Default, Clone)]
pub struct HuffTable {
    lut: Vec<(u8, u8)>,
    valptr: Vec<isize>,
    huffval: Vec<u8>,
    maxcode: Vec<isize>,
    mincode: Vec<isize>,
}

pub struct HuffDecoder {
    pub bits: u32,
    pub num_bits: u8,
    pub end: bool,
    pub marker: u8,
}

impl HuffDecoder {
    pub fn new() -> HuffDecoder {
        HuffDecoder {
            bits: 0,
            num_bits: 0,
            end: false,
            marker: 0
        }
    }

    fn guarantee<R: Read>(&mut self, r: &mut R, n: u8) -> ImageResult<()> {
        while self.num_bits < n && !self.end {
            let byte = try!(r.read_u8());

            if byte == 0xFF {
                let byte2 = try!(r.read_u8());
                if byte2 != 0 {
                    self.marker = byte2;
                    self.end = true;
                }
            }

            self.bits |= ((byte as u32) << (32 - 8)) >> self.num_bits as usize;
            self.num_bits += 8;
        }

        Ok(())
    }

    pub fn read_bit<R: Read>(&mut self, r: &mut R) -> ImageResult<u8> {
        let _   = try!(self.guarantee(r, 1));
        let bit = (self.bits & (1 << 31)) >> 31;
        self.consume(1);

        Ok(bit as u8)
    }

    // Section F.2.2.4
    // Figure F.17
    pub fn receive<R: Read>(&mut self, r: &mut R, ssss: u8) -> ImageResult<i32> {
        let _ = try!(self.guarantee(r, ssss));
        let bits = (self.bits & (0xFFFFFFFFu32 << (32 - ssss as usize))) >> (32 - ssss) as usize;
        self.consume(ssss);

        Ok(bits as i32)
    }

    fn consume(&mut self, n: u8) {
        self.bits <<= n as usize;
        self.num_bits -= n;
    }

    pub fn decode_symbol<R: Read>(&mut self, r: &mut R, table: &HuffTable) -> ImageResult<u8> {
        let _ = try!(self.guarantee(r, 8));

        let index = (self.bits & 0xFF000000) >> (32 - 8);
        let (val, size) = table.lut[index as usize];

        if index < 256 && size < 9 {
        self.consume(size);
            Ok(val)
        } else {
            let mut code = 0usize;

            for i in (0usize..16) {
                let b = try!(self.read_bit(r));
                code |= b as usize;

                if (code as isize) <= table.maxcode[i] {
                    let index = table.valptr[i] +
                                code as isize -
                                table.mincode[i];

                    return Ok(table.huffval[index as usize])
                }

                code <<= 1;
            }

            Err(image::ImageError::FormatError("Could not decode symbol.".to_string()))
        }
    }
}

/// Given an array containing the number of codes of each code length,
/// this function generates the huffman codes lengths and their respective
/// code lengths as specified by the JPEG spec.
fn derive_codes_and_sizes(bits: &[u8]) -> (Vec<u8>, Vec<u16>) {
    let mut huffsize = repeat(0u8).take(256).collect::<Vec<u8>>();
    let mut huffcode = repeat(0u16).take(256).collect::<Vec<u16>>();

    let mut k = 0;
    let mut j;

    // Annex C.2
    // Figure C.1
    // Generate table of individual code lengths
    for i in (0usize..16) {
        j = 0;

        while j < bits[i] {
            huffsize[k] = i as u8 + 1;
            k += 1;
            j += 1;
        }
    }

    huffsize[k] = 0;

    // Annex C.2
    // Figure C.2
    // Generate table of huffman codes
    k = 0;
    let mut code = 0u16;
    let mut size = huffsize[0];

    while huffsize[k] != 0 {
        huffcode[k] = code;
        code += 1;
        k += 1;

        if huffsize[k] == size {
            continue
        }

        // FIXME there is something wrong with this code
        let diff = huffsize[k].wrapping_sub(size);
        code <<= diff as usize;

        size = size.wrapping_add(diff)
    }

    (huffsize, huffcode)
}

pub fn build_huff_lut(bits: &[u8], huffval: &[u8]) -> Vec<(u8, u16)> {
    let mut lut = repeat((17u8, 0u16)).take(256).collect::<Vec<(u8, u16)>>();
    let (huffsize, huffcode) = derive_codes_and_sizes(bits);

    for (i, &v) in huffval.iter().enumerate() {
        lut[v as usize] = (huffsize[i], huffcode[i]);
    }

    lut
}

pub fn derive_tables(bits: Vec<u8>, huffval: Vec<u8>) -> HuffTable {
    let mut mincode = repeat(-1isize).take(16).collect::<Vec<isize>>();
    let mut maxcode = repeat(-1isize).take(16).collect::<Vec<isize>>();
    let mut valptr  = repeat(-1isize).take(16).collect::<Vec<isize>>();
    let mut lut     = repeat((0u8, 17u8)).take(256).collect::<Vec<(u8, u8)>>();

    let (huffsize, huffcode) = derive_codes_and_sizes(&bits);

    // Annex F.2.2.3
    // Figure F.15
    let mut j = 0;

    for i in (0usize..16) {
        if bits[i] != 0 {
            valptr[i] = j;
            mincode[i] = huffcode[j as usize] as isize;
            j += bits[i] as isize - 1;
            maxcode[i] = huffcode[j as usize] as isize;

            j += 1;
        }
    }

    for (i, v) in huffval.iter().enumerate() {
        if huffsize[i] > 8 {
            break
        }

        let r = 8 - huffsize[i] as usize;

        for j in (0usize..1 << r) {
            let index = (huffcode[i] << r) + j as u16;
            lut[index as usize] = (*v, huffsize[i]);
        }
    }

    HuffTable {
        lut: lut,
        huffval: huffval,
        maxcode: maxcode,
        mincode: mincode,
        valptr: valptr
    }
}
<commit_msg>Fix JPG overflow on debug builds<commit_after>use std::iter::repeat;
use std::io::Read;
use byteorder::ReadBytesExt;

use image;
use image::ImageResult;

#[derive(Default, Clone)]
pub struct HuffTable {
    lut: Vec<(u8, u8)>,
    valptr: Vec<isize>,
    huffval: Vec<u8>,
    maxcode: Vec<isize>,
    mincode: Vec<isize>,
}

pub struct HuffDecoder {
    pub bits: u32,
    pub num_bits: u8,
    pub end: bool,
    pub marker: u8,
}

impl HuffDecoder {
    pub fn new() -> HuffDecoder {
        HuffDecoder {
            bits: 0,
            num_bits: 0,
            end: false,
            marker: 0
        }
    }

    fn guarantee<R: Read>(&mut self, r: &mut R, n: u8) -> ImageResult<()> {
        while self.num_bits < n && !self.end {
            let byte = try!(r.read_u8());

            if byte == 0xFF {
                let byte2 = try!(r.read_u8());
                if byte2 != 0 {
                    self.marker = byte2;
                    self.end = true;
                }
            }

            self.bits |= ((byte as u32) << (32 - 8)) >> self.num_bits as usize;
            self.num_bits += 8;
        }

        Ok(())
    }

    pub fn read_bit<R: Read>(&mut self, r: &mut R) -> ImageResult<u8> {
        let _   = try!(self.guarantee(r, 1));
        let bit = (self.bits & (1 << 31)) >> 31;
        self.consume(1);

        Ok(bit as u8)
    }

    // Section F.2.2.4
    // Figure F.17
    pub fn receive<R: Read>(&mut self, r: &mut R, ssss: u8) -> ImageResult<i32> {
        let _ = try!(self.guarantee(r, ssss));
        let bits = (self.bits & (0xFFFFFFFFu32 << (32 - ssss as usize))) >> (32 - ssss) as usize;
        self.consume(ssss);

        Ok(bits as i32)
    }

    fn consume(&mut self, n: u8) {
        self.bits <<= n as usize;
        self.num_bits -= n;
    }

    pub fn decode_symbol<R: Read>(&mut self, r: &mut R, table: &HuffTable) -> ImageResult<u8> {
        let _ = try!(self.guarantee(r, 8));

        let index = (self.bits & 0xFF000000) >> (32 - 8);
        let (val, size) = table.lut[index as usize];

        if index < 256 && size < 9 {
        self.consume(size);
            Ok(val)
        } else {
            let mut code = 0usize;

            for i in (0usize..16) {
                let b = try!(self.read_bit(r));
                code |= b as usize;

                if (code as isize) <= table.maxcode[i] {
                    let index = table.valptr[i] +
                                code as isize -
                                table.mincode[i];

                    return Ok(table.huffval[index as usize])
                }

                code <<= 1;
            }

            Err(image::ImageError::FormatError("Could not decode symbol.".to_string()))
        }
    }
}

/// Given an array containing the number of codes of each code length,
/// this function generates the huffman codes lengths and their respective
/// code lengths as specified by the JPEG spec.
fn derive_codes_and_sizes(bits: &[u8]) -> (Vec<u8>, Vec<u16>) {
    let mut huffsize = repeat(0u8).take(256).collect::<Vec<u8>>();
    let mut huffcode = repeat(0u16).take(256).collect::<Vec<u16>>();

    let mut k = 0;
    let mut j;

    // Annex C.2
    // Figure C.1
    // Generate table of individual code lengths
    for i in (0usize..16) {
        j = 0;

        while j < bits[i] {
            huffsize[k] = i as u8 + 1;
            k += 1;
            j += 1;
        }
    }

    huffsize[k] = 0;

    // Annex C.2
    // Figure C.2
    // Generate table of huffman codes
    k = 0;
    let mut code = 0u16;
    let mut size = huffsize[0];

    while huffsize[k] != 0 {
        huffcode[k] = code;
        code += 1;
        k += 1;

        if huffsize[k] == size {
            continue
        }

        // FIXME there is something wrong with this code
        let diff = huffsize[k].wrapping_sub(size);
        code = if diff < 16  { code << diff as usize } else { 0 };

        size = size.wrapping_add(diff);
    }

    (huffsize, huffcode)
}

pub fn build_huff_lut(bits: &[u8], huffval: &[u8]) -> Vec<(u8, u16)> {
    let mut lut = repeat((17u8, 0u16)).take(256).collect::<Vec<(u8, u16)>>();
    let (huffsize, huffcode) = derive_codes_and_sizes(bits);

    for (i, &v) in huffval.iter().enumerate() {
        lut[v as usize] = (huffsize[i], huffcode[i]);
    }

    lut
}

pub fn derive_tables(bits: Vec<u8>, huffval: Vec<u8>) -> HuffTable {
    let mut mincode = repeat(-1isize).take(16).collect::<Vec<isize>>();
    let mut maxcode = repeat(-1isize).take(16).collect::<Vec<isize>>();
    let mut valptr  = repeat(-1isize).take(16).collect::<Vec<isize>>();
    let mut lut     = repeat((0u8, 17u8)).take(256).collect::<Vec<(u8, u8)>>();

    let (huffsize, huffcode) = derive_codes_and_sizes(&bits);

    // Annex F.2.2.3
    // Figure F.15
    let mut j = 0;

    for i in (0usize..16) {
        if bits[i] != 0 {
            valptr[i] = j;
            mincode[i] = huffcode[j as usize] as isize;
            j += bits[i] as isize - 1;
            maxcode[i] = huffcode[j as usize] as isize;

            j += 1;
        }
    }

    for (i, v) in huffval.iter().enumerate() {
        if huffsize[i] > 8 {
            break
        }

        let r = 8 - huffsize[i] as usize;

        for j in (0usize..1 << r) {
            let index = (huffcode[i] << r) + j as u16;
            lut[index as usize] = (*v, huffsize[i]);
        }
    }

    HuffTable {
        lut: lut,
        huffval: huffval,
        maxcode: maxcode,
        mincode: mincode,
        valptr: valptr
    }
}
<|endoftext|>