<commit_before>use stats::LogProb;

pub mod evidence {
    /// Scale of evidence as defined by
    /// [Kass and Raftery 1995](http://www.andrew.cmu.edu/user/kk3n/simplicity/KassRaftery1995.pdf).
    #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, EnumString, EnumIter)]
    #[strum(serialize_all = "snake_case")]
    pub enum KassRaftery {
        None,
        Barely,
        Positive,
        Strong,
        #[strum(serialize = "very-strong")]
        VeryStrong,
    }
}

custom_derive! {
    /// A newtype for Bayes factors.
    #[derive(
        NewtypeFrom,
        NewtypeDeref,
        PartialEq,
        PartialOrd,
        Copy,
        Clone,
        Debug,
    )]
    pub struct BayesFactor(pub f64);
}

impl BayesFactor {
    /// Calculate Bayes factor from given probabilities.
    pub fn new(a: LogProb, b: LogProb) -> Self {
        BayesFactor((a - b).exp())
    }

    /// Calculate strength of evidence as defined by
    /// [Kass and Raftery 1995](http://www.andrew.cmu.edu/user/kk3n/simplicity/KassRaftery1995.pdf).
    pub fn evidence_kass_raftery(&self) -> evidence::KassRaftery {
        let k = **self;
        if k >= 1.0 && k <= 3.0 {
            evidence::KassRaftery::Barely
        } else if k <= 20.0 {
            evidence::KassRaftery::Positive
        } else if k <= 150.0 {
            evidence::KassRaftery::Strong
        } else {
            evidence::KassRaftery::VeryStrong
        }
    }
}

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

    #[test]
    fn test_bayes_factor() {
        let bf = BayesFactor::new(LogProb(0.5_f64.ln()), LogProb(0.1_f64.ln()));
        assert_relative_eq!(*bf, 5.0, epsilon = 1e-9);
        assert_eq!(bf.evidence_kass_raftery(), evidence::KassRaftery::Positive);
    }
}
<commit_msg>derive display<commit_after>use stats::LogProb;

pub mod evidence {
    /// Scale of evidence as defined by
    /// [Kass and Raftery 1995](http://www.andrew.cmu.edu/user/kk3n/simplicity/KassRaftery1995.pdf).
    #[derive(Display, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, EnumString, EnumIter)]
    #[strum(serialize_all = "snake_case")]
    pub enum KassRaftery {
        None,
        Barely,
        Positive,
        Strong,
        #[strum(serialize = "very-strong")]
        VeryStrong,
    }
}

custom_derive! {
    /// A newtype for Bayes factors.
    #[derive(
        NewtypeFrom,
        NewtypeDeref,
        PartialEq,
        PartialOrd,
        Copy,
        Clone,
        Debug,
    )]
    pub struct BayesFactor(pub f64);
}

impl BayesFactor {
    /// Calculate Bayes factor from given probabilities.
    pub fn new(a: LogProb, b: LogProb) -> Self {
        BayesFactor((a - b).exp())
    }

    /// Calculate strength of evidence as defined by
    /// [Kass and Raftery 1995](http://www.andrew.cmu.edu/user/kk3n/simplicity/KassRaftery1995.pdf).
    pub fn evidence_kass_raftery(&self) -> evidence::KassRaftery {
        let k = **self;
        if k >= 1.0 && k <= 3.0 {
            evidence::KassRaftery::Barely
        } else if k <= 20.0 {
            evidence::KassRaftery::Positive
        } else if k <= 150.0 {
            evidence::KassRaftery::Strong
        } else {
            evidence::KassRaftery::VeryStrong
        }
    }
}

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

    #[test]
    fn test_bayes_factor() {
        let bf = BayesFactor::new(LogProb(0.5_f64.ln()), LogProb(0.1_f64.ln()));
        assert_relative_eq!(*bf, 5.0, epsilon = 1e-9);
        assert_eq!(bf.evidence_kass_raftery(), evidence::KassRaftery::Positive);
    }
}
<|endoftext|>


<commit_before>//! Abstractions for page tables and page table entries.

use core::fmt;
use core::ops::{Index, IndexMut};

use super::{PageSize, PhysFrame, Size4KiB};
use crate::addr::PhysAddr;

use bitflags::bitflags;

/// The error returned by the `PageTableEntry::frame` method.
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum FrameError {
    /// The entry does not have the `PRESENT` flag set, so it isn't currently mapped to a frame.
    FrameNotPresent,
    /// The entry does have the `HUGE_PAGE` flag set. The `frame` method has a standard 4KiB frame
    /// as return type, so a huge frame can't be returned.
    HugeFrame,
}

/// A 64-bit page table entry.
#[derive(Clone)]
#[repr(transparent)]
pub struct PageTableEntry {
    entry: u64,
}

impl PageTableEntry {
    /// Creates an unused page table entry.
    #[inline]
    pub const fn new() -> Self {
        PageTableEntry { entry: 0 }
    }

    /// Returns whether this entry is zero.
    #[inline]
    pub const fn is_unused(&self) -> bool {
        self.entry == 0
    }

    /// Sets this entry to zero.
    #[inline]
    pub fn set_unused(&mut self) {
        self.entry = 0;
    }

    /// Returns the flags of this entry.
    #[inline]
    pub const fn flags(&self) -> PageTableFlags {
        PageTableFlags::from_bits_truncate(self.entry)
    }

    /// Returns the physical address mapped by this entry, might be zero.
    #[inline]
    pub fn addr(&self) -> PhysAddr {
        PhysAddr::new(self.entry & 0x000fffff_fffff000)
    }

    /// Returns the physical frame mapped by this entry.
    ///
    /// Returns the following errors:
    ///
    /// - `FrameError::FrameNotPresent` if the entry doesn't have the `PRESENT` flag set.
    /// - `FrameError::HugeFrame` if the entry has the `HUGE_PAGE` flag set (for huge pages the
    ///    `addr` function must be used)
    #[inline]
    pub fn frame(&self) -> Result<PhysFrame, FrameError> {
        if !self.flags().contains(PageTableFlags::PRESENT) {
            Err(FrameError::FrameNotPresent)
        } else if self.flags().contains(PageTableFlags::HUGE_PAGE) {
            Err(FrameError::HugeFrame)
        } else {
            Ok(PhysFrame::containing_address(self.addr()))
        }
    }

    /// Map the entry to the specified physical address with the specified flags.
    #[inline]
    pub fn set_addr(&mut self, addr: PhysAddr, flags: PageTableFlags) {
        assert!(addr.is_aligned(Size4KiB::SIZE));
        self.entry = (addr.as_u64()) | flags.bits();
    }

    /// Map the entry to the specified physical frame with the specified flags.
    #[inline]
    pub fn set_frame(&mut self, frame: PhysFrame, flags: PageTableFlags) {
        assert!(!flags.contains(PageTableFlags::HUGE_PAGE));
        self.set_addr(frame.start_address(), flags)
    }

    /// Sets the flags of this entry.
    #[inline]
    pub fn set_flags(&mut self, flags: PageTableFlags) {
        self.entry = self.addr().as_u64() | flags.bits();
    }
}

impl fmt::Debug for PageTableEntry {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let mut f = f.debug_struct("PageTableEntry");
        f.field("addr", &self.addr());
        f.field("flags", &self.flags());
        f.finish()
    }
}

bitflags! {
    /// Possible flags for a page table entry.
    pub struct PageTableFlags: u64 {
        /// Specifies whether the mapped frame or page table is loaded in memory.
        const PRESENT =         1;
        /// Controls whether writes to the mapped frames are allowed.
        ///
        /// If this bit is unset in a level 1 page table entry, the mapped frame is read-only.
        /// If this bit is unset in a higher level page table entry the complete range of mapped
        /// pages is read-only.
        const WRITABLE =        1 << 1;
        /// Controls whether accesses from userspace (i.e. ring 3) are permitted.
        const USER_ACCESSIBLE = 1 << 2;
        /// If this bit is set, a “write-through” policy is used for the cache, else a “write-back”
        /// policy is used.
        const WRITE_THROUGH =   1 << 3;
        /// Disables caching for the pointed entry is cacheable.
        const NO_CACHE =        1 << 4;
        /// Set by the CPU when the mapped frame or page table is accessed.
        const ACCESSED =        1 << 5;
        /// Set by the CPU on a write to the mapped frame.
        const DIRTY =           1 << 6;
        /// Specifies that the entry maps a huge frame instead of a page table. Only allowed in
        /// P2 or P3 tables.
        const HUGE_PAGE =       1 << 7;
        /// Indicates that the mapping is present in all address spaces, so it isn't flushed from
        /// the TLB on an address space switch.
        const GLOBAL =          1 << 8;
        /// Available to the OS, can be used to store additional data, e.g. custom flags.
        const BIT_9 =           1 << 9;
        /// Available to the OS, can be used to store additional data, e.g. custom flags.
        const BIT_10 =          1 << 10;
        /// Available to the OS, can be used to store additional data, e.g. custom flags.
        const BIT_11 =          1 << 11;
        /// Available to the OS, can be used to store additional data, e.g. custom flags.
        const BIT_52 =          1 << 52;
        /// Available to the OS, can be used to store additional data, e.g. custom flags.
        const BIT_53 =          1 << 53;
        /// Available to the OS, can be used to store additional data, e.g. custom flags.
        const BIT_54 =          1 << 54;
        /// Available to the OS, can be used to store additional data, e.g. custom flags.
        const BIT_55 =          1 << 55;
        /// Available to the OS, can be used to store additional data, e.g. custom flags.
        const BIT_56 =          1 << 56;
        /// Available to the OS, can be used to store additional data, e.g. custom flags.
        const BIT_57 =          1 << 57;
        /// Available to the OS, can be used to store additional data, e.g. custom flags.
        const BIT_58 =          1 << 58;
        /// Available to the OS, can be used to store additional data, e.g. custom flags.
        const BIT_59 =          1 << 59;
        /// Available to the OS, can be used to store additional data, e.g. custom flags.
        const BIT_60 =          1 << 60;
        /// Available to the OS, can be used to store additional data, e.g. custom flags.
        const BIT_61 =          1 << 61;
        /// Available to the OS, can be used to store additional data, e.g. custom flags.
        const BIT_62 =          1 << 62;
        /// Forbid code execution from the mapped frames.
        ///
        /// Can be only used when the no-execute page protection feature is enabled in the EFER
        /// register.
        const NO_EXECUTE =      1 << 63;
    }
}

/// The number of entries in a page table.
const ENTRY_COUNT: usize = 512;

/// Represents a page table.
///
/// Always page-sized.
///
/// This struct implements the `Index` and `IndexMut` traits, so the entries can be accessed
/// through index operations. For example, `page_table[15]` returns the 15th page table entry.
#[repr(align(4096))]
#[repr(C)]
pub struct PageTable {
    entries: [PageTableEntry; ENTRY_COUNT],
}

impl PageTable {
    /// Creates an empty page table.
    #[cfg(feature = "const_fn")]
    #[inline]
    pub const fn new() -> Self {
        const EMPTY: PageTableEntry = PageTableEntry::new();
        PageTable {
            entries: [EMPTY; ENTRY_COUNT],
        }
    }

    #[cfg(not(feature = "const_fn"))]
    #[inline]
    pub fn new() -> Self {
        const EMPTY: PageTableEntry = PageTableEntry::new();
        PageTable {
            entries: [EMPTY; ENTRY_COUNT],
        }
    }

    /// Clears all entries.
    #[inline]
    pub fn zero(&mut self) {
        for entry in self.entries.iter_mut() {
            entry.set_unused();
        }
    }

    /// Returns an iterator over the entries of the page table.
    #[inline]
    pub fn iter(&self) -> impl Iterator<Item = &PageTableEntry> {
        self.entries.iter()
    }

    /// Returns an iterator that allows modifying the entries of the page table.
    #[inline]
    pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut PageTableEntry> {
        self.entries.iter_mut()
    }
}

impl Index<usize> for PageTable {
    type Output = PageTableEntry;

    #[inline]
    fn index(&self, index: usize) -> &Self::Output {
        &self.entries[index]
    }
}

impl IndexMut<usize> for PageTable {
    #[inline]
    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
        &mut self.entries[index]
    }
}

impl Index<PageTableIndex> for PageTable {
    type Output = PageTableEntry;

    #[inline]
    fn index(&self, index: PageTableIndex) -> &Self::Output {
        &self.entries[usize::from(index)]
    }
}

impl IndexMut<PageTableIndex> for PageTable {
    #[inline]
    fn index_mut(&mut self, index: PageTableIndex) -> &mut Self::Output {
        &mut self.entries[usize::from(index)]
    }
}

impl Default for PageTable {
    fn default() -> Self {
        Self::new()
    }
}

impl fmt::Debug for PageTable {
    #[inline]
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.entries[..].fmt(f)
    }
}

/// A 9-bit index into a page table.
///
/// Can be used to select one of the 512 entries of a page table.
///
/// Guaranteed to only ever contain 0..512.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct PageTableIndex(u16);

impl PageTableIndex {
    /// Creates a new index from the given `u16`. Panics if the given value is >=512.
    #[inline]
    pub fn new(index: u16) -> Self {
        assert!(usize::from(index) < ENTRY_COUNT);
        Self(index)
    }

    /// Creates a new index from the given `u16`. Throws away bits if the value is >=512.
    #[inline]
    pub const fn new_truncate(index: u16) -> Self {
        Self(index % ENTRY_COUNT as u16)
    }
}

impl From<PageTableIndex> for u16 {
    #[inline]
    fn from(index: PageTableIndex) -> Self {
        index.0
    }
}

impl From<PageTableIndex> for u32 {
    #[inline]
    fn from(index: PageTableIndex) -> Self {
        u32::from(index.0)
    }
}

impl From<PageTableIndex> for u64 {
    #[inline]
    fn from(index: PageTableIndex) -> Self {
        u64::from(index.0)
    }
}

impl From<PageTableIndex> for usize {
    #[inline]
    fn from(index: PageTableIndex) -> Self {
        usize::from(index.0)
    }
}

/// A 12-bit offset into a 4KiB Page.
///
/// This type is returned by the `VirtAddr::page_offset` method.
///
/// Guaranteed to only ever contain 0..4096.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct PageOffset(u16);

impl PageOffset {
    /// Creates a new offset from the given `u16`. Panics if the passed value is >=4096.
    #[inline]
    pub fn new(offset: u16) -> Self {
        assert!(offset < (1 << 12));
        Self(offset)
    }

    /// Creates a new offset from the given `u16`. Throws away bits if the value is >=4096.
    #[inline]
    pub const fn new_truncate(offset: u16) -> Self {
        Self(offset % (1 << 12))
    }
}

impl From<PageOffset> for u16 {
    #[inline]
    fn from(offset: PageOffset) -> Self {
        offset.0
    }
}

impl From<PageOffset> for u32 {
    #[inline]
    fn from(offset: PageOffset) -> Self {
        u32::from(offset.0)
    }
}

impl From<PageOffset> for u64 {
    #[inline]
    fn from(offset: PageOffset) -> Self {
        u64::from(offset.0)
    }
}

impl From<PageOffset> for usize {
    #[inline]
    fn from(offset: PageOffset) -> Self {
        usize::from(offset.0)
    }
}
<commit_msg>Group hex literal by four to resolve clippy warning<commit_after>//! Abstractions for page tables and page table entries.

use core::fmt;
use core::ops::{Index, IndexMut};

use super::{PageSize, PhysFrame, Size4KiB};
use crate::addr::PhysAddr;

use bitflags::bitflags;

/// The error returned by the `PageTableEntry::frame` method.
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum FrameError {
    /// The entry does not have the `PRESENT` flag set, so it isn't currently mapped to a frame.
    FrameNotPresent,
    /// The entry does have the `HUGE_PAGE` flag set. The `frame` method has a standard 4KiB frame
    /// as return type, so a huge frame can't be returned.
    HugeFrame,
}

/// A 64-bit page table entry.
#[derive(Clone)]
#[repr(transparent)]
pub struct PageTableEntry {
    entry: u64,
}

impl PageTableEntry {
    /// Creates an unused page table entry.
    #[inline]
    pub const fn new() -> Self {
        PageTableEntry { entry: 0 }
    }

    /// Returns whether this entry is zero.
    #[inline]
    pub const fn is_unused(&self) -> bool {
        self.entry == 0
    }

    /// Sets this entry to zero.
    #[inline]
    pub fn set_unused(&mut self) {
        self.entry = 0;
    }

    /// Returns the flags of this entry.
    #[inline]
    pub const fn flags(&self) -> PageTableFlags {
        PageTableFlags::from_bits_truncate(self.entry)
    }

    /// Returns the physical address mapped by this entry, might be zero.
    #[inline]
    pub fn addr(&self) -> PhysAddr {
        PhysAddr::new(self.entry & 0x000f_ffff_ffff_f000)
    }

    /// Returns the physical frame mapped by this entry.
    ///
    /// Returns the following errors:
    ///
    /// - `FrameError::FrameNotPresent` if the entry doesn't have the `PRESENT` flag set.
    /// - `FrameError::HugeFrame` if the entry has the `HUGE_PAGE` flag set (for huge pages the
    ///    `addr` function must be used)
    #[inline]
    pub fn frame(&self) -> Result<PhysFrame, FrameError> {
        if !self.flags().contains(PageTableFlags::PRESENT) {
            Err(FrameError::FrameNotPresent)
        } else if self.flags().contains(PageTableFlags::HUGE_PAGE) {
            Err(FrameError::HugeFrame)
        } else {
            Ok(PhysFrame::containing_address(self.addr()))
        }
    }

    /// Map the entry to the specified physical address with the specified flags.
    #[inline]
    pub fn set_addr(&mut self, addr: PhysAddr, flags: PageTableFlags) {
        assert!(addr.is_aligned(Size4KiB::SIZE));
        self.entry = (addr.as_u64()) | flags.bits();
    }

    /// Map the entry to the specified physical frame with the specified flags.
    #[inline]
    pub fn set_frame(&mut self, frame: PhysFrame, flags: PageTableFlags) {
        assert!(!flags.contains(PageTableFlags::HUGE_PAGE));
        self.set_addr(frame.start_address(), flags)
    }

    /// Sets the flags of this entry.
    #[inline]
    pub fn set_flags(&mut self, flags: PageTableFlags) {
        self.entry = self.addr().as_u64() | flags.bits();
    }
}

impl fmt::Debug for PageTableEntry {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let mut f = f.debug_struct("PageTableEntry");
        f.field("addr", &self.addr());
        f.field("flags", &self.flags());
        f.finish()
    }
}

bitflags! {
    /// Possible flags for a page table entry.
    pub struct PageTableFlags: u64 {
        /// Specifies whether the mapped frame or page table is loaded in memory.
        const PRESENT =         1;
        /// Controls whether writes to the mapped frames are allowed.
        ///
        /// If this bit is unset in a level 1 page table entry, the mapped frame is read-only.
        /// If this bit is unset in a higher level page table entry the complete range of mapped
        /// pages is read-only.
        const WRITABLE =        1 << 1;
        /// Controls whether accesses from userspace (i.e. ring 3) are permitted.
        const USER_ACCESSIBLE = 1 << 2;
        /// If this bit is set, a “write-through” policy is used for the cache, else a “write-back”
        /// policy is used.
        const WRITE_THROUGH =   1 << 3;
        /// Disables caching for the pointed entry is cacheable.
        const NO_CACHE =        1 << 4;
        /// Set by the CPU when the mapped frame or page table is accessed.
        const ACCESSED =        1 << 5;
        /// Set by the CPU on a write to the mapped frame.
        const DIRTY =           1 << 6;
        /// Specifies that the entry maps a huge frame instead of a page table. Only allowed in
        /// P2 or P3 tables.
        const HUGE_PAGE =       1 << 7;
        /// Indicates that the mapping is present in all address spaces, so it isn't flushed from
        /// the TLB on an address space switch.
        const GLOBAL =          1 << 8;
        /// Available to the OS, can be used to store additional data, e.g. custom flags.
        const BIT_9 =           1 << 9;
        /// Available to the OS, can be used to store additional data, e.g. custom flags.
        const BIT_10 =          1 << 10;
        /// Available to the OS, can be used to store additional data, e.g. custom flags.
        const BIT_11 =          1 << 11;
        /// Available to the OS, can be used to store additional data, e.g. custom flags.
        const BIT_52 =          1 << 52;
        /// Available to the OS, can be used to store additional data, e.g. custom flags.
        const BIT_53 =          1 << 53;
        /// Available to the OS, can be used to store additional data, e.g. custom flags.
        const BIT_54 =          1 << 54;
        /// Available to the OS, can be used to store additional data, e.g. custom flags.
        const BIT_55 =          1 << 55;
        /// Available to the OS, can be used to store additional data, e.g. custom flags.
        const BIT_56 =          1 << 56;
        /// Available to the OS, can be used to store additional data, e.g. custom flags.
        const BIT_57 =          1 << 57;
        /// Available to the OS, can be used to store additional data, e.g. custom flags.
        const BIT_58 =          1 << 58;
        /// Available to the OS, can be used to store additional data, e.g. custom flags.
        const BIT_59 =          1 << 59;
        /// Available to the OS, can be used to store additional data, e.g. custom flags.
        const BIT_60 =          1 << 60;
        /// Available to the OS, can be used to store additional data, e.g. custom flags.
        const BIT_61 =          1 << 61;
        /// Available to the OS, can be used to store additional data, e.g. custom flags.
        const BIT_62 =          1 << 62;
        /// Forbid code execution from the mapped frames.
        ///
        /// Can be only used when the no-execute page protection feature is enabled in the EFER
        /// register.
        const NO_EXECUTE =      1 << 63;
    }
}

/// The number of entries in a page table.
const ENTRY_COUNT: usize = 512;

/// Represents a page table.
///
/// Always page-sized.
///
/// This struct implements the `Index` and `IndexMut` traits, so the entries can be accessed
/// through index operations. For example, `page_table[15]` returns the 15th page table entry.
#[repr(align(4096))]
#[repr(C)]
pub struct PageTable {
    entries: [PageTableEntry; ENTRY_COUNT],
}

impl PageTable {
    /// Creates an empty page table.
    #[cfg(feature = "const_fn")]
    #[inline]
    pub const fn new() -> Self {
        const EMPTY: PageTableEntry = PageTableEntry::new();
        PageTable {
            entries: [EMPTY; ENTRY_COUNT],
        }
    }

    #[cfg(not(feature = "const_fn"))]
    #[inline]
    pub fn new() -> Self {
        const EMPTY: PageTableEntry = PageTableEntry::new();
        PageTable {
            entries: [EMPTY; ENTRY_COUNT],
        }
    }

    /// Clears all entries.
    #[inline]
    pub fn zero(&mut self) {
        for entry in self.entries.iter_mut() {
            entry.set_unused();
        }
    }

    /// Returns an iterator over the entries of the page table.
    #[inline]
    pub fn iter(&self) -> impl Iterator<Item = &PageTableEntry> {
        self.entries.iter()
    }

    /// Returns an iterator that allows modifying the entries of the page table.
    #[inline]
    pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut PageTableEntry> {
        self.entries.iter_mut()
    }
}

impl Index<usize> for PageTable {
    type Output = PageTableEntry;

    #[inline]
    fn index(&self, index: usize) -> &Self::Output {
        &self.entries[index]
    }
}

impl IndexMut<usize> for PageTable {
    #[inline]
    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
        &mut self.entries[index]
    }
}

impl Index<PageTableIndex> for PageTable {
    type Output = PageTableEntry;

    #[inline]
    fn index(&self, index: PageTableIndex) -> &Self::Output {
        &self.entries[usize::from(index)]
    }
}

impl IndexMut<PageTableIndex> for PageTable {
    #[inline]
    fn index_mut(&mut self, index: PageTableIndex) -> &mut Self::Output {
        &mut self.entries[usize::from(index)]
    }
}

impl Default for PageTable {
    fn default() -> Self {
        Self::new()
    }
}

impl fmt::Debug for PageTable {
    #[inline]
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.entries[..].fmt(f)
    }
}

/// A 9-bit index into a page table.
///
/// Can be used to select one of the 512 entries of a page table.
///
/// Guaranteed to only ever contain 0..512.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct PageTableIndex(u16);

impl PageTableIndex {
    /// Creates a new index from the given `u16`. Panics if the given value is >=512.
    #[inline]
    pub fn new(index: u16) -> Self {
        assert!(usize::from(index) < ENTRY_COUNT);
        Self(index)
    }

    /// Creates a new index from the given `u16`. Throws away bits if the value is >=512.
    #[inline]
    pub const fn new_truncate(index: u16) -> Self {
        Self(index % ENTRY_COUNT as u16)
    }
}

impl From<PageTableIndex> for u16 {
    #[inline]
    fn from(index: PageTableIndex) -> Self {
        index.0
    }
}

impl From<PageTableIndex> for u32 {
    #[inline]
    fn from(index: PageTableIndex) -> Self {
        u32::from(index.0)
    }
}

impl From<PageTableIndex> for u64 {
    #[inline]
    fn from(index: PageTableIndex) -> Self {
        u64::from(index.0)
    }
}

impl From<PageTableIndex> for usize {
    #[inline]
    fn from(index: PageTableIndex) -> Self {
        usize::from(index.0)
    }
}

/// A 12-bit offset into a 4KiB Page.
///
/// This type is returned by the `VirtAddr::page_offset` method.
///
/// Guaranteed to only ever contain 0..4096.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct PageOffset(u16);

impl PageOffset {
    /// Creates a new offset from the given `u16`. Panics if the passed value is >=4096.
    #[inline]
    pub fn new(offset: u16) -> Self {
        assert!(offset < (1 << 12));
        Self(offset)
    }

    /// Creates a new offset from the given `u16`. Throws away bits if the value is >=4096.
    #[inline]
    pub const fn new_truncate(offset: u16) -> Self {
        Self(offset % (1 << 12))
    }
}

impl From<PageOffset> for u16 {
    #[inline]
    fn from(offset: PageOffset) -> Self {
        offset.0
    }
}

impl From<PageOffset> for u32 {
    #[inline]
    fn from(offset: PageOffset) -> Self {
        u32::from(offset.0)
    }
}

impl From<PageOffset> for u64 {
    #[inline]
    fn from(offset: PageOffset) -> Self {
        u64::from(offset.0)
    }
}

impl From<PageOffset> for usize {
    #[inline]
    fn from(offset: PageOffset) -> Self {
        usize::from(offset.0)
    }
}
<|endoftext|>


<commit_before>#[cfg(test)]
extern crate assert;

#[macro_use]
extern crate log;

extern crate configuration;
extern crate fractal;
extern crate probability;
extern crate random;
extern crate sql;
extern crate sqlite;
extern crate temperature;
extern crate threed_ice;
extern crate time;

use std::path::Path;
use std::{error, fmt};

mod math {
    use std::f64::INFINITY;

    #[link_name = "m"]
    extern {
        fn nextafter(x: f64, y: f64) -> f64;
    }

    #[inline]
    pub fn next_after(x: f64) -> f64 {
        unsafe { nextafter(x, INFINITY) }
    }
}

#[macro_use]
mod macros;

mod platform;
mod profile;
mod schedule;
mod system;
mod traffic;
mod workload;

pub use platform::Platform;
pub use profile::Profile;
pub use system::{Increment, Job, System};

pub type Error = Box<std::error::Error>;
pub type Result<T> = std::result::Result<T, Error>;

pub struct ErrorString(pub String);

pub type Config = configuration::Tree;
pub type Source = random::Default;

impl fmt::Debug for ErrorString {
    #[inline]
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(formatter)
    }
}

impl fmt::Display for ErrorString {
    #[inline]
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(formatter)
    }
}

impl error::Error for ErrorString {
    #[inline]
    fn description(&self) -> &str {
        &self.0
    }
}

#[inline]
pub fn open<T: AsRef<Path>>(path: T) -> Result<System> {
    let config = try!(configure(path));
    let source = {
        let seed = config.get::<i64>("seed").map(|&seed| seed as u64).unwrap_or(0);
        let seed = if seed > 0 { seed } else { time::now().to_timespec().sec as u64 };
        let seed = [0x12345678 & seed, 0x87654321 & seed];
        random::default().seed(seed)
    };
    System::new(config, source)
}

fn configure<T: AsRef<Path>>(path: T) -> Result<Config> {
    use configuration::format::toml;

    let path = path.as_ref();
    let mut config = try!(toml::open(path));
    if let Some(root) = path.parent() {
        if config.set("root", root.to_path_buf()).is_none() {
            raise!("failed to set the root directory");
        }
    }
    Ok(config)
}
<commit_msg>Make a cosmetic change<commit_after>#[cfg(test)]
extern crate assert;

#[macro_use]
extern crate log;

extern crate configuration;
extern crate fractal;
extern crate probability;
extern crate random;
extern crate sql;
extern crate sqlite;
extern crate temperature;
extern crate threed_ice;
extern crate time;

use std::path::Path;
use std::{error, fmt};

mod math {
    use std::f64::INFINITY;

    #[link_name = "m"]
    extern {
        fn nextafter(x: f64, y: f64) -> f64;
    }

    #[inline]
    pub fn next_after(x: f64) -> f64 {
        unsafe { nextafter(x, INFINITY) }
    }
}

#[macro_use]
mod macros;

mod platform;
mod profile;
mod schedule;
mod system;
mod traffic;
mod workload;

pub use platform::Platform;
pub use profile::Profile;
pub use system::{Increment, Job, System};

pub type Error = Box<std::error::Error>;
pub type Result<T> = std::result::Result<T, Error>;

pub struct ErrorString(pub String);

pub type Config = configuration::Tree;
pub type Source = random::Default;

impl fmt::Debug for ErrorString {
    #[inline]
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(formatter)
    }
}

impl fmt::Display for ErrorString {
    #[inline]
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(formatter)
    }
}

impl error::Error for ErrorString {
    #[inline]
    fn description(&self) -> &str {
        &self.0
    }
}

pub fn open<T: AsRef<Path>>(path: T) -> Result<System> {
    let config = try!(configure(path));
    let source = {
        let seed = config.get::<i64>("seed").map(|&seed| seed as u64).unwrap_or(0);
        let seed = if seed > 0 { seed } else { time::now().to_timespec().sec as u64 };
        let seed = [0x12345678 & seed, 0x87654321 & seed];
        random::default().seed(seed)
    };
    System::new(config, source)
}

fn configure<T: AsRef<Path>>(path: T) -> Result<Config> {
    let path = path.as_ref();
    let mut config = try!(configuration::format::toml::open(path));
    if let Some(root) = path.parent() {
        if config.set("root", root.to_path_buf()).is_none() {
            raise!("failed to set the root directory");
        }
    }
    Ok(config)
}
<|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.

//! A mutable, nullable memory location

use cast::transmute_mut;
use prelude::*;

/*
A dynamic, mutable location.

Similar to a mutable option type, but friendlier.
*/

pub struct Cell<T> {
    value: Option<T>
}

impl<T:cmp::Eq> cmp::Eq for Cell<T> {
    fn eq(&self, other: &Cell<T>) -> bool {
        (self.value) == (other.value)
    }
    fn ne(&self, other: &Cell<T>) -> bool { !self.eq(other) }
}

/// Creates a new full cell with the given value.
pub fn Cell<T>(value: T) -> Cell<T> {
    Cell { value: Some(value) }
}

pub fn empty_cell<T>() -> Cell<T> {
    Cell { value: None }
}

pub impl<T> Cell<T> {
    /// Yields the value, failing if the cell is empty.
    fn take(&self) -> T {
        let mut self = unsafe { transmute_mut(self) };
        if self.is_empty() {
            fail!(~"attempt to take an empty cell");
        }

        let mut value = None;
        value <-> self.value;
        value.unwrap()
    }

    /// Returns the value, failing if the cell is full.
    fn put_back(&self, value: T) {
        let mut self = unsafe { transmute_mut(self) };
        if !self.is_empty() {
            fail!(~"attempt to put a value back into a full cell");
        }
        self.value = Some(value);
    }

    /// Returns true if the cell is empty and false if the cell is full.
    fn is_empty(&self) -> bool {
        self.value.is_none()
    }

    // Calls a closure with a reference to the value.
    fn with_ref<R>(&self, op: &fn(v: &T) -> R) -> R {
        let v = self.take();
        let r = op(&v);
        self.put_back(v);
        r
    }

    // Calls a closure with a mutable reference to the value.
    fn with_mut_ref<R>(&self, op: &fn(v: &mut T) -> R) -> R {
        let mut v = self.take();
        let r = op(&mut v);
        self.put_back(v);
        r
    }
}

#[test]
fn test_basic() {
    let value_cell = Cell(~10);
    assert!(!value_cell.is_empty());
    let value = value_cell.take();
    assert!(value == ~10);
    assert!(value_cell.is_empty());
    value_cell.put_back(value);
    assert!(!value_cell.is_empty());
}

#[test]
#[should_fail]
#[ignore(cfg(windows))]
fn test_take_empty() {
    let value_cell = empty_cell::<~int>();
    value_cell.take();
}

#[test]
#[should_fail]
#[ignore(cfg(windows))]
fn test_put_back_non_empty() {
    let value_cell = Cell(~10);
    value_cell.put_back(~20);
}

#[test]
fn test_with_ref() {
    let good = 6;
    let c = Cell(~[1, 2, 3, 4, 5, 6]);
    let l = do c.with_ref() |v| { v.len() };
    assert!(l == good);
}

#[test]
fn test_with_mut_ref() {
    let good = ~[1, 2, 3];
    let mut v = ~[1, 2];
    let c = Cell(v);
    do c.with_mut_ref() |v| { v.push(3); }
    let v = c.take();
    assert!(v == good);
}
<commit_msg>cell: public field is unsafe<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.

//! A mutable, nullable memory location

use cast::transmute_mut;
use prelude::*;

/*
A dynamic, mutable location.

Similar to a mutable option type, but friendlier.
*/

pub struct Cell<T> {
    priv value: Option<T>
}

impl<T:cmp::Eq> cmp::Eq for Cell<T> {
    fn eq(&self, other: &Cell<T>) -> bool {
        (self.value) == (other.value)
    }
    fn ne(&self, other: &Cell<T>) -> bool { !self.eq(other) }
}

/// Creates a new full cell with the given value.
pub fn Cell<T>(value: T) -> Cell<T> {
    Cell { value: Some(value) }
}

pub fn empty_cell<T>() -> Cell<T> {
    Cell { value: None }
}

pub impl<T> Cell<T> {
    /// Yields the value, failing if the cell is empty.
    fn take(&self) -> T {
        let mut self = unsafe { transmute_mut(self) };
        if self.is_empty() {
            fail!(~"attempt to take an empty cell");
        }

        let mut value = None;
        value <-> self.value;
        value.unwrap()
    }

    /// Returns the value, failing if the cell is full.
    fn put_back(&self, value: T) {
        let mut self = unsafe { transmute_mut(self) };
        if !self.is_empty() {
            fail!(~"attempt to put a value back into a full cell");
        }
        self.value = Some(value);
    }

    /// Returns true if the cell is empty and false if the cell is full.
    fn is_empty(&self) -> bool {
        self.value.is_none()
    }

    // Calls a closure with a reference to the value.
    fn with_ref<R>(&self, op: &fn(v: &T) -> R) -> R {
        let v = self.take();
        let r = op(&v);
        self.put_back(v);
        r
    }

    // Calls a closure with a mutable reference to the value.
    fn with_mut_ref<R>(&self, op: &fn(v: &mut T) -> R) -> R {
        let mut v = self.take();
        let r = op(&mut v);
        self.put_back(v);
        r
    }
}

#[test]
fn test_basic() {
    let value_cell = Cell(~10);
    assert!(!value_cell.is_empty());
    let value = value_cell.take();
    assert!(value == ~10);
    assert!(value_cell.is_empty());
    value_cell.put_back(value);
    assert!(!value_cell.is_empty());
}

#[test]
#[should_fail]
#[ignore(cfg(windows))]
fn test_take_empty() {
    let value_cell = empty_cell::<~int>();
    value_cell.take();
}

#[test]
#[should_fail]
#[ignore(cfg(windows))]
fn test_put_back_non_empty() {
    let value_cell = Cell(~10);
    value_cell.put_back(~20);
}

#[test]
fn test_with_ref() {
    let good = 6;
    let c = Cell(~[1, 2, 3, 4, 5, 6]);
    let l = do c.with_ref() |v| { v.len() };
    assert!(l == good);
}

#[test]
fn test_with_mut_ref() {
    let good = ~[1, 2, 3];
    let mut v = ~[1, 2];
    let c = Cell(v);
    do c.with_mut_ref() |v| { v.push(3); }
    let v = c.take();
    assert!(v == good);
}
<|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.

/*!
Primitive traits representing basic 'kinds' of types

Rust types can be classified in various useful ways according to
intrinsic properties of the type. These classifications, often called
'kinds', are represented as traits.

They cannot be implemented by user code, but are instead implemented
by the compiler automatically for the types to which they apply.

*/

/// Types able to be transferred across task boundaries.
#[lang="send"]
pub trait Send {
    // empty.
}

/// Types with a constant size known at compile-time.
#[lang="sized"]
pub trait Sized {
    // Empty.
}

/// Types that can be copied by simply copying bits (i.e. `memcpy`).
///
/// The name "POD" stands for "Plain Old Data" and is borrowed from C++.
#[lang="pod"]
pub trait Pod {
    // Empty.
}

/// Types that can be safely shared between threads, hence thread-safe.
#[lang="share"]
pub trait Share {
    // Empty
}

/// Marker types are special types that are used with unsafe code to
/// inform the compiler of special constraints. Marker types should
/// only be needed when you are creating an abstraction that is
/// implemented using unsafe code. In that case, you may want to embed
/// some of the marker types below into your type.
pub mod marker {

    /// A marker type whose type parameter `T` is considered to be
    /// covariant with respect to the type itself. This is (typically)
    /// used to indicate that an instance of the type `T` is being stored
    /// into memory and read from, even though that may not be apparent.
    ///
    /// For more information about variance, refer to this Wikipedia
    /// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
    ///
    /// *Note:* It is very unusual to have to add a covariant constraint.
    /// If you are not sure, you probably want to use `InvariantType`.
    ///
    /// # Example
    ///
    /// Given a struct `S` that includes a type parameter `T`
    /// but does not actually *reference* that type parameter:
    ///
    /// ```ignore
    /// use std::cast;
    ///
    /// struct S<T> { x: *() }
    /// fn get<T>(s: &S<T>) -> T {
    ///    unsafe {
    ///        let x: *T = cast::transmute(s.x);
    ///        *x
    ///    }
    /// }
    /// ```
    ///
    /// The type system would currently infer that the value of
    /// the type parameter `T` is irrelevant, and hence a `S<int>` is
    /// a subtype of `S<~[int]>` (or, for that matter, `S<U>` for
    /// any `U`). But this is incorrect because `get()` converts the
    /// `*()` into a `*T` and reads from it. Therefore, we should include the
    /// a marker field `CovariantType<T>` to inform the type checker that
    /// `S<T>` is a subtype of `S<U>` if `T` is a subtype of `U`
    /// (for example, `S<&'static int>` is a subtype of `S<&'a int>`
    /// for some lifetime `'a`, but not the other way around).
    #[lang="covariant_type"]
    #[deriving(Eq,Clone)]
    pub struct CovariantType<T>;

    /// A marker type whose type parameter `T` is considered to be
    /// contravariant with respect to the type itself. This is (typically)
    /// used to indicate that an instance of the type `T` will be consumed
    /// (but not read from), even though that may not be apparent.
    ///
    /// For more information about variance, refer to this Wikipedia
    /// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
    ///
    /// *Note:* It is very unusual to have to add a contravariant constraint.
    /// If you are not sure, you probably want to use `InvariantType`.
    ///
    /// # Example
    ///
    /// Given a struct `S` that includes a type parameter `T`
    /// but does not actually *reference* that type parameter:
    ///
    /// ```
    /// use std::cast;
    ///
    /// struct S<T> { x: *() }
    /// fn get<T>(s: &S<T>, v: T) {
    ///    unsafe {
    ///        let x: fn(T) = cast::transmute(s.x);
    ///        x(v)
    ///    }
    /// }
    /// ```
    ///
    /// The type system would currently infer that the value of
    /// the type parameter `T` is irrelevant, and hence a `S<int>` is
    /// a subtype of `S<~[int]>` (or, for that matter, `S<U>` for
    /// any `U`). But this is incorrect because `get()` converts the
    /// `*()` into a `fn(T)` and then passes a value of type `T` to it.
    ///
    /// Supplying a `ContravariantType` marker would correct the
    /// problem, because it would mark `S` so that `S<T>` is only a
    /// subtype of `S<U>` if `U` is a subtype of `T`; given that the
    /// function requires arguments of type `T`, it must also accept
    /// arguments of type `U`, hence such a conversion is safe.
    #[lang="contravariant_type"]
    #[deriving(Eq,Clone)]
    pub struct ContravariantType<T>;

    /// A marker type whose type parameter `T` is considered to be
    /// invariant with respect to the type itself. This is (typically)
    /// used to indicate that instances of the type `T` may be read or
    /// written, even though that may not be apparent.
    ///
    /// For more information about variance, refer to this Wikipedia
    /// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
    ///
    /// # Example
    ///
    /// The Cell type is an example which uses unsafe code to achieve
    /// "interior" mutability:
    ///
    /// ```
    /// pub struct Cell<T> { priv value: T }
    /// # fn main() {}
    /// ```
    ///
    /// The type system would infer that `value` is only read here and
    /// never written, but in fact `Cell` uses unsafe code to achieve
    /// interior mutability.
    #[lang="invariant_type"]
    #[deriving(Eq,Clone)]
    pub struct InvariantType<T>;

    /// As `CovariantType`, but for lifetime parameters. Using
    /// `CovariantLifetime<'a>` indicates that it is ok to substitute
    /// a *longer* lifetime for `'a` than the one you originally
    /// started with (e.g., you could convert any lifetime `'foo` to
    /// `'static`). You almost certainly want `ContravariantLifetime`
    /// instead, or possibly `InvariantLifetime`. The only case where
    /// it would be appropriate is that you have a (type-casted, and
    /// hence hidden from the type system) function pointer with a
    /// signature like `fn(&'a T)` (and no other uses of `'a`). In
    /// this case, it is ok to substitute a larger lifetime for `'a`
    /// (e.g., `fn(&'static T)`), because the function is only
    /// becoming more selective in terms of what it accepts as
    /// argument.
    ///
    /// For more information about variance, refer to this Wikipedia
    /// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
    #[lang="covariant_lifetime"]
    #[deriving(Eq,Clone)]
    pub struct CovariantLifetime<'a>;

    /// As `ContravariantType`, but for lifetime parameters. Using
    /// `ContravariantLifetime<'a>` indicates that it is ok to
    /// substitute a *shorter* lifetime for `'a` than the one you
    /// originally started with (e.g., you could convert `'static` to
    /// any lifetime `'foo`). This is appropriate for cases where you
    /// have an unsafe pointer that is actually a pointer into some
    /// memory with lifetime `'a`, and thus you want to limit the
    /// lifetime of your data structure to `'a`. An example of where
    /// this is used is the iterator for vectors.
    ///
    /// For more information about variance, refer to this Wikipedia
    /// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
    #[lang="contravariant_lifetime"]
    #[deriving(Eq,Clone)]
    pub struct ContravariantLifetime<'a>;

    /// As `InvariantType`, but for lifetime parameters. Using
    /// `InvariantLifetime<'a>` indicates that it is not ok to
    /// substitute any other lifetime for `'a` besides its original
    /// value. This is appropriate for cases where you have an unsafe
    /// pointer that is actually a pointer into memory with lifetime `'a`,
    /// and this pointer is itself stored in an inherently mutable
    /// location (such as a `Cell`).
    #[lang="invariant_lifetime"]
    #[deriving(Eq,Clone)]
    pub struct InvariantLifetime<'a>;

    /// A type which is considered "not sendable", meaning that it cannot
    /// be safely sent between tasks, even if it is owned. This is
    /// typically embedded in other types, such as `Gc`, to ensure that
    /// their instances remain thread-local.
    #[lang="no_send_bound"]
    #[deriving(Eq,Clone)]
    pub struct NoSend;

    /// A type which is considered "not POD", meaning that it is not
    /// implicitly copyable. This is typically embedded in other types to
    /// ensure that they are never copied, even if they lack a destructor.
    #[lang="no_pod_bound"]
    #[deriving(Eq,Clone)]
    pub struct NoPod;

    /// A type which is considered "not sharable", meaning that
    /// its contents are not threadsafe, hence they cannot be
    /// shared between tasks.
    #[lang="no_share_bound"]
    #[deriving(Eq,Clone)]
    pub struct NoShare;

    /// A type which is considered managed by the GC. This is typically
    /// embedded in other types.
    #[lang="managed_bound"]
    #[deriving(Eq,Clone)]
    pub struct Managed;
}
<commit_msg>std: expand the `Share` docs to make them more precise.<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.

/*!
Primitive traits representing basic 'kinds' of types

Rust types can be classified in various useful ways according to
intrinsic properties of the type. These classifications, often called
'kinds', are represented as traits.

They cannot be implemented by user code, but are instead implemented
by the compiler automatically for the types to which they apply.

*/

/// Types able to be transferred across task boundaries.
#[lang="send"]
pub trait Send {
    // empty.
}

/// Types with a constant size known at compile-time.
#[lang="sized"]
pub trait Sized {
    // Empty.
}

/// Types that can be copied by simply copying bits (i.e. `memcpy`).
///
/// The name "POD" stands for "Plain Old Data" and is borrowed from C++.
#[lang="pod"]
pub trait Pod {
    // Empty.
}

/// Types that can be safely shared between tasks when aliased.
///
/// The precise definition is: a type `T` is `Share` if `&T` is
/// thread-safe. In other words, there is no possibility of data races
/// when passing `&T` references between tasks.
///
/// As one would expect, primitive types like `u8` and `f64` are all
/// `Share`, and so are simple aggregate types containing them (like
/// tuples, structs and enums). More instances of basic `Share` types
/// include "immutable" types like `&T` and those with simple
/// inherited mutability, such as `~T`, `Vec<T>` and most other
/// collection types. (Generic parameters need to be `Share` for their
/// container to be `Share`.)
///
/// A somewhat surprising consequence of the definition is `&mut T` is
/// `Share` (if `T` is `Share`) even though it seems that it might
/// provide unsynchronised mutation. The trick is a mutable reference
/// stored in an aliasable reference (that is, `& &mut T`) becomes
/// read-only, as if it were a `& &T`, hence there is no risk of a data
/// race.
///
/// Types that are not `Share` are those that have "interior
/// mutability" in a non-thread-safe way, such as `Cell` and `RefCell`
/// in `std::cell`. These types allow for mutation of their contents
/// even when in an immutable, aliasable slot, e.g. the contents of
/// `&Cell<T>` can be `.set`, and do not ensure data races are
/// impossible, hence they cannot be `Share`. A higher level example
/// of a non-`Share` type is the reference counted pointer
/// `std::rc::Rc`, because any reference `&Rc<T>` can clone a new
/// reference, which modifies the reference counts in a non-atomic
/// way.
///
/// For cases when one does need thread-safe interior mutability,
/// types like the atomics in `std::sync` and `Mutex` & `RWLock` in
/// the `sync` crate do ensure that any mutation cannot cause data
/// races.  Hence these types are `Share`.
///
/// Users writing their own types with interior mutability (or anything
/// else that is not thread-safe) should use the `NoShare` marker type
/// (from `std::kinds::marker`) to ensure that the compiler doesn't
/// consider the user-defined type to be `Share`.  Any types with
/// interior mutability must also use the `std::ty::Unsafe` wrapper
/// around the value(s) which can be mutated when behind a `&`
/// reference; not doing this is undefined behaviour (for example,
/// `transmute`-ing from `&T` to `&mut T` is illegal).
#[lang="share"]
pub trait Share {
    // Empty
}

/// Marker types are special types that are used with unsafe code to
/// inform the compiler of special constraints. Marker types should
/// only be needed when you are creating an abstraction that is
/// implemented using unsafe code. In that case, you may want to embed
/// some of the marker types below into your type.
pub mod marker {

    /// A marker type whose type parameter `T` is considered to be
    /// covariant with respect to the type itself. This is (typically)
    /// used to indicate that an instance of the type `T` is being stored
    /// into memory and read from, even though that may not be apparent.
    ///
    /// For more information about variance, refer to this Wikipedia
    /// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
    ///
    /// *Note:* It is very unusual to have to add a covariant constraint.
    /// If you are not sure, you probably want to use `InvariantType`.
    ///
    /// # Example
    ///
    /// Given a struct `S` that includes a type parameter `T`
    /// but does not actually *reference* that type parameter:
    ///
    /// ```ignore
    /// use std::cast;
    ///
    /// struct S<T> { x: *() }
    /// fn get<T>(s: &S<T>) -> T {
    ///    unsafe {
    ///        let x: *T = cast::transmute(s.x);
    ///        *x
    ///    }
    /// }
    /// ```
    ///
    /// The type system would currently infer that the value of
    /// the type parameter `T` is irrelevant, and hence a `S<int>` is
    /// a subtype of `S<~[int]>` (or, for that matter, `S<U>` for
    /// any `U`). But this is incorrect because `get()` converts the
    /// `*()` into a `*T` and reads from it. Therefore, we should include the
    /// a marker field `CovariantType<T>` to inform the type checker that
    /// `S<T>` is a subtype of `S<U>` if `T` is a subtype of `U`
    /// (for example, `S<&'static int>` is a subtype of `S<&'a int>`
    /// for some lifetime `'a`, but not the other way around).
    #[lang="covariant_type"]
    #[deriving(Eq,Clone)]
    pub struct CovariantType<T>;

    /// A marker type whose type parameter `T` is considered to be
    /// contravariant with respect to the type itself. This is (typically)
    /// used to indicate that an instance of the type `T` will be consumed
    /// (but not read from), even though that may not be apparent.
    ///
    /// For more information about variance, refer to this Wikipedia
    /// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
    ///
    /// *Note:* It is very unusual to have to add a contravariant constraint.
    /// If you are not sure, you probably want to use `InvariantType`.
    ///
    /// # Example
    ///
    /// Given a struct `S` that includes a type parameter `T`
    /// but does not actually *reference* that type parameter:
    ///
    /// ```
    /// use std::cast;
    ///
    /// struct S<T> { x: *() }
    /// fn get<T>(s: &S<T>, v: T) {
    ///    unsafe {
    ///        let x: fn(T) = cast::transmute(s.x);
    ///        x(v)
    ///    }
    /// }
    /// ```
    ///
    /// The type system would currently infer that the value of
    /// the type parameter `T` is irrelevant, and hence a `S<int>` is
    /// a subtype of `S<~[int]>` (or, for that matter, `S<U>` for
    /// any `U`). But this is incorrect because `get()` converts the
    /// `*()` into a `fn(T)` and then passes a value of type `T` to it.
    ///
    /// Supplying a `ContravariantType` marker would correct the
    /// problem, because it would mark `S` so that `S<T>` is only a
    /// subtype of `S<U>` if `U` is a subtype of `T`; given that the
    /// function requires arguments of type `T`, it must also accept
    /// arguments of type `U`, hence such a conversion is safe.
    #[lang="contravariant_type"]
    #[deriving(Eq,Clone)]
    pub struct ContravariantType<T>;

    /// A marker type whose type parameter `T` is considered to be
    /// invariant with respect to the type itself. This is (typically)
    /// used to indicate that instances of the type `T` may be read or
    /// written, even though that may not be apparent.
    ///
    /// For more information about variance, refer to this Wikipedia
    /// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
    ///
    /// # Example
    ///
    /// The Cell type is an example which uses unsafe code to achieve
    /// "interior" mutability:
    ///
    /// ```
    /// pub struct Cell<T> { priv value: T }
    /// # fn main() {}
    /// ```
    ///
    /// The type system would infer that `value` is only read here and
    /// never written, but in fact `Cell` uses unsafe code to achieve
    /// interior mutability.
    #[lang="invariant_type"]
    #[deriving(Eq,Clone)]
    pub struct InvariantType<T>;

    /// As `CovariantType`, but for lifetime parameters. Using
    /// `CovariantLifetime<'a>` indicates that it is ok to substitute
    /// a *longer* lifetime for `'a` than the one you originally
    /// started with (e.g., you could convert any lifetime `'foo` to
    /// `'static`). You almost certainly want `ContravariantLifetime`
    /// instead, or possibly `InvariantLifetime`. The only case where
    /// it would be appropriate is that you have a (type-casted, and
    /// hence hidden from the type system) function pointer with a
    /// signature like `fn(&'a T)` (and no other uses of `'a`). In
    /// this case, it is ok to substitute a larger lifetime for `'a`
    /// (e.g., `fn(&'static T)`), because the function is only
    /// becoming more selective in terms of what it accepts as
    /// argument.
    ///
    /// For more information about variance, refer to this Wikipedia
    /// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
    #[lang="covariant_lifetime"]
    #[deriving(Eq,Clone)]
    pub struct CovariantLifetime<'a>;

    /// As `ContravariantType`, but for lifetime parameters. Using
    /// `ContravariantLifetime<'a>` indicates that it is ok to
    /// substitute a *shorter* lifetime for `'a` than the one you
    /// originally started with (e.g., you could convert `'static` to
    /// any lifetime `'foo`). This is appropriate for cases where you
    /// have an unsafe pointer that is actually a pointer into some
    /// memory with lifetime `'a`, and thus you want to limit the
    /// lifetime of your data structure to `'a`. An example of where
    /// this is used is the iterator for vectors.
    ///
    /// For more information about variance, refer to this Wikipedia
    /// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
    #[lang="contravariant_lifetime"]
    #[deriving(Eq,Clone)]
    pub struct ContravariantLifetime<'a>;

    /// As `InvariantType`, but for lifetime parameters. Using
    /// `InvariantLifetime<'a>` indicates that it is not ok to
    /// substitute any other lifetime for `'a` besides its original
    /// value. This is appropriate for cases where you have an unsafe
    /// pointer that is actually a pointer into memory with lifetime `'a`,
    /// and this pointer is itself stored in an inherently mutable
    /// location (such as a `Cell`).
    #[lang="invariant_lifetime"]
    #[deriving(Eq,Clone)]
    pub struct InvariantLifetime<'a>;

    /// A type which is considered "not sendable", meaning that it cannot
    /// be safely sent between tasks, even if it is owned. This is
    /// typically embedded in other types, such as `Gc`, to ensure that
    /// their instances remain thread-local.
    #[lang="no_send_bound"]
    #[deriving(Eq,Clone)]
    pub struct NoSend;

    /// A type which is considered "not POD", meaning that it is not
    /// implicitly copyable. This is typically embedded in other types to
    /// ensure that they are never copied, even if they lack a destructor.
    #[lang="no_pod_bound"]
    #[deriving(Eq,Clone)]
    pub struct NoPod;

    /// A type which is considered "not sharable", meaning that
    /// its contents are not threadsafe, hence they cannot be
    /// shared between tasks.
    #[lang="no_share_bound"]
    #[deriving(Eq,Clone)]
    pub struct NoShare;

    /// A type which is considered managed by the GC. This is typically
    /// embedded in other types.
    #[lang="managed_bound"]
    #[deriving(Eq,Clone)]
    pub struct Managed;
}
<|endoftext|>


<commit_before>
use {
    Borrowed,
    Field,
    Line,
    Matrix2d,
    Value,
    View,
};
use vecmath::{
    identity,
};
use internal::{
    CanTransform,
    HasTransform,
};

/// A line context.
pub struct LineContext<'a> {
    /// Base/original transform.
    pub base: Field<'a, Matrix2d>,
    /// Current transform.
    pub transform: Field<'a, Matrix2d>,
    /// Current line.
    pub line: Field<'a, Line>,
}

impl<'a> HasTransform<'a, Matrix2d> for LineContext<'a> {
    #[inline(always)]
    fn get_transform(&'a self) -> &'a Matrix2d {
        self.transform.get()
    }
}

impl<'a> CanTransform<'a, LineContext<'a>, Matrix2d> for LineContext<'a> {
    #[inline(always)]
    fn transform(&'a self, value: Matrix2d) -> LineContext<'a> {
        LineContext {
            base: Borrowed(self.base.get()),
            transform: Value(value),
            line: Borrowed(self.line.get()),
        }
    }
}

impl<'a> View<'a> for LineContext<'a> {
    #[inline(always)]
    fn view(&'a self) -> LineContext<'a> {
        LineContext {
            base: Borrowed(self.base.get()),
            transform: Borrowed(self.base.get()),
            line: Borrowed(self.line.get()),
        }
    }

    #[inline(always)]
    fn reset(&'a self) -> LineContext<'a> {
        LineContext {
            base: Borrowed(self.base.get()),
            transform: Value(identity()),
            line: Borrowed(self.line.get()),
        }
    }

    #[inline(always)]
    fn store_view(&'a self) -> LineContext<'a> {
        LineContext {
            base: Borrowed(self.transform.get()),
            transform: Borrowed(self.transform.get()),
            line: Borrowed(self.line.get()),
        }
    }
}

<commit_msg>Implemented `AddColor` for `LineContext`<commit_after>
use {
    AddColor,
    Borrowed,
    Field,
    Line,
    LineColorContext,
    Matrix2d,
    Value,
    View,
};
use vecmath::{
    identity,
};
use internal::{
    CanTransform,
    HasTransform,
};

/// A line context.
pub struct LineContext<'a> {
    /// Base/original transform.
    pub base: Field<'a, Matrix2d>,
    /// Current transform.
    pub transform: Field<'a, Matrix2d>,
    /// Current line.
    pub line: Field<'a, Line>,
}

impl<'a> HasTransform<'a, Matrix2d> for LineContext<'a> {
    #[inline(always)]
    fn get_transform(&'a self) -> &'a Matrix2d {
        self.transform.get()
    }
}

impl<'a> CanTransform<'a, LineContext<'a>, Matrix2d> for LineContext<'a> {
    #[inline(always)]
    fn transform(&'a self, value: Matrix2d) -> LineContext<'a> {
        LineContext {
            base: Borrowed(self.base.get()),
            transform: Value(value),
            line: Borrowed(self.line.get()),
        }
    }
}

impl<'a> View<'a> for LineContext<'a> {
    #[inline(always)]
    fn view(&'a self) -> LineContext<'a> {
        LineContext {
            base: Borrowed(self.base.get()),
            transform: Borrowed(self.base.get()),
            line: Borrowed(self.line.get()),
        }
    }

    #[inline(always)]
    fn reset(&'a self) -> LineContext<'a> {
        LineContext {
            base: Borrowed(self.base.get()),
            transform: Value(identity()),
            line: Borrowed(self.line.get()),
        }
    }

    #[inline(always)]
    fn store_view(&'a self) -> LineContext<'a> {
        LineContext {
            base: Borrowed(self.transform.get()),
            transform: Borrowed(self.transform.get()),
            line: Borrowed(self.line.get()),
        }
    }
}

impl<'a> AddColor<'a, LineColorContext<'a>> for LineContext<'a> {
    #[inline(always)]
    fn rgba(&'a self, r: f32, g: f32, b: f32, a: f32) -> LineColorContext<'a> {
        LineColorContext {
            base: Borrowed(self.base.get()),
            transform: Borrowed(self.transform.get()),
            line: Borrowed(self.line.get()),
            color: Value([r, g, b, a]),
        }
    }
}

<|endoftext|>


<commit_before>use std::ffi::{CString, CStr};
use std::os::raw::c_char;
use std::ptr;
use std::cell::RefCell;

use llvm_sys::prelude::*;
use llvm_sys::core::*;
use llvm_sys::analysis::{LLVMVerifyModule, LLVMVerifierFailureAction};
use llvm_sys::transforms::pass_manager_builder as builder;
use llvm_sys::execution_engine as engine;
pub use llvm_sys::LLVMIntPredicate;

// FIXME: Force to link against libffi
#[link(name = "ffi")]
extern {}

pub struct Context {
    context_ref: LLVMContextRef,
    strings:     RefCell<Vec<CString>>,
}

impl Context {
    pub fn new() -> Self {
        Context {
            context_ref: unsafe { LLVMContextCreate() },
            strings:     RefCell::new(Vec::new()),
        }
    }

    pub fn new_name(&self, name: &str) -> *const c_char {
        let string = CString::new(name).unwrap();
        let ptr    = string.as_ptr();
        self.strings.borrow_mut().push(string);
        ptr
    }

    fn wrap_value(&self, value_ref: LLVMValueRef) -> Value {
        Value {
            value_ref: value_ref,
            context:   self,
        }
    }

    fn wrap_type(&self, type_ref: LLVMTypeRef) -> Type {
        Type {
            type_ref: type_ref,
            context:  self,
        }
    }
}

impl Drop for Context {
    fn drop(&mut self) {
        unsafe {
            LLVMContextDispose(self.context_ref);
        }
    }
}

#[derive(Clone, Copy)]
pub struct Module<'a> {
    module_ref: LLVMModuleRef,
    context:    &'a Context,
}

impl<'a> Module<'a> {
    pub fn new(context: &'a Context, name: &str) -> Self {
        let name = context.new_name(name);
        Module {
            module_ref: unsafe {
                LLVMModuleCreateWithNameInContext(name, context.context_ref)
            },
            context: context,
        }
    }

    pub fn add_function(&self, name: &str, ty: Type<'a>) -> Value<'a> {
        let name = self.context.new_name(name);
        self.context.wrap_value(unsafe {
            LLVMAddFunction(self.module_ref, name, ty.type_ref)
        })
    }

    // From llvm-alt:
    pub fn optimize(&self, opt_level: usize, size_level: usize) {
        unsafe {
            let builder = builder::LLVMPassManagerBuilderCreate();
            builder::LLVMPassManagerBuilderSetOptLevel(builder, opt_level as _);
            builder::LLVMPassManagerBuilderSetSizeLevel(builder, size_level as _);
            let pass_manager = LLVMCreatePassManager();
            builder::LLVMPassManagerBuilderPopulateModulePassManager(builder, pass_manager);
            builder::LLVMPassManagerBuilderDispose(builder);
            LLVMRunPassManager(pass_manager, self.module_ref);
            LLVMDisposePassManager(pass_manager);
        }
    }

    pub fn dump(&self) {
        unsafe {
            LLVMDumpModule(self.module_ref);
        }
    }

    pub fn verify(&self) -> Result<(), String> {
        let mut out_message: *mut c_char = ptr::null_mut();

        unsafe {
            if LLVMVerifyModule(self.module_ref,
                                LLVMVerifierFailureAction::LLVMReturnStatusAction,
                                &mut out_message) == 0 {
                Ok(())
            } else {
                let result = CStr::from_ptr(out_message).to_string_lossy().into_owned();
                LLVMDisposeMessage(out_message);
                Err(result)
            }
        }
    }

    pub fn run_function(&self, fun: Value<'a>) -> Result<u64, String> {
        let mut out_message: *mut c_char = ptr::null_mut();
        let mut exec: engine::LLVMExecutionEngineRef = ptr::null_mut();

        unsafe {
            engine::LLVMLinkInInterpreter();
            engine::LLVMLinkInMCJIT();

            if engine::LLVMCreateExecutionEngineForModule(&mut exec, self.module_ref, &mut out_message) != 0 {
                let result = CStr::from_ptr(out_message).to_string_lossy().into_owned();
                LLVMDisposeMessage(out_message);
                return Err(result);
            }

            let size = engine::LLVMCreateGenericValueOfInt(Type::get_i64(self.context).type_ref,
                                                           30_000 as _,
                                                           0 as i32);
            let mut args = vec![size];
            let result = engine::LLVMRunFunction(exec,
                                                 fun.value_ref,
                                                 args.len() as u32,
                                                 args.as_mut_ptr());
            Ok(engine::LLVMGenericValueToInt(result, 0 as i32) as _)
        }
    }
}

#[derive(Copy, Clone)]
pub struct Type<'a> {
    type_ref:  LLVMTypeRef,
    context:   &'a Context,
}

impl<'a> Type<'a> {
    pub fn get_i64(context: &'a Context) -> Self {
        context.wrap_type(unsafe {
            LLVMInt64TypeInContext(context.context_ref)
        })
    }

    pub fn get_i32(context: &'a Context) -> Self {
        context.wrap_type(unsafe {
            LLVMInt32TypeInContext(context.context_ref)
        })
    }

    pub fn get_i8(context: &'a Context) -> Self {
        context.wrap_type(unsafe {
            LLVMInt8TypeInContext(context.context_ref)
        })
    }

    pub fn get_bool(context: &'a Context) -> Self {
        context.wrap_type(unsafe {
            LLVMInt1TypeInContext(context.context_ref)
        })
    }

    pub fn get_void(context: &'a Context) -> Self {
        context.wrap_type(unsafe {
            LLVMVoidTypeInContext(context.context_ref)
        })
    }

    pub fn get_pointer(target: Type<'a>) -> Self {
        target.context.wrap_type(unsafe {
            LLVMPointerType(target.type_ref, 0)
        })
    }

    pub fn get_function(args: &[Type<'a>], result: Type<'a>) -> Self {
        let mut args = args.into_iter().map(|arg| arg.type_ref).collect::<Vec<_>>();
        result.context.wrap_type(unsafe {
            LLVMFunctionType(result.type_ref,
                             args.as_mut_ptr(),
                             args.len() as _,
                             0)
        })
    }
}

#[derive(Copy, Clone)]
pub struct Value<'a> {
    value_ref: LLVMValueRef,
    context:   &'a Context,
}

impl<'a> Value<'a> {
//    pub fn get_fun_param(&self, index: usize) -> Self {
//        self.context.wrap_value(unsafe {
//            LLVMGetParam(self.value_ref, index as _)
//        })
//    }

    pub fn append(&self, name: &str) -> BasicBlock<'a> {
        let name = self.context.new_name(name);
        let bb_ref = unsafe {
            LLVMAppendBasicBlockInContext(self.context.context_ref,
                                          self.value_ref,
                                          name)
        };
        BasicBlock {
            bb_ref: bb_ref,
            _context: self.context,
        }
    }

    pub fn get_u64(context: &'a Context, value: u64) -> Self {
        context.wrap_value(unsafe {
            LLVMConstInt(Type::get_i64(context).type_ref,
                         value as _,
                         false as _)
        })
    }

    pub fn get_u32(context: &'a Context, value: u32) -> Self {
        context.wrap_value(unsafe {
            LLVMConstInt(Type::get_i32(context).type_ref,
                         value as _,
                         false as _)
        })
    }

    pub fn get_u8(context: &'a Context, value: u8) -> Self {
        context.wrap_value(unsafe {
            LLVMConstInt(Type::get_i8(context).type_ref,
                         value as _,
                         false as _)
        })
    }

    pub fn get_bool(context: &'a Context, value: bool) -> Self {
        context.wrap_value(unsafe {
            LLVMConstInt(Type::get_bool(context).type_ref,
                         value as _,
                         false as _)
        })
    }
}

#[derive(Copy, Clone)]
pub struct BasicBlock<'a> {
    bb_ref:  LLVMBasicBlockRef,
    _context: &'a Context,
}

#[derive(Copy, Clone)]
pub struct Builder<'a> {
    builder_ref: LLVMBuilderRef,
    context:     &'a Context,
}

impl<'a> Builder<'a> {
    pub fn new(context: &'a Context) -> Self {
        Builder {
            builder_ref: unsafe { LLVMCreateBuilderInContext(context.context_ref) },
            context:     context,
        }
    }

    pub fn position_at_end(&self, bb: BasicBlock<'a>) {
        unsafe {
            LLVMPositionBuilderAtEnd(self.builder_ref, bb.bb_ref);
        }
    }

    pub fn add(&self, v1: Value<'a>, v2: Value<'a>, name: &str) -> Value<'a> {
        let name = self.context.new_name(name);
        self.context.wrap_value(unsafe {
            LLVMBuildAdd(self.builder_ref, v1.value_ref, v2.value_ref, name)
        })
    }

    pub fn alloca(&self, ty: Type<'a>, name: &str) -> Value<'a> {
        let name = self.context.new_name(name);
        self.context.wrap_value(unsafe {
            LLVMBuildAlloca(self.builder_ref, ty.type_ref, name)
        })
    }

    pub fn array_alloca(&self, ty: Type<'a>, size: Value<'a>, name: &str) -> Value<'a> {
        let name = self.context.new_name(name);
        self.context.wrap_value(unsafe {
            LLVMBuildArrayAlloca(self.builder_ref,
                                 ty.type_ref,
                                 size.value_ref,
                                 name)
        })
    }

    pub fn br(&self, dst: BasicBlock<'a>) {
        unsafe {
            LLVMBuildBr(self.builder_ref, dst.bb_ref);
        }
    }

    pub fn call(&self, fun: Value<'a>, args: &[Value<'a>], name: &str) -> Value<'a> {
        let name = self.context.new_name(name);
        let mut args = args.into_iter().map(|arg| arg.value_ref).collect::<Vec<_>>();
        self.context.wrap_value(unsafe {
            LLVMBuildCall(self.builder_ref,
                          fun.value_ref,
                          args.as_mut_ptr(),
                          args.len() as u32,
                          name)
        })
    }

    pub fn cmp(&self, pred: LLVMIntPredicate, lhs: Value<'a>, rhs: Value<'a>,
               name: &str) -> Value<'a> {
        let name = self.context.new_name(name);
        self.context.wrap_value(unsafe {
            LLVMBuildICmp(self.builder_ref, pred, lhs.value_ref, rhs.value_ref, name)

        })
    }

    pub fn cond_br(&self, test: Value<'a>, then: BasicBlock<'a>, else_: BasicBlock<'a>) {
        unsafe {
            LLVMBuildCondBr(self.builder_ref, test.value_ref, then.bb_ref, else_.bb_ref);
        }
    }

    pub fn gep(&self, ptr: Value<'a>, indices: &[Value<'a>], name: &str) -> Value<'a> {
        let name = self.context.new_name(name);
        let mut indices = indices.into_iter().map(|i| i.value_ref).collect::<Vec<_>>();
        self.context.wrap_value(unsafe {
            LLVMBuildGEP(self.builder_ref,
                         ptr.value_ref,
                         indices.as_mut_ptr(),
                         indices.len() as u32,
                         name)
        })
    }

    pub fn load(&self, ptr: Value<'a>, name: &str) -> Value<'a> {
        let name = self.context.new_name(name);
        self.context.wrap_value(unsafe {
            LLVMBuildLoad(self.builder_ref, ptr.value_ref, name)
        })
    }

    pub fn ret(&self, value: Value<'a>) {
        unsafe {
            LLVMBuildRet(self.builder_ref, value.value_ref);
        }
    }

    pub fn store(&self, src: Value<'a>, dst: Value<'a>) {
        unsafe {
            LLVMBuildStore(self.builder_ref, src.value_ref, dst.value_ref);
        }
    }

    pub fn sub(&self, v1: Value<'a>, v2: Value<'a>, name: &str) -> Value<'a> {
        let name = self.context.new_name(name);
        self.context.wrap_value(unsafe {
            LLVMBuildSub(self.builder_ref, v1.value_ref, v2.value_ref, name)
        })
    }

    pub fn trunc(&self, value: Value<'a>, ty: Type<'a>, name: &str) -> Value<'a> {
        let name = self.context.new_name(name);
        self.context.wrap_value(unsafe {
            LLVMBuildTrunc(self.builder_ref, value.value_ref, ty.type_ref, name)
        })
    }

    pub fn zext(&self, value: Value<'a>, ty: Type<'a>, name: &str) -> Value<'a> {
        let name = self.context.new_name(name);
        self.context.wrap_value(unsafe {
            LLVMBuildZExt(self.builder_ref, value.value_ref, ty.type_ref, name)
        })
    }
}
<commit_msg>Initializing native target to try to get MCJIT working.<commit_after>use std::ffi::{CString, CStr};
use std::os::raw::c_char;
use std::ptr;
use std::cell::RefCell;

use llvm_sys::prelude::*;
use llvm_sys::core::*;
use llvm_sys::target::LLVM_InitializeNativeTarget;
use llvm_sys::analysis::{LLVMVerifyModule, LLVMVerifierFailureAction};
use llvm_sys::transforms::pass_manager_builder as builder;
use llvm_sys::execution_engine as engine;
pub use llvm_sys::LLVMIntPredicate;

// FIXME: Force to link against libffi
#[link(name = "ffi")]
extern {}

pub struct Context {
    context_ref: LLVMContextRef,
    strings:     RefCell<Vec<CString>>,
}

impl Context {
    pub fn new() -> Self {
        Context {
            context_ref: unsafe { LLVMContextCreate() },
            strings:     RefCell::new(Vec::new()),
        }
    }

    pub fn new_name(&self, name: &str) -> *const c_char {
        let string = CString::new(name).unwrap();
        let ptr    = string.as_ptr();
        self.strings.borrow_mut().push(string);
        ptr
    }

    fn wrap_value(&self, value_ref: LLVMValueRef) -> Value {
        Value {
            value_ref: value_ref,
            context:   self,
        }
    }

    fn wrap_type(&self, type_ref: LLVMTypeRef) -> Type {
        Type {
            type_ref: type_ref,
            context:  self,
        }
    }
}

impl Drop for Context {
    fn drop(&mut self) {
        unsafe {
            LLVMContextDispose(self.context_ref);
        }
    }
}

#[derive(Clone, Copy)]
pub struct Module<'a> {
    module_ref: LLVMModuleRef,
    context:    &'a Context,
}

impl<'a> Module<'a> {
    pub fn new(context: &'a Context, name: &str) -> Self {
        let name = context.new_name(name);
        Module {
            module_ref: unsafe {
                LLVMModuleCreateWithNameInContext(name, context.context_ref)
            },
            context: context,
        }
    }

    pub fn add_function(&self, name: &str, ty: Type<'a>) -> Value<'a> {
        let name = self.context.new_name(name);
        self.context.wrap_value(unsafe {
            LLVMAddFunction(self.module_ref, name, ty.type_ref)
        })
    }

    // From llvm-alt:
    pub fn optimize(&self, opt_level: usize, size_level: usize) {
        unsafe {
            let builder = builder::LLVMPassManagerBuilderCreate();
            builder::LLVMPassManagerBuilderSetOptLevel(builder, opt_level as _);
            builder::LLVMPassManagerBuilderSetSizeLevel(builder, size_level as _);
            let pass_manager = LLVMCreatePassManager();
            builder::LLVMPassManagerBuilderPopulateModulePassManager(builder, pass_manager);
            builder::LLVMPassManagerBuilderDispose(builder);
            LLVMRunPassManager(pass_manager, self.module_ref);
            LLVMDisposePassManager(pass_manager);
        }
    }

    pub fn dump(&self) {
        unsafe {
            LLVMDumpModule(self.module_ref);
        }
    }

    pub fn verify(&self) -> Result<(), String> {
        let mut out_message: *mut c_char = ptr::null_mut();

        unsafe {
            if LLVMVerifyModule(self.module_ref,
                                LLVMVerifierFailureAction::LLVMReturnStatusAction,
                                &mut out_message) == 0 {
                Ok(())
            } else {
                let result = CStr::from_ptr(out_message).to_string_lossy().into_owned();
                LLVMDisposeMessage(out_message);
                Err(result)
            }
        }
    }

    pub fn run_function(&self, fun: Value<'a>) -> Result<u64, String> {
        let mut out_message: *mut c_char = ptr::null_mut();
        let mut exec: engine::LLVMExecutionEngineRef = ptr::null_mut();

        unsafe {
            engine::LLVMLinkInMCJIT();

            if LLVM_InitializeNativeTarget() == 1 {
                panic!("Could not initialize native target for LLVM.");
            }

            if engine::LLVMCreateMCJITCompilerForModule(&mut exec,
                                                        self.module_ref,
                                                        ptr::null_mut(),
                                                        0,
                                                        &mut out_message) != 0 {
                let result = CStr::from_ptr(out_message).to_string_lossy().into_owned();
                LLVMDisposeMessage(out_message);
                return Err(result);
            }

            let size = engine::LLVMCreateGenericValueOfInt(Type::get_i64(self.context).type_ref,
                                                           30_000 as _,
                                                           0 as i32);
            let mut args = vec![size];
            let result = engine::LLVMRunFunction(exec,
                                                 fun.value_ref,
                                                 args.len() as u32,
                                                 args.as_mut_ptr());
            Ok(engine::LLVMGenericValueToInt(result, 0 as i32) as _)
        }
    }
}

#[derive(Copy, Clone)]
pub struct Type<'a> {
    type_ref:  LLVMTypeRef,
    context:   &'a Context,
}

impl<'a> Type<'a> {
    pub fn get_i64(context: &'a Context) -> Self {
        context.wrap_type(unsafe {
            LLVMInt64TypeInContext(context.context_ref)
        })
    }

    pub fn get_i32(context: &'a Context) -> Self {
        context.wrap_type(unsafe {
            LLVMInt32TypeInContext(context.context_ref)
        })
    }

    pub fn get_i8(context: &'a Context) -> Self {
        context.wrap_type(unsafe {
            LLVMInt8TypeInContext(context.context_ref)
        })
    }

    pub fn get_bool(context: &'a Context) -> Self {
        context.wrap_type(unsafe {
            LLVMInt1TypeInContext(context.context_ref)
        })
    }

    pub fn get_void(context: &'a Context) -> Self {
        context.wrap_type(unsafe {
            LLVMVoidTypeInContext(context.context_ref)
        })
    }

    pub fn get_pointer(target: Type<'a>) -> Self {
        target.context.wrap_type(unsafe {
            LLVMPointerType(target.type_ref, 0)
        })
    }

    pub fn get_function(args: &[Type<'a>], result: Type<'a>) -> Self {
        let mut args = args.into_iter().map(|arg| arg.type_ref).collect::<Vec<_>>();
        result.context.wrap_type(unsafe {
            LLVMFunctionType(result.type_ref,
                             args.as_mut_ptr(),
                             args.len() as _,
                             0)
        })
    }
}

#[derive(Copy, Clone)]
pub struct Value<'a> {
    value_ref: LLVMValueRef,
    context:   &'a Context,
}

impl<'a> Value<'a> {
//    pub fn get_fun_param(&self, index: usize) -> Self {
//        self.context.wrap_value(unsafe {
//            LLVMGetParam(self.value_ref, index as _)
//        })
//    }

    pub fn append(&self, name: &str) -> BasicBlock<'a> {
        let name = self.context.new_name(name);
        let bb_ref = unsafe {
            LLVMAppendBasicBlockInContext(self.context.context_ref,
                                          self.value_ref,
                                          name)
        };
        BasicBlock {
            bb_ref: bb_ref,
            _context: self.context,
        }
    }

    pub fn get_u64(context: &'a Context, value: u64) -> Self {
        context.wrap_value(unsafe {
            LLVMConstInt(Type::get_i64(context).type_ref,
                         value as _,
                         false as _)
        })
    }

    pub fn get_u32(context: &'a Context, value: u32) -> Self {
        context.wrap_value(unsafe {
            LLVMConstInt(Type::get_i32(context).type_ref,
                         value as _,
                         false as _)
        })
    }

    pub fn get_u8(context: &'a Context, value: u8) -> Self {
        context.wrap_value(unsafe {
            LLVMConstInt(Type::get_i8(context).type_ref,
                         value as _,
                         false as _)
        })
    }

    pub fn get_bool(context: &'a Context, value: bool) -> Self {
        context.wrap_value(unsafe {
            LLVMConstInt(Type::get_bool(context).type_ref,
                         value as _,
                         false as _)
        })
    }
}

#[derive(Copy, Clone)]
pub struct BasicBlock<'a> {
    bb_ref:  LLVMBasicBlockRef,
    _context: &'a Context,
}

#[derive(Copy, Clone)]
pub struct Builder<'a> {
    builder_ref: LLVMBuilderRef,
    context:     &'a Context,
}

impl<'a> Builder<'a> {
    pub fn new(context: &'a Context) -> Self {
        Builder {
            builder_ref: unsafe { LLVMCreateBuilderInContext(context.context_ref) },
            context:     context,
        }
    }

    pub fn position_at_end(&self, bb: BasicBlock<'a>) {
        unsafe {
            LLVMPositionBuilderAtEnd(self.builder_ref, bb.bb_ref);
        }
    }

    pub fn add(&self, v1: Value<'a>, v2: Value<'a>, name: &str) -> Value<'a> {
        let name = self.context.new_name(name);
        self.context.wrap_value(unsafe {
            LLVMBuildAdd(self.builder_ref, v1.value_ref, v2.value_ref, name)
        })
    }

    pub fn alloca(&self, ty: Type<'a>, name: &str) -> Value<'a> {
        let name = self.context.new_name(name);
        self.context.wrap_value(unsafe {
            LLVMBuildAlloca(self.builder_ref, ty.type_ref, name)
        })
    }

    pub fn array_alloca(&self, ty: Type<'a>, size: Value<'a>, name: &str) -> Value<'a> {
        let name = self.context.new_name(name);
        self.context.wrap_value(unsafe {
            LLVMBuildArrayAlloca(self.builder_ref,
                                 ty.type_ref,
                                 size.value_ref,
                                 name)
        })
    }

    pub fn br(&self, dst: BasicBlock<'a>) {
        unsafe {
            LLVMBuildBr(self.builder_ref, dst.bb_ref);
        }
    }

    pub fn call(&self, fun: Value<'a>, args: &[Value<'a>], name: &str) -> Value<'a> {
        let name = self.context.new_name(name);
        let mut args = args.into_iter().map(|arg| arg.value_ref).collect::<Vec<_>>();
        self.context.wrap_value(unsafe {
            LLVMBuildCall(self.builder_ref,
                          fun.value_ref,
                          args.as_mut_ptr(),
                          args.len() as u32,
                          name)
        })
    }

    pub fn cmp(&self, pred: LLVMIntPredicate, lhs: Value<'a>, rhs: Value<'a>,
               name: &str) -> Value<'a> {
        let name = self.context.new_name(name);
        self.context.wrap_value(unsafe {
            LLVMBuildICmp(self.builder_ref, pred, lhs.value_ref, rhs.value_ref, name)

        })
    }

    pub fn cond_br(&self, test: Value<'a>, then: BasicBlock<'a>, else_: BasicBlock<'a>) {
        unsafe {
            LLVMBuildCondBr(self.builder_ref, test.value_ref, then.bb_ref, else_.bb_ref);
        }
    }

    pub fn gep(&self, ptr: Value<'a>, indices: &[Value<'a>], name: &str) -> Value<'a> {
        let name = self.context.new_name(name);
        let mut indices = indices.into_iter().map(|i| i.value_ref).collect::<Vec<_>>();
        self.context.wrap_value(unsafe {
            LLVMBuildGEP(self.builder_ref,
                         ptr.value_ref,
                         indices.as_mut_ptr(),
                         indices.len() as u32,
                         name)
        })
    }

    pub fn load(&self, ptr: Value<'a>, name: &str) -> Value<'a> {
        let name = self.context.new_name(name);
        self.context.wrap_value(unsafe {
            LLVMBuildLoad(self.builder_ref, ptr.value_ref, name)
        })
    }

    pub fn ret(&self, value: Value<'a>) {
        unsafe {
            LLVMBuildRet(self.builder_ref, value.value_ref);
        }
    }

    pub fn store(&self, src: Value<'a>, dst: Value<'a>) {
        unsafe {
            LLVMBuildStore(self.builder_ref, src.value_ref, dst.value_ref);
        }
    }

    pub fn sub(&self, v1: Value<'a>, v2: Value<'a>, name: &str) -> Value<'a> {
        let name = self.context.new_name(name);
        self.context.wrap_value(unsafe {
            LLVMBuildSub(self.builder_ref, v1.value_ref, v2.value_ref, name)
        })
    }

    pub fn trunc(&self, value: Value<'a>, ty: Type<'a>, name: &str) -> Value<'a> {
        let name = self.context.new_name(name);
        self.context.wrap_value(unsafe {
            LLVMBuildTrunc(self.builder_ref, value.value_ref, ty.type_ref, name)
        })
    }

    pub fn zext(&self, value: Value<'a>, ty: Type<'a>, name: &str) -> Value<'a> {
        let name = self.context.new_name(name);
        self.context.wrap_value(unsafe {
            LLVMBuildZExt(self.builder_ref, value.value_ref, ty.type_ref, name)
        })
    }
}
<|endoftext|>