<commit_before>#![allow(missing_docs)]

use std::collections::{
    BTreeMap,
    BTreeSet,
    HashMap,
    HashSet,
    btree_map,
    btree_set,
    hash_map,
    hash_set,
};
use std::hash::Hash;
use std::vec;

use de;
use bytes;

///////////////////////////////////////////////////////////////////////////////

#[derive(Clone, Debug, PartialEq)]
pub enum Error {
    SyntaxError,
    EndOfStreamError,
    UnknownFieldError(String),
    MissingFieldError(&'static str),
}

impl de::Error for Error {
    fn syntax(_: &str) -> Self { Error::SyntaxError }
    fn end_of_stream() -> Self { Error::EndOfStreamError }
    fn unknown_field(field: &str) -> Self { Error::UnknownFieldError(String::from(field)) }
    fn missing_field(field: &'static str) -> Self { Error::MissingFieldError(field) }
}

///////////////////////////////////////////////////////////////////////////////

pub trait ValueDeserializer {
    type Deserializer: de::Deserializer<Error=Error>;

    fn into_deserializer(self) -> Self::Deserializer;
}

///////////////////////////////////////////////////////////////////////////////

impl ValueDeserializer for () {
    type Deserializer = UnitDeserializer;

    fn into_deserializer(self) -> UnitDeserializer {
        UnitDeserializer
    }
}

/// A helper deserializer that deserializes a `()`.
pub struct UnitDeserializer;

impl de::Deserializer for UnitDeserializer {
    type Error = Error;

    fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
        where V: de::Visitor,
    {
        visitor.visit_unit()
    }

    fn visit_option<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
        where V: de::Visitor,
    {
        visitor.visit_none()
    }
}

///////////////////////////////////////////////////////////////////////////////

macro_rules! primitive_deserializer {
    ($ty:ty, $name:ident, $method:ident) => {
        pub struct $name(Option<$ty>);

        impl ValueDeserializer for $ty {
            type Deserializer = $name;

            fn into_deserializer(self) -> $name {
                $name(Some(self))
            }
        }

        impl de::Deserializer for $name {
            type Error = Error;

            fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
                where V: de::Visitor,
            {
                match self.0.take() {
                    Some(v) => visitor.$method(v),
                    None => Err(de::Error::end_of_stream()),
                }
            }
        }
    }
}

primitive_deserializer!(bool, BoolDeserializer, visit_bool);
primitive_deserializer!(i8, I8Deserializer, visit_i8);
primitive_deserializer!(i16, I16Deserializer, visit_i16);
primitive_deserializer!(i32, I32Deserializer, visit_i32);
primitive_deserializer!(i64, I64Deserializer, visit_i64);
primitive_deserializer!(isize, IsizeDeserializer, visit_isize);
primitive_deserializer!(u8, U8Deserializer, visit_u8);
primitive_deserializer!(u16, U16Deserializer, visit_u16);
primitive_deserializer!(u32, U32Deserializer, visit_u32);
primitive_deserializer!(u64, U64Deserializer, visit_u64);
primitive_deserializer!(usize, UsizeDeserializer, visit_usize);
primitive_deserializer!(f32, F32Deserializer, visit_f32);
primitive_deserializer!(f64, F64Deserializer, visit_f64);
primitive_deserializer!(char, CharDeserializer, visit_char);

///////////////////////////////////////////////////////////////////////////////

/// A helper deserializer that deserializes a `&str`.
pub struct StrDeserializer<'a>(Option<&'a str>);

impl<'a> ValueDeserializer for &'a str {
    type Deserializer = StrDeserializer<'a>;

    fn into_deserializer(self) -> StrDeserializer<'a> {
        StrDeserializer(Some(self))
    }
}

impl<'a> de::Deserializer for StrDeserializer<'a> {
    type Error = Error;

    fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
        where V: de::Visitor,
    {
        match self.0.take() {
            Some(v) => visitor.visit_str(v),
            None => Err(de::Error::end_of_stream()),
        }
    }

    fn visit_enum<V>(&mut self,
                     _name: &str,
                     _variants: &'static [&'static str],
                     mut visitor: V) -> Result<V::Value, Error>
        where V: de::EnumVisitor,
    {
        visitor.visit(self)
    }
}

impl<'a> de::VariantVisitor for StrDeserializer<'a> {
    type Error = Error;

    fn visit_variant<T>(&mut self) -> Result<T, Error>
        where T: de::Deserialize,
    {
        de::Deserialize::deserialize(self)
    }

    fn visit_unit(&mut self) -> Result<(), Error> {
        Ok(())
    }
}

///////////////////////////////////////////////////////////////////////////////

/// A helper deserializer that deserializes a `String`.
pub struct StringDeserializer(Option<String>);

impl ValueDeserializer for String {
    type Deserializer = StringDeserializer;

    fn into_deserializer(self) -> StringDeserializer {
        StringDeserializer(Some(self))
    }
}

impl de::Deserializer for StringDeserializer {
    type Error = Error;

    fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
        where V: de::Visitor,
    {
        match self.0.take() {
            Some(string) => visitor.visit_string(string),
            None => Err(de::Error::end_of_stream()),
        }
    }

    fn visit_enum<V>(&mut self,
                     _name: &str,
                     _variants: &'static [&'static str],
                     mut visitor: V) -> Result<V::Value, Error>
        where V: de::EnumVisitor,
    {
        visitor.visit(self)
    }
}

impl<'a> de::VariantVisitor for StringDeserializer {
    type Error = Error;

    fn visit_variant<T>(&mut self) -> Result<T, Error>
        where T: de::Deserialize,
    {
        de::Deserialize::deserialize(self)
    }

    fn visit_unit(&mut self) -> Result<(), Error> {
        Ok(())
    }
}

///////////////////////////////////////////////////////////////////////////////

pub struct SeqDeserializer<I> {
    iter: I,
    len: usize,
}

impl<I> SeqDeserializer<I> {
    pub fn new(iter: I, len: usize) -> Self {
        SeqDeserializer {
            iter: iter,
            len: len,
        }
    }
}

impl<I, T> de::Deserializer for SeqDeserializer<I>
    where I: Iterator<Item=T>,
          T: ValueDeserializer,
{
    type Error = Error;

    fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
        where V: de::Visitor,
    {
        visitor.visit_seq(self)
    }
}

impl<I, T> de::SeqVisitor for SeqDeserializer<I>
    where I: Iterator<Item=T>,
          T: ValueDeserializer,
{
    type Error = Error;

    fn visit<V>(&mut self) -> Result<Option<V>, Error>
        where V: de::Deserialize
    {
        match self.iter.next() {
            Some(value) => {
                self.len -= 1;
                let mut de = value.into_deserializer();
                Ok(Some(try!(de::Deserialize::deserialize(&mut de))))
            }
            None => Ok(None),
        }
    }

    fn end(&mut self) -> Result<(), Error> {
        if self.len == 0 {
            Ok(())
        } else {
            Err(de::Error::length_mismatch(self.len))
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        (self.len, Some(self.len))
    }
}

///////////////////////////////////////////////////////////////////////////////

impl<T> ValueDeserializer for Vec<T>
    where T: ValueDeserializer,
{
    type Deserializer = SeqDeserializer<vec::IntoIter<T>>;

    fn into_deserializer(self) -> SeqDeserializer<vec::IntoIter<T>> {
        let len = self.len();
        SeqDeserializer::new(self.into_iter(), len)
    }
}

impl<T> ValueDeserializer for BTreeSet<T>
    where T: ValueDeserializer + Eq + Ord,
{
    type Deserializer = SeqDeserializer<btree_set::IntoIter<T>>;

    fn into_deserializer(self) -> SeqDeserializer<btree_set::IntoIter<T>> {
        let len = self.len();
        SeqDeserializer::new(self.into_iter(), len)
    }
}

impl<T> ValueDeserializer for HashSet<T>
    where T: ValueDeserializer + Eq + Hash,
{
    type Deserializer = SeqDeserializer<hash_set::IntoIter<T>>;

    fn into_deserializer(self) -> SeqDeserializer<hash_set::IntoIter<T>> {
        let len = self.len();
        SeqDeserializer::new(self.into_iter(), len)
    }
}

///////////////////////////////////////////////////////////////////////////////

pub struct MapDeserializer<I, K, V>
    where I: Iterator<Item=(K, V)>,
          K: ValueDeserializer,
          V: ValueDeserializer,
{
    iter: I,
    value: Option<V>,
    len: usize,
}

impl<I, K, V> MapDeserializer<I, K, V>
    where I: Iterator<Item=(K, V)>,
          K: ValueDeserializer,
          V: ValueDeserializer,
{
    pub fn new(iter: I, len: usize) -> Self {
        MapDeserializer {
            iter: iter,
            value: None,
            len: len,
        }
    }
}

impl<I, K, V> de::Deserializer for MapDeserializer<I, K, V>
    where I: Iterator<Item=(K, V)>,
          K: ValueDeserializer,
          V: ValueDeserializer,
{
    type Error = Error;

    fn visit<V_>(&mut self, mut visitor: V_) -> Result<V_::Value, Error>
        where V_: de::Visitor,
    {
        visitor.visit_map(self)
    }
}

impl<I, K, V> de::MapVisitor for MapDeserializer<I, K, V>
    where I: Iterator<Item=(K, V)>,
          K: ValueDeserializer,
          V: ValueDeserializer,
{
    type Error = Error;

    fn visit_key<T>(&mut self) -> Result<Option<T>, Error>
        where T: de::Deserialize,
    {
        match self.iter.next() {
            Some((key, value)) => {
                self.len -= 1;
                self.value = Some(value);
                let mut de = key.into_deserializer();
                Ok(Some(try!(de::Deserialize::deserialize(&mut de))))
            }
            None => Ok(None),
        }
    }

    fn visit_value<T>(&mut self) -> Result<T, Error>
        where T: de::Deserialize,
    {
        match self.value.take() {
            Some(value) => {
                let mut de = value.into_deserializer();
                de::Deserialize::deserialize(&mut de)
            }
            None => Err(de::Error::syntax("expected a map value"))
        }
    }

    fn end(&mut self) -> Result<(), Error> {
        if self.len == 0 {
            Ok(())
        } else {
            Err(de::Error::length_mismatch(self.len))
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        (self.len, Some(self.len))
    }
}

///////////////////////////////////////////////////////////////////////////////

impl<K, V> ValueDeserializer for BTreeMap<K, V>
    where K: ValueDeserializer + Eq + Ord,
          V: ValueDeserializer,
{
    type Deserializer = MapDeserializer<btree_map::IntoIter<K, V>, K, V>;

    fn into_deserializer(self) -> MapDeserializer<btree_map::IntoIter<K, V>, K, V> {
        let len = self.len();
        MapDeserializer::new(self.into_iter(), len)
    }
}

impl<K, V> ValueDeserializer for HashMap<K, V>
    where K: ValueDeserializer + Eq + Hash,
          V: ValueDeserializer,
{
    type Deserializer = MapDeserializer<hash_map::IntoIter<K, V>, K, V>;

    fn into_deserializer(self) -> MapDeserializer<hash_map::IntoIter<K, V>, K, V> {
        let len = self.len();
        MapDeserializer::new(self.into_iter(), len)
    }
}

///////////////////////////////////////////////////////////////////////////////

impl<'a> ValueDeserializer for bytes::Bytes<'a>
{
    type Deserializer = BytesDeserializer<'a>;

    fn into_deserializer(self) -> BytesDeserializer<'a> {
        BytesDeserializer(Some(self.into()))
    }
}

pub struct BytesDeserializer<'a> (Option<&'a [u8]>);

impl<'a> de::Deserializer for BytesDeserializer<'a> {
    type Error = Error;

    fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
        where V: de::Visitor,
    {
        match self.0.take() {
            Some(bytes) => visitor.visit_bytes(bytes),
            None => Err(de::Error::end_of_stream()),
        }
    }
}

///////////////////////////////////////////////////////////////////////////////

impl ValueDeserializer for bytes::ByteBuf
{
    type Deserializer = ByteBufDeserializer;

    fn into_deserializer(self) -> Self::Deserializer {
        ByteBufDeserializer(Some(self.into()))
    }
}

pub struct ByteBufDeserializer(Option<Vec<u8>>);

impl de::Deserializer for ByteBufDeserializer {
    type Error = Error;

    fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
        where V: de::Visitor,
    {
        match self.0.take() {
            Some(bytes) => visitor.visit_byte_buf(bytes),
            None => Err(de::Error::end_of_stream()),
        }
    }
}
<commit_msg>Document serde::de::value<commit_after>//! This module supports deserializing from primitives with the `ValueDeserializer` trait.

use std::collections::{
    BTreeMap,
    BTreeSet,
    HashMap,
    HashSet,
    btree_map,
    btree_set,
    hash_map,
    hash_set,
};
use std::hash::Hash;
use std::vec;

use de;
use bytes;

///////////////////////////////////////////////////////////////////////////////

/// This represents all the possible errors that can occur using the `ValueDeserializer`.
#[derive(Clone, Debug, PartialEq)]
pub enum Error {
    /// The value had some syntatic error.
    SyntaxError,

    /// EOF while deserializing a value.
    EndOfStreamError,

    /// Unknown field in struct.
    UnknownFieldError(String),

    /// Struct is missing a field.
    MissingFieldError(&'static str),
}

impl de::Error for Error {
    fn syntax(_: &str) -> Self { Error::SyntaxError }
    fn end_of_stream() -> Self { Error::EndOfStreamError }
    fn unknown_field(field: &str) -> Self { Error::UnknownFieldError(String::from(field)) }
    fn missing_field(field: &'static str) -> Self { Error::MissingFieldError(field) }
}

///////////////////////////////////////////////////////////////////////////////

/// This trait converts primitive types into a deserializer.
pub trait ValueDeserializer {
    /// The actual deserializer type.
    type Deserializer: de::Deserializer<Error=Error>;

    /// Convert this value into a deserializer.
    fn into_deserializer(self) -> Self::Deserializer;
}

///////////////////////////////////////////////////////////////////////////////

impl ValueDeserializer for () {
    type Deserializer = UnitDeserializer;

    fn into_deserializer(self) -> UnitDeserializer {
        UnitDeserializer
    }
}

/// A helper deserializer that deserializes a `()`.
pub struct UnitDeserializer;

impl de::Deserializer for UnitDeserializer {
    type Error = Error;

    fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
        where V: de::Visitor,
    {
        visitor.visit_unit()
    }

    fn visit_option<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
        where V: de::Visitor,
    {
        visitor.visit_none()
    }
}

///////////////////////////////////////////////////////////////////////////////

macro_rules! primitive_deserializer {
    ($ty:ty, $name:ident, $method:ident) => {
        /// A helper deserializer that deserializes a number.
        pub struct $name(Option<$ty>);

        impl ValueDeserializer for $ty {
            type Deserializer = $name;

            fn into_deserializer(self) -> $name {
                $name(Some(self))
            }
        }

        impl de::Deserializer for $name {
            type Error = Error;

            fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
                where V: de::Visitor,
            {
                match self.0.take() {
                    Some(v) => visitor.$method(v),
                    None => Err(de::Error::end_of_stream()),
                }
            }
        }
    }
}

primitive_deserializer!(bool, BoolDeserializer, visit_bool);
primitive_deserializer!(i8, I8Deserializer, visit_i8);
primitive_deserializer!(i16, I16Deserializer, visit_i16);
primitive_deserializer!(i32, I32Deserializer, visit_i32);
primitive_deserializer!(i64, I64Deserializer, visit_i64);
primitive_deserializer!(isize, IsizeDeserializer, visit_isize);
primitive_deserializer!(u8, U8Deserializer, visit_u8);
primitive_deserializer!(u16, U16Deserializer, visit_u16);
primitive_deserializer!(u32, U32Deserializer, visit_u32);
primitive_deserializer!(u64, U64Deserializer, visit_u64);
primitive_deserializer!(usize, UsizeDeserializer, visit_usize);
primitive_deserializer!(f32, F32Deserializer, visit_f32);
primitive_deserializer!(f64, F64Deserializer, visit_f64);
primitive_deserializer!(char, CharDeserializer, visit_char);

///////////////////////////////////////////////////////////////////////////////

/// A helper deserializer that deserializes a `&str`.
pub struct StrDeserializer<'a>(Option<&'a str>);

impl<'a> ValueDeserializer for &'a str {
    type Deserializer = StrDeserializer<'a>;

    fn into_deserializer(self) -> StrDeserializer<'a> {
        StrDeserializer(Some(self))
    }
}

impl<'a> de::Deserializer for StrDeserializer<'a> {
    type Error = Error;

    fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
        where V: de::Visitor,
    {
        match self.0.take() {
            Some(v) => visitor.visit_str(v),
            None => Err(de::Error::end_of_stream()),
        }
    }

    fn visit_enum<V>(&mut self,
                     _name: &str,
                     _variants: &'static [&'static str],
                     mut visitor: V) -> Result<V::Value, Error>
        where V: de::EnumVisitor,
    {
        visitor.visit(self)
    }
}

impl<'a> de::VariantVisitor for StrDeserializer<'a> {
    type Error = Error;

    fn visit_variant<T>(&mut self) -> Result<T, Error>
        where T: de::Deserialize,
    {
        de::Deserialize::deserialize(self)
    }

    fn visit_unit(&mut self) -> Result<(), Error> {
        Ok(())
    }
}

///////////////////////////////////////////////////////////////////////////////

/// A helper deserializer that deserializes a `String`.
pub struct StringDeserializer(Option<String>);

impl ValueDeserializer for String {
    type Deserializer = StringDeserializer;

    fn into_deserializer(self) -> StringDeserializer {
        StringDeserializer(Some(self))
    }
}

impl de::Deserializer for StringDeserializer {
    type Error = Error;

    fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
        where V: de::Visitor,
    {
        match self.0.take() {
            Some(string) => visitor.visit_string(string),
            None => Err(de::Error::end_of_stream()),
        }
    }

    fn visit_enum<V>(&mut self,
                     _name: &str,
                     _variants: &'static [&'static str],
                     mut visitor: V) -> Result<V::Value, Error>
        where V: de::EnumVisitor,
    {
        visitor.visit(self)
    }
}

impl<'a> de::VariantVisitor for StringDeserializer {
    type Error = Error;

    fn visit_variant<T>(&mut self) -> Result<T, Error>
        where T: de::Deserialize,
    {
        de::Deserialize::deserialize(self)
    }

    fn visit_unit(&mut self) -> Result<(), Error> {
        Ok(())
    }
}

///////////////////////////////////////////////////////////////////////////////

/// A helper deserializer that deserializes a sequence.
pub struct SeqDeserializer<I> {
    iter: I,
    len: usize,
}

impl<I> SeqDeserializer<I> {
    /// Construct a new `SeqDeserializer<I>`.
    pub fn new(iter: I, len: usize) -> Self {
        SeqDeserializer {
            iter: iter,
            len: len,
        }
    }
}

impl<I, T> de::Deserializer for SeqDeserializer<I>
    where I: Iterator<Item=T>,
          T: ValueDeserializer,
{
    type Error = Error;

    fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
        where V: de::Visitor,
    {
        visitor.visit_seq(self)
    }
}

impl<I, T> de::SeqVisitor for SeqDeserializer<I>
    where I: Iterator<Item=T>,
          T: ValueDeserializer,
{
    type Error = Error;

    fn visit<V>(&mut self) -> Result<Option<V>, Error>
        where V: de::Deserialize
    {
        match self.iter.next() {
            Some(value) => {
                self.len -= 1;
                let mut de = value.into_deserializer();
                Ok(Some(try!(de::Deserialize::deserialize(&mut de))))
            }
            None => Ok(None),
        }
    }

    fn end(&mut self) -> Result<(), Error> {
        if self.len == 0 {
            Ok(())
        } else {
            Err(de::Error::length_mismatch(self.len))
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        (self.len, Some(self.len))
    }
}

///////////////////////////////////////////////////////////////////////////////

impl<T> ValueDeserializer for Vec<T>
    where T: ValueDeserializer,
{
    type Deserializer = SeqDeserializer<vec::IntoIter<T>>;

    fn into_deserializer(self) -> SeqDeserializer<vec::IntoIter<T>> {
        let len = self.len();
        SeqDeserializer::new(self.into_iter(), len)
    }
}

impl<T> ValueDeserializer for BTreeSet<T>
    where T: ValueDeserializer + Eq + Ord,
{
    type Deserializer = SeqDeserializer<btree_set::IntoIter<T>>;

    fn into_deserializer(self) -> SeqDeserializer<btree_set::IntoIter<T>> {
        let len = self.len();
        SeqDeserializer::new(self.into_iter(), len)
    }
}

impl<T> ValueDeserializer for HashSet<T>
    where T: ValueDeserializer + Eq + Hash,
{
    type Deserializer = SeqDeserializer<hash_set::IntoIter<T>>;

    fn into_deserializer(self) -> SeqDeserializer<hash_set::IntoIter<T>> {
        let len = self.len();
        SeqDeserializer::new(self.into_iter(), len)
    }
}

///////////////////////////////////////////////////////////////////////////////

/// A helper deserializer that deserializes a map.
pub struct MapDeserializer<I, K, V>
    where I: Iterator<Item=(K, V)>,
          K: ValueDeserializer,
          V: ValueDeserializer,
{
    iter: I,
    value: Option<V>,
    len: usize,
}

impl<I, K, V> MapDeserializer<I, K, V>
    where I: Iterator<Item=(K, V)>,
          K: ValueDeserializer,
          V: ValueDeserializer,
{
    /// Construct a new `MapDeserializer<I, K, V>`.
    pub fn new(iter: I, len: usize) -> Self {
        MapDeserializer {
            iter: iter,
            value: None,
            len: len,
        }
    }
}

impl<I, K, V> de::Deserializer for MapDeserializer<I, K, V>
    where I: Iterator<Item=(K, V)>,
          K: ValueDeserializer,
          V: ValueDeserializer,
{
    type Error = Error;

    fn visit<V_>(&mut self, mut visitor: V_) -> Result<V_::Value, Error>
        where V_: de::Visitor,
    {
        visitor.visit_map(self)
    }
}

impl<I, K, V> de::MapVisitor for MapDeserializer<I, K, V>
    where I: Iterator<Item=(K, V)>,
          K: ValueDeserializer,
          V: ValueDeserializer,
{
    type Error = Error;

    fn visit_key<T>(&mut self) -> Result<Option<T>, Error>
        where T: de::Deserialize,
    {
        match self.iter.next() {
            Some((key, value)) => {
                self.len -= 1;
                self.value = Some(value);
                let mut de = key.into_deserializer();
                Ok(Some(try!(de::Deserialize::deserialize(&mut de))))
            }
            None => Ok(None),
        }
    }

    fn visit_value<T>(&mut self) -> Result<T, Error>
        where T: de::Deserialize,
    {
        match self.value.take() {
            Some(value) => {
                let mut de = value.into_deserializer();
                de::Deserialize::deserialize(&mut de)
            }
            None => Err(de::Error::syntax("expected a map value"))
        }
    }

    fn end(&mut self) -> Result<(), Error> {
        if self.len == 0 {
            Ok(())
        } else {
            Err(de::Error::length_mismatch(self.len))
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        (self.len, Some(self.len))
    }
}

///////////////////////////////////////////////////////////////////////////////

impl<K, V> ValueDeserializer for BTreeMap<K, V>
    where K: ValueDeserializer + Eq + Ord,
          V: ValueDeserializer,
{
    type Deserializer = MapDeserializer<btree_map::IntoIter<K, V>, K, V>;

    fn into_deserializer(self) -> MapDeserializer<btree_map::IntoIter<K, V>, K, V> {
        let len = self.len();
        MapDeserializer::new(self.into_iter(), len)
    }
}

impl<K, V> ValueDeserializer for HashMap<K, V>
    where K: ValueDeserializer + Eq + Hash,
          V: ValueDeserializer,
{
    type Deserializer = MapDeserializer<hash_map::IntoIter<K, V>, K, V>;

    fn into_deserializer(self) -> MapDeserializer<hash_map::IntoIter<K, V>, K, V> {
        let len = self.len();
        MapDeserializer::new(self.into_iter(), len)
    }
}

///////////////////////////////////////////////////////////////////////////////

impl<'a> ValueDeserializer for bytes::Bytes<'a>
{
    type Deserializer = BytesDeserializer<'a>;

    fn into_deserializer(self) -> BytesDeserializer<'a> {
        BytesDeserializer(Some(self.into()))
    }
}

/// A helper deserializer that deserializes a `&[u8]`.
pub struct BytesDeserializer<'a> (Option<&'a [u8]>);

impl<'a> de::Deserializer for BytesDeserializer<'a> {
    type Error = Error;

    fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
        where V: de::Visitor,
    {
        match self.0.take() {
            Some(bytes) => visitor.visit_bytes(bytes),
            None => Err(de::Error::end_of_stream()),
        }
    }
}

///////////////////////////////////////////////////////////////////////////////

impl ValueDeserializer for bytes::ByteBuf
{
    type Deserializer = ByteBufDeserializer;

    fn into_deserializer(self) -> Self::Deserializer {
        ByteBufDeserializer(Some(self.into()))
    }
}

/// A helper deserializer that deserializes a `Vec<u8>`.
pub struct ByteBufDeserializer(Option<Vec<u8>>);

impl de::Deserializer for ByteBufDeserializer {
    type Error = Error;

    fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
        where V: de::Visitor,
    {
        match self.0.take() {
            Some(bytes) => visitor.visit_byte_buf(bytes),
            None => Err(de::Error::end_of_stream()),
        }
    }
}
<|endoftext|>


<commit_before>//! Defines `SimpleJITBackend`.

use cranelift_codegen::binemit::{Addend, CodeOffset, NullTrapSink, Reloc, RelocSink};
use cranelift_codegen::isa::TargetIsa;
use cranelift_codegen::{self, ir, settings};
use cranelift_module::{
    Backend, DataContext, DataDescription, Init, Linkage, ModuleNamespace, ModuleResult,
    Writability,
};
use cranelift_native;
use libc;
use memory::Memory;
use std::collections::HashMap;
use std::ffi::CString;
use std::ptr;
use target_lexicon::PointerWidth;
#[cfg(windows)]
use winapi;

/// A builder for `SimpleJITBackend`.
pub struct SimpleJITBuilder {
    isa: Box<TargetIsa>,
    symbols: HashMap<String, *const u8>,
}

impl SimpleJITBuilder {
    /// Create a new `SimpleJITBuilder`.
    pub fn new() -> Self {
        let (flag_builder, isa_builder) = cranelift_native::builders().unwrap_or_else(|_| {
            panic!("host machine is not a supported target");
        });
        let isa = isa_builder.finish(settings::Flags::new(flag_builder));
        Self::with_isa(isa)
    }

    /// Create a new `SimpleJITBuilder` with an arbitrary target. This is mainly
    /// useful for testing.
    ///
    /// SimpleJIT requires a `TargetIsa` configured for non-PIC.
    ///
    /// To create a `SimpleJITBuilder` for native use, use the `new` constructor
    /// instead.
    pub fn with_isa(isa: Box<TargetIsa>) -> Self {
        debug_assert!(!isa.flags().is_pic(), "SimpleJIT requires non-PIC code");
        let symbols = HashMap::new();
        Self { isa, symbols }
    }

    /// Define a symbol in the internal symbol table.
    ///
    /// The JIT will use the symbol table to resolve names that are declared,
    /// but not defined, in the module being compiled.  A common example is
    /// external functions.  With this method, functions and data can be exposed
    /// to the code being compiled which are defined by the host.
    ///
    /// If a symbol is defined more than once, the most recent definition will
    /// be retained.
    ///
    /// If the JIT fails to find a symbol in its internal table, it will fall
    /// back to a platform-specific search (this typically involves searching
    /// the current process for public symbols, followed by searching the
    /// platform's C runtime).
    pub fn symbol<'a, K>(&'a mut self, name: K, ptr: *const u8) -> &'a mut Self
    where
        K: Into<String>,
    {
        self.symbols.insert(name.into(), ptr);
        self
    }

    /// Define multiple symbols in the internal symbol table.
    ///
    /// Using this is equivalent to calling `symbol` on each element.
    pub fn symbols<'a, It, K>(&'a mut self, symbols: It) -> &'a mut Self
    where
        It: IntoIterator<Item = (K, *const u8)>,
        K: Into<String>,
    {
        for (name, ptr) in symbols {
            self.symbols.insert(name.into(), ptr);
        }
        self
    }
}

/// A `SimpleJITBackend` implements `Backend` and emits code and data into memory where it can be
/// directly called and accessed.
pub struct SimpleJITBackend {
    isa: Box<TargetIsa>,
    symbols: HashMap<String, *const u8>,
    code_memory: Memory,
    readonly_memory: Memory,
    writable_memory: Memory,
}

/// A record of a relocation to perform.
struct RelocRecord {
    offset: CodeOffset,
    reloc: Reloc,
    name: ir::ExternalName,
    addend: Addend,
}

pub struct SimpleJITCompiledFunction {
    code: *mut u8,
    size: usize,
    relocs: Vec<RelocRecord>,
}

pub struct SimpleJITCompiledData {
    storage: *mut u8,
    size: usize,
    relocs: Vec<RelocRecord>,
}

impl SimpleJITBackend {
    fn lookup_symbol(&self, name: &str) -> *const u8 {
        match self.symbols.get(name) {
            Some(&ptr) => ptr,
            None => lookup_with_dlsym(name),
        }
    }
}

impl<'simple_jit_backend> Backend for SimpleJITBackend {
    type Builder = SimpleJITBuilder;

    /// SimpleJIT compiled function and data objects may have outstanding
    /// relocations that need to be performed before the memory can be used.
    /// These relocations are performed within `finalize_function` and
    /// `finalize_data`.
    type CompiledFunction = SimpleJITCompiledFunction;
    type CompiledData = SimpleJITCompiledData;

    /// SimpleJIT emits code and data into memory, and provides raw pointers
    /// to them.
    type FinalizedFunction = *const u8;
    type FinalizedData = (*mut u8, usize);

    /// SimpleJIT emits code and data into memory as it processes them, so it
    /// doesn't need to provide anything after the `Module` is complete.
    type Product = ();

    /// Create a new `SimpleJITBackend`.
    fn new(builder: SimpleJITBuilder) -> Self {
        Self {
            isa: builder.isa,
            symbols: builder.symbols,
            code_memory: Memory::new(),
            readonly_memory: Memory::new(),
            writable_memory: Memory::new(),
        }
    }

    fn isa(&self) -> &TargetIsa {
        &*self.isa
    }

    fn declare_function(&mut self, _name: &str, _linkage: Linkage) {
        // Nothing to do.
    }

    fn declare_data(&mut self, _name: &str, _linkage: Linkage, _writable: bool) {
        // Nothing to do.
    }

    fn define_function(
        &mut self,
        _name: &str,
        ctx: &cranelift_codegen::Context,
        _namespace: &ModuleNamespace<Self>,
        code_size: u32,
    ) -> ModuleResult<Self::CompiledFunction> {
        let size = code_size as usize;
        let ptr = self
            .code_memory
            .allocate(size)
            .expect("TODO: handle OOM etc.");
        let mut reloc_sink = SimpleJITRelocSink::new();
        // Ignore traps for now. For now, frontends should just avoid generating code
        // that traps.
        let mut trap_sink = NullTrapSink {};
        unsafe { ctx.emit_to_memory(&*self.isa, ptr, &mut reloc_sink, &mut trap_sink) };

        Ok(Self::CompiledFunction {
            code: ptr,
            size,
            relocs: reloc_sink.relocs,
        })
    }

    fn define_data(
        &mut self,
        _name: &str,
        data: &DataContext,
        _namespace: &ModuleNamespace<Self>,
    ) -> ModuleResult<Self::CompiledData> {
        let &DataDescription {
            writable,
            ref init,
            ref function_decls,
            ref data_decls,
            ref function_relocs,
            ref data_relocs,
        } = data.description();

        let size = init.size();
        let storage = match writable {
            Writability::Readonly => self
                .writable_memory
                .allocate(size)
                .expect("TODO: handle OOM etc."),
            Writability::Writable => self
                .writable_memory
                .allocate(size)
                .expect("TODO: handle OOM etc."),
        };

        match *init {
            Init::Uninitialized => {
                panic!("data is not initialized yet");
            }
            Init::Zeros { .. } => {
                unsafe { ptr::write_bytes(storage, 0, size) };
            }
            Init::Bytes { ref contents } => {
                let src = contents.as_ptr();
                unsafe { ptr::copy_nonoverlapping(src, storage, size) };
            }
        }

        let reloc = match self.isa.triple().pointer_width().unwrap() {
            PointerWidth::U16 => panic!(),
            PointerWidth::U32 => Reloc::Abs4,
            PointerWidth::U64 => Reloc::Abs8,
        };
        let mut relocs = Vec::new();
        for &(offset, id) in function_relocs {
            relocs.push(RelocRecord {
                reloc,
                offset,
                name: function_decls[id].clone(),
                addend: 0,
            });
        }
        for &(offset, id, addend) in data_relocs {
            relocs.push(RelocRecord {
                reloc,
                offset,
                name: data_decls[id].clone(),
                addend,
            });
        }

        Ok(Self::CompiledData {
            storage,
            size,
            relocs,
        })
    }

    fn write_data_funcaddr(
        &mut self,
        _data: &mut Self::CompiledData,
        _offset: usize,
        _what: ir::FuncRef,
    ) {
        unimplemented!();
    }

    fn write_data_dataaddr(
        &mut self,
        _data: &mut Self::CompiledData,
        _offset: usize,
        _what: ir::GlobalValue,
        _usize: Addend,
    ) {
        unimplemented!();
    }

    fn finalize_function(
        &mut self,
        func: &Self::CompiledFunction,
        namespace: &ModuleNamespace<Self>,
    ) -> Self::FinalizedFunction {
        use std::ptr::write_unaligned;

        for &RelocRecord {
            reloc,
            offset,
            ref name,
            addend,
        } in &func.relocs
        {
            let ptr = func.code;
            debug_assert!((offset as usize) < func.size);
            let at = unsafe { ptr.offset(offset as isize) };
            let base = if namespace.is_function(name) {
                let (def, name_str, _signature) = namespace.get_function_definition(&name);
                match def {
                    Some(compiled) => compiled.code,
                    None => self.lookup_symbol(name_str),
                }
            } else {
                let (def, name_str, _writable) = namespace.get_data_definition(&name);
                match def {
                    Some(compiled) => compiled.storage,
                    None => self.lookup_symbol(name_str),
                }
            };
            // TODO: Handle overflow.
            let what = unsafe { base.offset(addend as isize) };
            match reloc {
                Reloc::Abs4 => {
                    // TODO: Handle overflow.
                    #[cfg_attr(feature = "cargo-clippy", allow(cast_ptr_alignment))]
                    unsafe {
                        write_unaligned(at as *mut u32, what as u32)
                    };
                }
                Reloc::Abs8 => {
                    #[cfg_attr(feature = "cargo-clippy", allow(cast_ptr_alignment))]
                    unsafe {
                        write_unaligned(at as *mut u64, what as u64)
                    };
                }
                Reloc::X86PCRel4 | Reloc::X86CallPCRel4 => {
                    // TODO: Handle overflow.
                    let pcrel = ((what as isize) - (at as isize)) as i32;
                    #[cfg_attr(feature = "cargo-clippy", allow(cast_ptr_alignment))]
                    unsafe {
                        write_unaligned(at as *mut i32, pcrel)
                    };
                }
                Reloc::X86GOTPCRel4 | Reloc::X86CallPLTRel4 => panic!("unexpected PIC relocation"),
                _ => unimplemented!(),
            }
        }

        // Now that we're done patching, make the memory executable.
        self.code_memory.set_executable();
        func.code
    }

    fn finalize_data(
        &mut self,
        data: &Self::CompiledData,
        namespace: &ModuleNamespace<Self>,
    ) -> Self::FinalizedData {
        use std::ptr::write_unaligned;

        for record in &data.relocs {
            match *record {
                RelocRecord {
                    reloc,
                    offset,
                    ref name,
                    addend,
                } => {
                    let ptr = data.storage;
                    debug_assert!((offset as usize) < data.size);
                    let at = unsafe { ptr.offset(offset as isize) };
                    let base = if namespace.is_function(name) {
                        let (def, name_str, _signature) = namespace.get_function_definition(&name);
                        match def {
                            Some(compiled) => compiled.code,
                            None => self.lookup_symbol(name_str),
                        }
                    } else {
                        let (def, name_str, _writable) = namespace.get_data_definition(&name);
                        match def {
                            Some(compiled) => compiled.storage,
                            None => self.lookup_symbol(name_str),
                        }
                    };
                    // TODO: Handle overflow.
                    let what = unsafe { base.offset(addend as isize) };
                    match reloc {
                        Reloc::Abs4 => {
                            // TODO: Handle overflow.
                            #[cfg_attr(feature = "cargo-clippy", allow(cast_ptr_alignment))]
                            unsafe {
                                write_unaligned(at as *mut u32, what as u32)
                            };
                        }
                        Reloc::Abs8 => {
                            #[cfg_attr(feature = "cargo-clippy", allow(cast_ptr_alignment))]
                            unsafe {
                                write_unaligned(at as *mut u64, what as u64)
                            };
                        }
                        Reloc::X86PCRel4
                        | Reloc::X86CallPCRel4
                        | Reloc::X86GOTPCRel4
                        | Reloc::X86CallPLTRel4 => panic!("unexpected text relocation in data"),
                        _ => unimplemented!(),
                    }
                }
            }
        }

        self.readonly_memory.set_readonly();
        (data.storage, data.size)
    }

    /// SimpleJIT emits code and data into memory as it processes them, so it
    /// doesn't need to provide anything after the `Module` is complete.
    fn finish(self) -> () {}
}

#[cfg(not(windows))]
fn lookup_with_dlsym(name: &str) -> *const u8 {
    let c_str = CString::new(name).unwrap();
    let c_str_ptr = c_str.as_ptr();
    let sym = unsafe { libc::dlsym(libc::RTLD_DEFAULT, c_str_ptr) };
    if sym.is_null() {
        panic!("can't resolve symbol {}", name);
    }
    sym as *const u8
}

#[cfg(windows)]
fn lookup_with_dlsym(name: &str) -> *const u8 {
    const MSVCRT_DLL: &[u8] = b"msvcrt.dll\0";

    let c_str = CString::new(name).unwrap();
    let c_str_ptr = c_str.as_ptr();

    unsafe {
        let handles = [
            // try to find the searched symbol in the currently running executable
            ptr::null_mut(),
            // try to find the searched symbol in local c runtime
            winapi::um::libloaderapi::GetModuleHandleA(MSVCRT_DLL.as_ptr() as *const i8),
        ];

        for handle in &handles {
            let addr = winapi::um::libloaderapi::GetProcAddress(*handle, c_str_ptr);
            if addr.is_null() {
                continue;
            }
            return addr as *const u8;
        }

        let msg = if handles[1].is_null() {
            "(msvcrt not loaded)"
        } else {
            ""
        };
        panic!("cannot resolve address of symbol {} {}", name, msg);
    }
}

struct SimpleJITRelocSink {
    pub relocs: Vec<RelocRecord>,
}

impl SimpleJITRelocSink {
    pub fn new() -> Self {
        Self { relocs: Vec::new() }
    }
}

impl RelocSink for SimpleJITRelocSink {
    fn reloc_ebb(&mut self, _offset: CodeOffset, _reloc: Reloc, _ebb_offset: CodeOffset) {
        unimplemented!();
    }

    fn reloc_external(
        &mut self,
        offset: CodeOffset,
        reloc: Reloc,
        name: &ir::ExternalName,
        addend: Addend,
    ) {
        self.relocs.push(RelocRecord {
            offset,
            reloc,
            name: name.clone(),
            addend,
        });
    }

    fn reloc_jt(&mut self, _offset: CodeOffset, _reloc: Reloc, _jt: ir::JumpTable) {
        unimplemented!();
    }
}
<commit_msg>[SimpleJIT] Fix allocation of readonly memory.<commit_after>//! Defines `SimpleJITBackend`.

use cranelift_codegen::binemit::{Addend, CodeOffset, NullTrapSink, Reloc, RelocSink};
use cranelift_codegen::isa::TargetIsa;
use cranelift_codegen::{self, ir, settings};
use cranelift_module::{
    Backend, DataContext, DataDescription, Init, Linkage, ModuleNamespace, ModuleResult,
    Writability,
};
use cranelift_native;
use libc;
use memory::Memory;
use std::collections::HashMap;
use std::ffi::CString;
use std::ptr;
use target_lexicon::PointerWidth;
#[cfg(windows)]
use winapi;

/// A builder for `SimpleJITBackend`.
pub struct SimpleJITBuilder {
    isa: Box<TargetIsa>,
    symbols: HashMap<String, *const u8>,
}

impl SimpleJITBuilder {
    /// Create a new `SimpleJITBuilder`.
    pub fn new() -> Self {
        let (flag_builder, isa_builder) = cranelift_native::builders().unwrap_or_else(|_| {
            panic!("host machine is not a supported target");
        });
        let isa = isa_builder.finish(settings::Flags::new(flag_builder));
        Self::with_isa(isa)
    }

    /// Create a new `SimpleJITBuilder` with an arbitrary target. This is mainly
    /// useful for testing.
    ///
    /// SimpleJIT requires a `TargetIsa` configured for non-PIC.
    ///
    /// To create a `SimpleJITBuilder` for native use, use the `new` constructor
    /// instead.
    pub fn with_isa(isa: Box<TargetIsa>) -> Self {
        debug_assert!(!isa.flags().is_pic(), "SimpleJIT requires non-PIC code");
        let symbols = HashMap::new();
        Self { isa, symbols }
    }

    /// Define a symbol in the internal symbol table.
    ///
    /// The JIT will use the symbol table to resolve names that are declared,
    /// but not defined, in the module being compiled.  A common example is
    /// external functions.  With this method, functions and data can be exposed
    /// to the code being compiled which are defined by the host.
    ///
    /// If a symbol is defined more than once, the most recent definition will
    /// be retained.
    ///
    /// If the JIT fails to find a symbol in its internal table, it will fall
    /// back to a platform-specific search (this typically involves searching
    /// the current process for public symbols, followed by searching the
    /// platform's C runtime).
    pub fn symbol<'a, K>(&'a mut self, name: K, ptr: *const u8) -> &'a mut Self
    where
        K: Into<String>,
    {
        self.symbols.insert(name.into(), ptr);
        self
    }

    /// Define multiple symbols in the internal symbol table.
    ///
    /// Using this is equivalent to calling `symbol` on each element.
    pub fn symbols<'a, It, K>(&'a mut self, symbols: It) -> &'a mut Self
    where
        It: IntoIterator<Item = (K, *const u8)>,
        K: Into<String>,
    {
        for (name, ptr) in symbols {
            self.symbols.insert(name.into(), ptr);
        }
        self
    }
}

/// A `SimpleJITBackend` implements `Backend` and emits code and data into memory where it can be
/// directly called and accessed.
pub struct SimpleJITBackend {
    isa: Box<TargetIsa>,
    symbols: HashMap<String, *const u8>,
    code_memory: Memory,
    readonly_memory: Memory,
    writable_memory: Memory,
}

/// A record of a relocation to perform.
struct RelocRecord {
    offset: CodeOffset,
    reloc: Reloc,
    name: ir::ExternalName,
    addend: Addend,
}

pub struct SimpleJITCompiledFunction {
    code: *mut u8,
    size: usize,
    relocs: Vec<RelocRecord>,
}

pub struct SimpleJITCompiledData {
    storage: *mut u8,
    size: usize,
    relocs: Vec<RelocRecord>,
}

impl SimpleJITBackend {
    fn lookup_symbol(&self, name: &str) -> *const u8 {
        match self.symbols.get(name) {
            Some(&ptr) => ptr,
            None => lookup_with_dlsym(name),
        }
    }
}

impl<'simple_jit_backend> Backend for SimpleJITBackend {
    type Builder = SimpleJITBuilder;

    /// SimpleJIT compiled function and data objects may have outstanding
    /// relocations that need to be performed before the memory can be used.
    /// These relocations are performed within `finalize_function` and
    /// `finalize_data`.
    type CompiledFunction = SimpleJITCompiledFunction;
    type CompiledData = SimpleJITCompiledData;

    /// SimpleJIT emits code and data into memory, and provides raw pointers
    /// to them.
    type FinalizedFunction = *const u8;
    type FinalizedData = (*mut u8, usize);

    /// SimpleJIT emits code and data into memory as it processes them, so it
    /// doesn't need to provide anything after the `Module` is complete.
    type Product = ();

    /// Create a new `SimpleJITBackend`.
    fn new(builder: SimpleJITBuilder) -> Self {
        Self {
            isa: builder.isa,
            symbols: builder.symbols,
            code_memory: Memory::new(),
            readonly_memory: Memory::new(),
            writable_memory: Memory::new(),
        }
    }

    fn isa(&self) -> &TargetIsa {
        &*self.isa
    }

    fn declare_function(&mut self, _name: &str, _linkage: Linkage) {
        // Nothing to do.
    }

    fn declare_data(&mut self, _name: &str, _linkage: Linkage, _writable: bool) {
        // Nothing to do.
    }

    fn define_function(
        &mut self,
        _name: &str,
        ctx: &cranelift_codegen::Context,
        _namespace: &ModuleNamespace<Self>,
        code_size: u32,
    ) -> ModuleResult<Self::CompiledFunction> {
        let size = code_size as usize;
        let ptr = self
            .code_memory
            .allocate(size)
            .expect("TODO: handle OOM etc.");
        let mut reloc_sink = SimpleJITRelocSink::new();
        // Ignore traps for now. For now, frontends should just avoid generating code
        // that traps.
        let mut trap_sink = NullTrapSink {};
        unsafe { ctx.emit_to_memory(&*self.isa, ptr, &mut reloc_sink, &mut trap_sink) };

        Ok(Self::CompiledFunction {
            code: ptr,
            size,
            relocs: reloc_sink.relocs,
        })
    }

    fn define_data(
        &mut self,
        _name: &str,
        data: &DataContext,
        _namespace: &ModuleNamespace<Self>,
    ) -> ModuleResult<Self::CompiledData> {
        let &DataDescription {
            writable,
            ref init,
            ref function_decls,
            ref data_decls,
            ref function_relocs,
            ref data_relocs,
        } = data.description();

        let size = init.size();
        let storage = match writable {
            Writability::Readonly => self
                .readonly_memory
                .allocate(size)
                .expect("TODO: handle OOM etc."),
            Writability::Writable => self
                .writable_memory
                .allocate(size)
                .expect("TODO: handle OOM etc."),
        };

        match *init {
            Init::Uninitialized => {
                panic!("data is not initialized yet");
            }
            Init::Zeros { .. } => {
                unsafe { ptr::write_bytes(storage, 0, size) };
            }
            Init::Bytes { ref contents } => {
                let src = contents.as_ptr();
                unsafe { ptr::copy_nonoverlapping(src, storage, size) };
            }
        }

        let reloc = match self.isa.triple().pointer_width().unwrap() {
            PointerWidth::U16 => panic!(),
            PointerWidth::U32 => Reloc::Abs4,
            PointerWidth::U64 => Reloc::Abs8,
        };
        let mut relocs = Vec::new();
        for &(offset, id) in function_relocs {
            relocs.push(RelocRecord {
                reloc,
                offset,
                name: function_decls[id].clone(),
                addend: 0,
            });
        }
        for &(offset, id, addend) in data_relocs {
            relocs.push(RelocRecord {
                reloc,
                offset,
                name: data_decls[id].clone(),
                addend,
            });
        }

        Ok(Self::CompiledData {
            storage,
            size,
            relocs,
        })
    }

    fn write_data_funcaddr(
        &mut self,
        _data: &mut Self::CompiledData,
        _offset: usize,
        _what: ir::FuncRef,
    ) {
        unimplemented!();
    }

    fn write_data_dataaddr(
        &mut self,
        _data: &mut Self::CompiledData,
        _offset: usize,
        _what: ir::GlobalValue,
        _usize: Addend,
    ) {
        unimplemented!();
    }

    fn finalize_function(
        &mut self,
        func: &Self::CompiledFunction,
        namespace: &ModuleNamespace<Self>,
    ) -> Self::FinalizedFunction {
        use std::ptr::write_unaligned;

        for &RelocRecord {
            reloc,
            offset,
            ref name,
            addend,
        } in &func.relocs
        {
            let ptr = func.code;
            debug_assert!((offset as usize) < func.size);
            let at = unsafe { ptr.offset(offset as isize) };
            let base = if namespace.is_function(name) {
                let (def, name_str, _signature) = namespace.get_function_definition(&name);
                match def {
                    Some(compiled) => compiled.code,
                    None => self.lookup_symbol(name_str),
                }
            } else {
                let (def, name_str, _writable) = namespace.get_data_definition(&name);
                match def {
                    Some(compiled) => compiled.storage,
                    None => self.lookup_symbol(name_str),
                }
            };
            // TODO: Handle overflow.
            let what = unsafe { base.offset(addend as isize) };
            match reloc {
                Reloc::Abs4 => {
                    // TODO: Handle overflow.
                    #[cfg_attr(feature = "cargo-clippy", allow(cast_ptr_alignment))]
                    unsafe {
                        write_unaligned(at as *mut u32, what as u32)
                    };
                }
                Reloc::Abs8 => {
                    #[cfg_attr(feature = "cargo-clippy", allow(cast_ptr_alignment))]
                    unsafe {
                        write_unaligned(at as *mut u64, what as u64)
                    };
                }
                Reloc::X86PCRel4 | Reloc::X86CallPCRel4 => {
                    // TODO: Handle overflow.
                    let pcrel = ((what as isize) - (at as isize)) as i32;
                    #[cfg_attr(feature = "cargo-clippy", allow(cast_ptr_alignment))]
                    unsafe {
                        write_unaligned(at as *mut i32, pcrel)
                    };
                }
                Reloc::X86GOTPCRel4 | Reloc::X86CallPLTRel4 => panic!("unexpected PIC relocation"),
                _ => unimplemented!(),
            }
        }

        // Now that we're done patching, make the memory executable.
        self.code_memory.set_executable();
        func.code
    }

    fn finalize_data(
        &mut self,
        data: &Self::CompiledData,
        namespace: &ModuleNamespace<Self>,
    ) -> Self::FinalizedData {
        use std::ptr::write_unaligned;

        for record in &data.relocs {
            match *record {
                RelocRecord {
                    reloc,
                    offset,
                    ref name,
                    addend,
                } => {
                    let ptr = data.storage;
                    debug_assert!((offset as usize) < data.size);
                    let at = unsafe { ptr.offset(offset as isize) };
                    let base = if namespace.is_function(name) {
                        let (def, name_str, _signature) = namespace.get_function_definition(&name);
                        match def {
                            Some(compiled) => compiled.code,
                            None => self.lookup_symbol(name_str),
                        }
                    } else {
                        let (def, name_str, _writable) = namespace.get_data_definition(&name);
                        match def {
                            Some(compiled) => compiled.storage,
                            None => self.lookup_symbol(name_str),
                        }
                    };
                    // TODO: Handle overflow.
                    let what = unsafe { base.offset(addend as isize) };
                    match reloc {
                        Reloc::Abs4 => {
                            // TODO: Handle overflow.
                            #[cfg_attr(feature = "cargo-clippy", allow(cast_ptr_alignment))]
                            unsafe {
                                write_unaligned(at as *mut u32, what as u32)
                            };
                        }
                        Reloc::Abs8 => {
                            #[cfg_attr(feature = "cargo-clippy", allow(cast_ptr_alignment))]
                            unsafe {
                                write_unaligned(at as *mut u64, what as u64)
                            };
                        }
                        Reloc::X86PCRel4
                        | Reloc::X86CallPCRel4
                        | Reloc::X86GOTPCRel4
                        | Reloc::X86CallPLTRel4 => panic!("unexpected text relocation in data"),
                        _ => unimplemented!(),
                    }
                }
            }
        }

        self.readonly_memory.set_readonly();
        (data.storage, data.size)
    }

    /// SimpleJIT emits code and data into memory as it processes them, so it
    /// doesn't need to provide anything after the `Module` is complete.
    fn finish(self) -> () {}
}

#[cfg(not(windows))]
fn lookup_with_dlsym(name: &str) -> *const u8 {
    let c_str = CString::new(name).unwrap();
    let c_str_ptr = c_str.as_ptr();
    let sym = unsafe { libc::dlsym(libc::RTLD_DEFAULT, c_str_ptr) };
    if sym.is_null() {
        panic!("can't resolve symbol {}", name);
    }
    sym as *const u8
}

#[cfg(windows)]
fn lookup_with_dlsym(name: &str) -> *const u8 {
    const MSVCRT_DLL: &[u8] = b"msvcrt.dll\0";

    let c_str = CString::new(name).unwrap();
    let c_str_ptr = c_str.as_ptr();

    unsafe {
        let handles = [
            // try to find the searched symbol in the currently running executable
            ptr::null_mut(),
            // try to find the searched symbol in local c runtime
            winapi::um::libloaderapi::GetModuleHandleA(MSVCRT_DLL.as_ptr() as *const i8),
        ];

        for handle in &handles {
            let addr = winapi::um::libloaderapi::GetProcAddress(*handle, c_str_ptr);
            if addr.is_null() {
                continue;
            }
            return addr as *const u8;
        }

        let msg = if handles[1].is_null() {
            "(msvcrt not loaded)"
        } else {
            ""
        };
        panic!("cannot resolve address of symbol {} {}", name, msg);
    }
}

struct SimpleJITRelocSink {
    pub relocs: Vec<RelocRecord>,
}

impl SimpleJITRelocSink {
    pub fn new() -> Self {
        Self { relocs: Vec::new() }
    }
}

impl RelocSink for SimpleJITRelocSink {
    fn reloc_ebb(&mut self, _offset: CodeOffset, _reloc: Reloc, _ebb_offset: CodeOffset) {
        unimplemented!();
    }

    fn reloc_external(
        &mut self,
        offset: CodeOffset,
        reloc: Reloc,
        name: &ir::ExternalName,
        addend: Addend,
    ) {
        self.relocs.push(RelocRecord {
            offset,
            reloc,
            name: name.clone(),
            addend,
        });
    }

    fn reloc_jt(&mut self, _offset: CodeOffset, _reloc: Reloc, _jt: ir::JumpTable) {
        unimplemented!();
    }
}
<|endoftext|>


<commit_before>use kay::{ID, World, ActorSystem, Fate};
use kay::swarm::{Swarm, SubActor};
use ordered_float::OrderedFloat;
use core::simulation::Timestamp;

use super::Destination;
use super::{RoughDestinationID, AsDestinationRequester, AsDestinationRequesterID,
            MSG_AsDestinationRequester_tell_as_destination};

#[derive(Compact, Clone)]
pub struct Trip {
    id: TripID,
    rough_source: RoughDestinationID,
    rough_destination: RoughDestinationID,
    source: Option<Destination>,
    destination: Option<Destination>,
    listener: Option<TripListenerID>,
}

impl Trip {
    pub fn spawn(
        id: TripID,
        rough_source: RoughDestinationID,
        rough_destination: RoughDestinationID,
        listener: Option<TripListenerID>,
        tick: Timestamp,
        world: &mut World,
    ) -> Self {

        rough_source.query_as_destination(id.into(), rough_source, tick, world);
        rough_destination.query_as_destination(id.into(), rough_destination, tick, world);

        if let Some(listener) = listener {
            listener.trip_created(id, world);
        }

        Trip {
            id: id,
            rough_source,
            rough_destination,
            listener,
            source: None,
            destination: None,
        }
    }

    pub fn fail_at(
        &mut self,
        location: RoughDestinationID,
        tick: Timestamp,
        world: &mut World,
    ) -> Fate {
        println!("Trip {:?} failed!", self.id());

        if let Some(listener) = self.listener {
            listener.trip_result(self.id, location, true, tick, world);
        }

        Fate::Die
    }

    pub fn succeed(&mut self, tick: Timestamp, world: &mut World) -> Fate {
        println!("Trip {:?} succeeded!", self.id());

        if let Some(listener) = self.listener {
            listener.trip_result(self.id, self.rough_destination, false, tick, world);
        }

        Fate::Die
    }
}

impl AsDestinationRequester for Trip {
    fn tell_as_destination(
        &mut self,
        rough_destination: RoughDestinationID,
        as_destination: Option<Destination>,
        tick: Timestamp,
        world: &mut World,
    ) {
        if let Some(precise) = as_destination {
            if rough_destination == self.rough_source {
                self.source = Some(precise);
            } else if rough_destination == self.rough_destination {
                self.destination = Some(precise);
            } else {
                unreachable!();
            }

            if let (Some(source), Some(destination)) = (self.source, self.destination) {
                world.send(
                    source.node,
                    AddCar {
                        car: LaneCar {
                            trip: self.id,
                            as_obstacle: Obstacle {
                                position: OrderedFloat(-1.0),
                                velocity: 0.0,
                                max_velocity: 15.0,
                            },
                            acceleration: 0.0,
                            destination: destination,
                            next_hop_interaction: 0,
                        },
                        from: None,
                        tick,
                    },
                );
            }
        } else {
            println!(
                "{:?} is not a source/destination yet",
                rough_destination._raw_id
            );
            self.id.fail_at(self.rough_source, tick, world);
        }
    }
}

use core::simulation::{Simulation, SleeperID, WakeUpIn, MSG_Sleeper_wake};
use core::simulation::DurationTicks;

pub fn setup(system: &mut ActorSystem) {
    auto_setup(system);

    system.add(
        TripCreator {
            current_source_lane: None,
            current_destination_lane: None,
        },
        |mut the_creator| {
            let sim_id = the_creator.world().id::<Simulation>();
            let tc_id = the_creator.world().id::<TripCreator>();

            the_creator.on(move |&AddLaneForTrip(lane_id), tc, world| {
                if tc.current_source_lane.is_some() {
                    tc.current_destination_lane = Some(lane_id)
                } else {
                    tc.current_source_lane = Some(lane_id);
                }
                world.send(
                    sim_id,
                    WakeUpIn(DurationTicks::new(0), SleeperID { _raw_id: tc_id }),
                );
                Fate::Live
            });

            the_creator.on(move |&MSG_Sleeper_wake(current_tick), tc, world| {
                TripID::spawn(
                    RoughDestinationID {
                        _raw_id: tc.current_source_lane.expect(
                            "Should already have source lane",
                        ),
                    },
                    RoughDestinationID {
                        _raw_id: tc.current_destination_lane.expect(
                            "Should already have destination lane",
                        ),
                    },
                    None,
                    current_tick,
                    world,
                );
                tc.current_source_lane = None;
                tc.current_destination_lane = None;
                Fate::Live
            })
        },
    );

    system.extend(Swarm::<Lane>::subactors(|mut each_lane| {
        let creator_id = each_lane.world().id::<TripCreator>();

        each_lane.on_random(move |event, lane, world| {
            match *event {
                Event3d::HoverStarted { .. } => {
                    lane.hovered = true;
                }
                Event3d::HoverStopped { .. } => {
                    lane.hovered = false;
                }
                Event3d::DragFinished { .. } => {
                    if !lane.connectivity.on_intersection {
                        world.send(creator_id, AddLaneForTrip(lane.id()));
                    }
                }
                _ => {}
            };
            Fate::Live
        })
    }));
}

use super::super::microtraffic::{AddCar, LaneCar, Obstacle};

pub trait TripListener {
    fn trip_created(&mut self, trip: TripID, world: &mut World);
    fn trip_result(
        &mut self,
        trip: TripID,
        location: RoughDestinationID,
        failed: bool,
        tick: Timestamp,
        world: &mut World,
    );
}

pub struct TripCreator {
    current_source_lane: Option<ID>,
    current_destination_lane: Option<ID>,
}

#[derive(Copy, Clone)]
pub struct AddLaneForTrip(ID);

use super::super::lane::Lane;
use stagemaster::Event3d;

mod kay_auto;
pub use self::kay_auto::*;
<commit_msg>quick commit to save<commit_after>use kay::{ID, World, ActorSystem, Fate};
use kay::swarm::{Swarm, SubActor};
use ordered_float::OrderedFloat;
use core::simulation::Timestamp;

use super::Destination;
use super::{RoughDestinationID, AsDestinationRequester, AsDestinationRequesterID,
            MSG_AsDestinationRequester_tell_as_destination};

#[derive(Compact, Clone)]
pub struct Trip {
    id: TripID,
    rough_source: RoughDestinationID,
    rough_destination: RoughDestinationID,
    source: Option<Destination>,
    destination: Option<Destination>,
    listener: Option<TripListenerID>,
}

impl Trip {
    pub fn spawn(
        id: TripID,
        rough_source: RoughDestinationID,
        rough_destination: RoughDestinationID,
        listener: Option<TripListenerID>,
        tick: Timestamp,
        world: &mut World,
    ) -> Self {

        rough_source.query_as_destination(id.into(), rough_source, tick, world);
        rough_destination.query_as_destination(id.into(), rough_destination, tick, world);

        if let Some(listener) = listener {
            listener.trip_created(id, world);
        }

        Trip {
            id: id,
            rough_source,
            rough_destination,
            listener,
            source: None,
            destination: None,
        }
    }

    pub fn fail_at(
        &mut self,
        location: RoughDestinationID,
        tick: Timestamp,
        world: &mut World,
    ) -> Fate {
        println!("Trip {:?} failed!", self.id());

        if let Some(listener) = self.listener {
            listener.trip_result(self.id, location, true, tick, world);
        }

        Fate::Die
    }

    pub fn succeed(&mut self, tick: Timestamp, world: &mut World) -> Fate {
        println!("Trip {:?} succeeded!", self.id());

        if let Some(listener) = self.listener {
            listener.trip_result(self.id, self.rough_destination, false, tick, world);
        }

        Fate::Die
    }
}

impl AsDestinationRequester for Trip {
    fn tell_as_destination(
        &mut self,
        rough_destination: RoughDestinationID,
        as_destination: Option<Destination>,
        tick: Timestamp,
        world: &mut World,
    ) {
        if let Some(precise) = as_destination {
            if rough_destination == self.rough_source {
                self.source = Some(precise);
            } else if rough_destination == self.rough_destination {
                self.destination = Some(precise);
            } else {
                unreachable!();
            }

            if let (Some(source), Some(destination)) = (self.source, self.destination) {
                world.send(
                    source.node,
                    AddCar {
                        car: LaneCar {
                            trip: self.id,
                            as_obstacle: Obstacle {
                                position: OrderedFloat(-1.0),
                                velocity: 0.0,
                                max_velocity: 15.0,
                            },
                            acceleration: 0.0,
                            destination: destination,
                            next_hop_interaction: 0,
                        },
                        from: None,
                        tick,
                    },
                );
            }
        } else {
            println!(
                "{:?} is not a source/destination yet",
                rough_destination._raw_id
            );
            self.id.fail_at(self.rough_source, tick, world);
        }
    }
}

use core::simulation::{Simulation, SleeperID, WakeUpIn, MSG_Sleeper_wake};
use core::simulation::DurationTicks;

pub fn setup(system: &mut ActorSystem) {
    auto_setup(system);

    system.add(
        TripCreator {
            current_source_lane: None,
            current_destination_lane: None,
        },
        |mut the_creator| {
            the_creator.on(move |&AddLaneForTrip(lane_id), tc, world| {
                if tc.current_source_lane.is_some() {
                    tc.current_destination_lane = Some(lane_id)
                } else {
                    tc.current_source_lane = Some(lane_id);
                }
                let sim_id = world.id::<Simulation>();
                let tc_id = world.id::<TripCreator>();
                world.send(
                    sim_id,
                    WakeUpIn(DurationTicks::new(0), SleeperID { _raw_id: tc_id }),
                );
                Fate::Live
            });

            the_creator.on(move |&MSG_Sleeper_wake(current_tick), tc, world| {
                TripID::spawn(
                    RoughDestinationID {
                        _raw_id: tc.current_source_lane.expect(
                            "Should already have source lane",
                        ),
                    },
                    RoughDestinationID {
                        _raw_id: tc.current_destination_lane.expect(
                            "Should already have destination lane",
                        ),
                    },
                    None,
                    current_tick,
                    world,
                );
                tc.current_source_lane = None;
                tc.current_destination_lane = None;
                Fate::Live
            })
        },
    );

    system.extend(Swarm::<Lane>::subactors(|mut each_lane| {
        let creator_id = each_lane.world().id::<TripCreator>();

        each_lane.on_random(move |event, lane, world| {
            match *event {
                Event3d::HoverStarted { .. } => {
                    lane.hovered = true;
                }
                Event3d::HoverStopped { .. } => {
                    lane.hovered = false;
                }
                Event3d::DragFinished { .. } => {
                    if !lane.connectivity.on_intersection {
                        world.send(creator_id, AddLaneForTrip(lane.id()));
                    }
                }
                _ => {}
            };
            Fate::Live
        })
    }));
}

use super::super::microtraffic::{AddCar, LaneCar, Obstacle};

pub trait TripListener {
    fn trip_created(&mut self, trip: TripID, world: &mut World);
    fn trip_result(
        &mut self,
        trip: TripID,
        location: RoughDestinationID,
        failed: bool,
        tick: Timestamp,
        world: &mut World,
    );
}

pub struct TripCreator {
    current_source_lane: Option<ID>,
    current_destination_lane: Option<ID>,
}

#[derive(Copy, Clone)]
pub struct AddLaneForTrip(ID);

use super::super::lane::Lane;
use stagemaster::Event3d;

mod kay_auto;
pub use self::kay_auto::*;
<|endoftext|>


<commit_before>// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#[allow(unused_imports)]
#[macro_use]
extern crate msg_on_socket_derive;
extern crate data_model;
#[macro_use]
extern crate sys_util;

mod msg_on_socket;

use std::io::Result;
use std::marker::PhantomData;
use std::os::unix::io::RawFd;
use std::os::unix::net::UnixDatagram;
use sys_util::{Error as SysError, ScmSocket, UnlinkUnixDatagram};

pub use msg_on_socket::*;
pub use msg_on_socket_derive::*;

/// Create a pair of socket. Request is send in one direction while response is in the other
/// direction.
pub fn pair<Request: MsgOnSocket, Response: MsgOnSocket>(
) -> Option<(MsgSocket<Request, Response>, MsgSocket<Response, Request>)> {
    let (sock1, sock2) = match UnixDatagram::pair() {
        Ok((sock1, sock2)) => (sock1, sock2),
        _ => {
            return None;
        }
    };
    let requester = MsgSocket {
        sock: sock1,
        _i: PhantomData,
        _o: PhantomData,
    };
    let responder = MsgSocket {
        sock: sock2,
        _i: PhantomData,
        _o: PhantomData,
    };
    Some((requester, responder))
}

/// Bidirection sock that support both send and recv.
pub struct MsgSocket<I: MsgOnSocket, O: MsgOnSocket> {
    sock: UnixDatagram,
    _i: PhantomData<I>,
    _o: PhantomData<O>,
}

impl<I: MsgOnSocket, O: MsgOnSocket> MsgSocket<I, O> {
    // Create a new MsgSocket.
    pub fn new(s: UnixDatagram) -> MsgSocket<I, O> {
        MsgSocket {
            sock: s,
            _i: PhantomData,
            _o: PhantomData,
        }
    }
}

/// Bidirection sock that support both send and recv.
pub struct UnlinkMsgSocket<I: MsgOnSocket, O: MsgOnSocket> {
    sock: UnlinkUnixDatagram,
    _i: PhantomData<I>,
    _o: PhantomData<O>,
}

impl<I: MsgOnSocket, O: MsgOnSocket> UnlinkMsgSocket<I, O> {
    // Create a new MsgSocket.
    pub fn new(s: UnlinkUnixDatagram) -> UnlinkMsgSocket<I, O> {
        UnlinkMsgSocket {
            sock: s,
            _i: PhantomData,
            _o: PhantomData,
        }
    }
}

/// One direction socket that only supports sending.
pub struct Sender<M: MsgOnSocket> {
    sock: UnixDatagram,
    _m: PhantomData<M>,
}

impl<M: MsgOnSocket> Sender<M> {
    /// Create a new sender sock.
    pub fn new(s: UnixDatagram) -> Sender<M> {
        Sender {
            sock: s,
            _m: PhantomData,
        }
    }
}

/// One direction socket that only supports receiving.
pub struct Receiver<M: MsgOnSocket> {
    sock: UnixDatagram,
    _m: PhantomData<M>,
}

impl<M: MsgOnSocket> Receiver<M> {
    /// Create a new receiver sock.
    pub fn new(s: UnixDatagram) -> Receiver<M> {
        Receiver {
            sock: s,
            _m: PhantomData,
        }
    }
}

impl<I: MsgOnSocket, O: MsgOnSocket> AsRef<UnixDatagram> for MsgSocket<I, O> {
    fn as_ref(&self) -> &UnixDatagram {
        &self.sock
    }
}

impl<I: MsgOnSocket, O: MsgOnSocket> AsRef<UnixDatagram> for UnlinkMsgSocket<I, O> {
    fn as_ref(&self) -> &UnixDatagram {
        self.sock.as_ref()
    }
}

impl<M: MsgOnSocket> AsRef<UnixDatagram> for Sender<M> {
    fn as_ref(&self) -> &UnixDatagram {
        &self.sock
    }
}

impl<M: MsgOnSocket> AsRef<UnixDatagram> for Receiver<M> {
    fn as_ref(&self) -> &UnixDatagram {
        &self.sock
    }
}

/// Types that could send a message.
pub trait MsgSender<M: MsgOnSocket>: AsRef<UnixDatagram> {
    fn send(&self, msg: &M) -> MsgResult<()> {
        let msg_size = M::msg_size();
        let fd_size = M::max_fd_count();
        let mut msg_buffer: Vec<u8> = vec![0; msg_size];
        let mut fd_buffer: Vec<RawFd> = vec![0; fd_size];

        let fd_size = msg.write_to_buffer(&mut msg_buffer, &mut fd_buffer)?;
        let sock: &UnixDatagram = self.as_ref();
        if fd_size == 0 {
            handle_eintr!(sock.send(&msg_buffer))
                .map_err(|e| MsgError::Send(SysError::new(e.raw_os_error().unwrap_or(0))))?;
        } else {
            sock.send_with_fds(&msg_buffer[..], &fd_buffer[0..fd_size])
                .map_err(|e| MsgError::Send(e))?;
        }
        Ok(())
    }
}

/// Types that could receive a message.
pub trait MsgReceiver<M: MsgOnSocket>: AsRef<UnixDatagram> {
    fn recv(&self) -> MsgResult<M> {
        let msg_size = M::msg_size();
        let fd_size = M::max_fd_count();
        let mut msg_buffer: Vec<u8> = vec![0; msg_size];
        let mut fd_buffer: Vec<RawFd> = vec![0; fd_size];

        let sock: &UnixDatagram = self.as_ref();

        let (recv_msg_size, recv_fd_size) = {
            if fd_size == 0 {
                let size = sock
                    .recv(&mut msg_buffer)
                    .map_err(|e| MsgError::Recv(SysError::new(e.raw_os_error().unwrap_or(0))))?;
                (size, 0)
            } else {
                sock.recv_with_fds(&mut msg_buffer, &mut fd_buffer)
                    .map_err(|e| MsgError::Recv(e))?
            }
        };
        if msg_size != recv_msg_size {
            return Err(MsgError::BadRecvSize(msg_size));
        }
        // Safe because fd buffer is read from socket.
        let (v, read_fd_size) = unsafe {
            M::read_from_buffer(&msg_buffer[0..recv_msg_size], &fd_buffer[0..recv_fd_size])?
        };
        if recv_fd_size != read_fd_size {
            return Err(MsgError::NotExpectFd);
        }
        Ok(v)
    }
}

impl<I: MsgOnSocket, O: MsgOnSocket> MsgSender<I> for MsgSocket<I, O> {}
impl<I: MsgOnSocket, O: MsgOnSocket> MsgReceiver<O> for MsgSocket<I, O> {}

impl<I: MsgOnSocket, O: MsgOnSocket> MsgSender<I> for UnlinkMsgSocket<I, O> {}
impl<I: MsgOnSocket, O: MsgOnSocket> MsgReceiver<O> for UnlinkMsgSocket<I, O> {}

impl<M: MsgOnSocket> MsgSender<M> for Sender<M> {}
impl<M: MsgOnSocket> MsgReceiver<M> for Receiver<M> {}
<commit_msg>msg_socket: implement AsRawFd for UnixDatagram wrappers<commit_after>// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#[allow(unused_imports)]
#[macro_use]
extern crate msg_on_socket_derive;
extern crate data_model;
#[macro_use]
extern crate sys_util;

mod msg_on_socket;

use std::io::Result;
use std::marker::PhantomData;
use std::os::unix::io::{AsRawFd, RawFd};
use std::os::unix::net::UnixDatagram;
use sys_util::{Error as SysError, ScmSocket, UnlinkUnixDatagram};

pub use msg_on_socket::*;
pub use msg_on_socket_derive::*;

/// Create a pair of socket. Request is send in one direction while response is in the other
/// direction.
pub fn pair<Request: MsgOnSocket, Response: MsgOnSocket>(
) -> Option<(MsgSocket<Request, Response>, MsgSocket<Response, Request>)> {
    let (sock1, sock2) = match UnixDatagram::pair() {
        Ok((sock1, sock2)) => (sock1, sock2),
        _ => {
            return None;
        }
    };
    let requester = MsgSocket {
        sock: sock1,
        _i: PhantomData,
        _o: PhantomData,
    };
    let responder = MsgSocket {
        sock: sock2,
        _i: PhantomData,
        _o: PhantomData,
    };
    Some((requester, responder))
}

/// Bidirection sock that support both send and recv.
pub struct MsgSocket<I: MsgOnSocket, O: MsgOnSocket> {
    sock: UnixDatagram,
    _i: PhantomData<I>,
    _o: PhantomData<O>,
}

impl<I: MsgOnSocket, O: MsgOnSocket> MsgSocket<I, O> {
    // Create a new MsgSocket.
    pub fn new(s: UnixDatagram) -> MsgSocket<I, O> {
        MsgSocket {
            sock: s,
            _i: PhantomData,
            _o: PhantomData,
        }
    }
}

/// Bidirection sock that support both send and recv.
pub struct UnlinkMsgSocket<I: MsgOnSocket, O: MsgOnSocket> {
    sock: UnlinkUnixDatagram,
    _i: PhantomData<I>,
    _o: PhantomData<O>,
}

impl<I: MsgOnSocket, O: MsgOnSocket> UnlinkMsgSocket<I, O> {
    // Create a new MsgSocket.
    pub fn new(s: UnlinkUnixDatagram) -> UnlinkMsgSocket<I, O> {
        UnlinkMsgSocket {
            sock: s,
            _i: PhantomData,
            _o: PhantomData,
        }
    }
}

/// One direction socket that only supports sending.
pub struct Sender<M: MsgOnSocket> {
    sock: UnixDatagram,
    _m: PhantomData<M>,
}

impl<M: MsgOnSocket> Sender<M> {
    /// Create a new sender sock.
    pub fn new(s: UnixDatagram) -> Sender<M> {
        Sender {
            sock: s,
            _m: PhantomData,
        }
    }
}

/// One direction socket that only supports receiving.
pub struct Receiver<M: MsgOnSocket> {
    sock: UnixDatagram,
    _m: PhantomData<M>,
}

impl<M: MsgOnSocket> Receiver<M> {
    /// Create a new receiver sock.
    pub fn new(s: UnixDatagram) -> Receiver<M> {
        Receiver {
            sock: s,
            _m: PhantomData,
        }
    }
}

impl<I: MsgOnSocket, O: MsgOnSocket> AsRef<UnixDatagram> for MsgSocket<I, O> {
    fn as_ref(&self) -> &UnixDatagram {
        &self.sock
    }
}

impl<I: MsgOnSocket, O: MsgOnSocket> AsRawFd for MsgSocket<I, O> {
    fn as_raw_fd(&self) -> RawFd {
        self.sock.as_raw_fd()
    }
}

impl<I: MsgOnSocket, O: MsgOnSocket> AsRef<UnixDatagram> for UnlinkMsgSocket<I, O> {
    fn as_ref(&self) -> &UnixDatagram {
        self.sock.as_ref()
    }
}

impl<I: MsgOnSocket, O: MsgOnSocket> AsRawFd for UnlinkMsgSocket<I, O> {
    fn as_raw_fd(&self) -> RawFd {
        self.as_ref().as_raw_fd()
    }
}

impl<M: MsgOnSocket> AsRef<UnixDatagram> for Sender<M> {
    fn as_ref(&self) -> &UnixDatagram {
        &self.sock
    }
}

impl<M: MsgOnSocket> AsRawFd for Sender<M> {
    fn as_raw_fd(&self) -> RawFd {
        self.sock.as_raw_fd()
    }
}

impl<M: MsgOnSocket> AsRef<UnixDatagram> for Receiver<M> {
    fn as_ref(&self) -> &UnixDatagram {
        &self.sock
    }
}

impl<M: MsgOnSocket> AsRawFd for Receiver<M> {
    fn as_raw_fd(&self) -> RawFd {
        self.sock.as_raw_fd()
    }
}

/// Types that could send a message.
pub trait MsgSender<M: MsgOnSocket>: AsRef<UnixDatagram> {
    fn send(&self, msg: &M) -> MsgResult<()> {
        let msg_size = M::msg_size();
        let fd_size = M::max_fd_count();
        let mut msg_buffer: Vec<u8> = vec![0; msg_size];
        let mut fd_buffer: Vec<RawFd> = vec![0; fd_size];

        let fd_size = msg.write_to_buffer(&mut msg_buffer, &mut fd_buffer)?;
        let sock: &UnixDatagram = self.as_ref();
        if fd_size == 0 {
            handle_eintr!(sock.send(&msg_buffer))
                .map_err(|e| MsgError::Send(SysError::new(e.raw_os_error().unwrap_or(0))))?;
        } else {
            sock.send_with_fds(&msg_buffer[..], &fd_buffer[0..fd_size])
                .map_err(|e| MsgError::Send(e))?;
        }
        Ok(())
    }
}

/// Types that could receive a message.
pub trait MsgReceiver<M: MsgOnSocket>: AsRef<UnixDatagram> {
    fn recv(&self) -> MsgResult<M> {
        let msg_size = M::msg_size();
        let fd_size = M::max_fd_count();
        let mut msg_buffer: Vec<u8> = vec![0; msg_size];
        let mut fd_buffer: Vec<RawFd> = vec![0; fd_size];

        let sock: &UnixDatagram = self.as_ref();

        let (recv_msg_size, recv_fd_size) = {
            if fd_size == 0 {
                let size = sock
                    .recv(&mut msg_buffer)
                    .map_err(|e| MsgError::Recv(SysError::new(e.raw_os_error().unwrap_or(0))))?;
                (size, 0)
            } else {
                sock.recv_with_fds(&mut msg_buffer, &mut fd_buffer)
                    .map_err(|e| MsgError::Recv(e))?
            }
        };
        if msg_size != recv_msg_size {
            return Err(MsgError::BadRecvSize(msg_size));
        }
        // Safe because fd buffer is read from socket.
        let (v, read_fd_size) = unsafe {
            M::read_from_buffer(&msg_buffer[0..recv_msg_size], &fd_buffer[0..recv_fd_size])?
        };
        if recv_fd_size != read_fd_size {
            return Err(MsgError::NotExpectFd);
        }
        Ok(v)
    }
}

impl<I: MsgOnSocket, O: MsgOnSocket> MsgSender<I> for MsgSocket<I, O> {}
impl<I: MsgOnSocket, O: MsgOnSocket> MsgReceiver<O> for MsgSocket<I, O> {}

impl<I: MsgOnSocket, O: MsgOnSocket> MsgSender<I> for UnlinkMsgSocket<I, O> {}
impl<I: MsgOnSocket, O: MsgOnSocket> MsgReceiver<O> for UnlinkMsgSocket<I, O> {}

impl<M: MsgOnSocket> MsgSender<M> for Sender<M> {}
impl<M: MsgOnSocket> MsgReceiver<M> for Receiver<M> {}
<|endoftext|>


<commit_before>//! Serialization for TimeSteward data.
//!
//! TimeSteward has a few special requirements for serialization:
//! * DataTimelineHandle objects get special consideration, to support DAGs and cyclic data structures.
//! * The serialization needs to not block other operations for more than O(1) time at a time.
//! * The serialization must be lossless and platform-independent. For this reason, we always use bincode in low-endian mode.

macro_rules! time_steward_serialization_impls_for_handle {
  (
    [$($bounds:tt)*]
    [$($concrete:tt)*]
    (&$self_hack: ident)
    Uniquely identified by (($identifier: expr): $Identifier: ty)
    Data located at (| $handle: ident | &mut $data: expr)
  ) => {

/*thread_local! {
  static SERIALIZATION_CONTEXT: RefCell<Option <SerializationContext>> = RefCell::new (None);
  static DESERIALIZATION_CONTEXT: RefCell<Option <DeserializationContext>> = RefCell::new (None);
}*/

impl <$($bounds)*> $crate::serde::Serialize for $($concrete)* {
  fn serialize <S: $crate::serde::Serializer> (&$self_hack, serializer: S)->Result <S::Ok, S::Error> {
    unimplemented!()
    /*
    SERIALIZATION_CONTEXT.with (| cell | {
      let mut guard = cell.borrow_mut();
      let mut map = &mut guard.unwrap().map;
      map.insert (
    })
    $identifier.serialize (serializer)
    */
  }
}

impl <'a, $($bounds)*> $crate::serde::Deserialize <'a> for $($concrete)* {
  fn deserialize <D: $crate::serde::Deserializer<'a>> (deserializer: D)->Result <Self, D::Error> {
    unimplemented!()
    /*
    let old_identifier = $Identifier::deserialize (deserializer)?;
    DESERIALIZATION_CONTEXT.with (| cell | {
      let mut guard = cell.borrow_mut();
      let mut map = &mut guard.unwrap().map;
      Ok(map.entry (old_pointer).or_insert_with (| | {
        unimplemented!()
        /*DataTimelineHandle {
          inner: Arc::new (unsafe {::std::mem::uninitialized()}),
        }*/
      }).clone().downcast::<T> ())
    })
    */
  }
}

/*
impl DeserializationContext {
  fn deserialize_(deserializer: D)->Result <(), D::Error> {
    let old_pointer = usize::deserialize (deserializer)?;
    DESERIALIZATION_CONTEXT.with (| cell | {
      let mut guard = cell.borrow_mut();
      let mut map = &mut guard.unwrap().map;
      let $handle = map.entry (old_pointer).or_insert_with (| | {
        unimplemented!()
        /*DataTimelineHandle {
          inner: Arc::new (unsafe {::std::mem::uninitialized()}),
        }*/
      });
      let new_pointer = &mut $data;
      unsafe {::std::ptr::write (
        new_pointer as *mut DataTimelineHandle,
        unimplemented!() //DataTimeline::deserialize (D)
      )?;}
    })?;
    Ok(())
  }
}*/

  };
}

<commit_msg>Wrote some more incomplete serialization stuff<commit_after>//! Serialization for TimeSteward data.
//!
//! TimeSteward has a few special requirements for serialization:
//! * DataTimelineHandle objects get special consideration, to support DAGs and cyclic data structures.
//! * The serialization needs to not block other operations for more than O(1) time at a time.
//! * The serialization must be lossless and platform-independent. For this reason, we always use bincode in low-endian mode.

macro_rules! time_steward_serialization_impls_for_handle {
  (
    [$($bounds:tt)*]
    [$($concrete:tt)*]
    (&$self_hack: ident)
    Uniquely identified by (($identifier: expr): $Identifier: ty)
    Data located at (| $handle: ident | &mut $data: expr)
  ) => {

/*thread_local! {
  static SERIALIZATION_CONTEXT: RefCell<Option <SerializationContext>> = RefCell::new (None);
  static DESERIALIZATION_CONTEXT: RefCell<Option <DeserializationContext>> = RefCell::new (None);
}*/

impl <$($bounds)*> $crate::serde::Serialize for $($concrete)* {
  fn serialize <S: $crate::serde::Serializer> (&$self_hack, serializer: S)->Result <S::Ok, S::Error> {
    unimplemented!()
    /*
    SERIALIZATION_CONTEXT.with (| cell | {
      let mut guard = cell.borrow_mut();
      let mut map = &mut guard.unwrap().map;
      map.insert (
    })
    $identifier.serialize (serializer)
    */
  }
}

impl <'a, $($bounds)*> $crate::serde::Deserialize <'a> for $($concrete)* {
  fn deserialize <D: $crate::serde::Deserializer<'a>> (deserializer: D)->Result <Self, D::Error> {
    unimplemented!()
    /*
    let old_identifier = $Identifier::deserialize (deserializer)?;
    DESERIALIZATION_CONTEXT.with (| cell | {
      let mut guard = cell.borrow_mut();
      let mut map = &mut guard.unwrap().map;
      Ok(map.entry (old_pointer).or_insert_with (| | {
        unimplemented!()
        /*DataTimelineHandle {
          inner: Arc::new (unsafe {::std::mem::uninitialized()}),
        }*/
      }).clone().downcast::<T> ())
    })
    */
  }
}

/*
impl DeserializationContext {
  fn deserialize_(deserializer: D)->Result <(), D::Error> {
    let old_pointer = usize::deserialize (deserializer)?;
    DESERIALIZATION_CONTEXT.with (| cell | {
      let mut guard = cell.borrow_mut();
      let mut map = &mut guard.unwrap().map;
      let $handle = map.entry (old_pointer).or_insert_with (| | {
        unimplemented!()
        /*DataTimelineHandle {
          inner: Arc::new (unsafe {::std::mem::uninitialized()}),
        }*/
      });
      let new_pointer = &mut $data;
      unsafe {::std::ptr::write (
        new_pointer as *mut DataTimelineHandle,
        unimplemented!() //DataTimeline::deserialize (D)
      )?;}
    })?;
    Ok(())
  }
}*/

  };
}

macro_rules! time_steward_serialization_impls {
  () => {
  fn deserialize_something <R: Read> (reader: &mut R)->$crate::bincode::Result <()> {
    DESERIALIZATION_CONTEXT.with (| cell | {
      {
        let guard = cell.borrow_mut();
        assert!(guard.is_none(), "deserializing recursively breaks my hacks probably makes no sense");
        *guard = Some(DeserializationContext::new());
      }
      // deserialize inside a closure so that errors can be collected and we still clear the context afterwards
      let result = || {
        let time: ExtendedTime <B> = deserialize_from (reader, ::std::mem::size_of::<ExtendedTime <B>>())?;
        let global_timeline: DataTimelineHandle <B::GlobalTimeline> = deserialize_from (reader, $crate::bincode::Infinite)?;

        while !cell.borrow().uninitialized.is_empty() {
          let next: ????? = deserialize_from (reader, $crate::bincode::Infinite)?;
          match next {
            ?????::DataTimeline (type_id) => {
              let deserialize_function = cell.borrow().?????.get (type_id);
              (*deserialize_function)();
            }
            ?????::Event (type_id) => {
              let deserialize_function = cell.borrow().?????.get (type_id);
              (*deserialize_function)();
            }
          };
        }
      }();

      {
        let guard = cell.borrow_mut();
        *guard = None;
      }
      result
    })
  }
  };
}

<|endoftext|>


<commit_before>use std::ops::{ Index, IndexMut };

struct GenericPixmap<T> {
    w: usize,
    h: usize,

    data: Vec<T>
}

impl<T> GenericPixmap<T>
    where T: Copy + Clone
{
    fn new(w: usize, h: usize, fill_value: T) -> GenericPixmap<T> {
        GenericPixmap {
            w: w,
            h: h,
            data: vec![fill_value; w*h]
        }
    }
}

impl<T> Index<usize> for  GenericPixmap<T>
    where T: Copy + Clone
{
    type Output = [T];

    fn index<'a>(&'a self, i: usize) -> &'a Self::Output {
        let from = i*self.w;
        let to = from+self.w;
        &self.data[from..to]
    }
}
impl<T> IndexMut<usize> for GenericPixmap<T>
    where T: Copy + Clone
{
    fn index_mut<'a>(&'a mut self, i: usize) -> &'a mut Self::Output {
        let from = i*self.w;
        let to = from+self.w;
        &mut self.data[from..to]
    }
}

type Pixmap = GenericPixmap<u32>;

trait Canvas
{
    fn set_pixel(&mut self, x: usize, y:usize, color:u32);
}

impl Canvas for Pixmap
{
    fn set_pixel(&mut self, x: usize, y:usize, color:u32)
    {
        self[x][y] = color;
    }
}

#[derive(Copy, Clone, PartialEq)]
struct Vec3 {
    x: i32,
    y: i32,
    z: i32
}

impl Index<usize> for Vec3
{
    type Output = i32;

    fn index<'a>(&'a self, i: usize) -> &'a Self::Output {
        match i {
            0   => &self.x,
            1   => &self.y,
            2   => &self.z,
            _   => panic!("Wrong index"),
        }
    }
}
impl IndexMut<usize> for Vec3
{
    fn index_mut<'a>(&'a mut self, i: usize) -> &'a mut Self::Output {
        match i {
            0   => &mut self.x,
            1   => &mut self.y,
            2   => &mut self.z,
            _   => panic!("Wrong index"),
        }
    }
}

struct RasterState {
    step: Vec3,
    d: Vec3,
    major_axis: usize,
}

struct LineRasterizer {
    from: Vec3,
    to: Vec3,

    state: Option<RasterState>
}

impl LineRasterizer {

    fn new(from: Vec3, to: Vec3) -> LineRasterizer {
        LineRasterizer {
            from: from,
            to: to,
            state: None
        }
    }

    fn next_point(&mut self) -> Option<Vec3> {
        match self.state {
            None => {
                let mut state = RasterState {
                    step: Vec3 { x: 0, y: 0, z: 0 },
                    d: Vec3 { x: 0, y: 0, z: 0 },
                    major_axis: 0
                };

                let mut max = 0;
                for i in 0..3 {
                    let d = self.to[i] - self.from[i];
                    state.step[i] = if d > 0 { 1 } else { -1 };

                    let d = d.abs();
                    if d > max {
                        max = d;
                        state.major_axis = i as usize;
                    };
                }

                self.state = Some(state);
                Some(self.from)
            },
            Some(ref mut state) => {
                if self.from == self.to {
                    None
                } else {
                    let from = self.from; let to = self.to;
                    let calc_residual_steps = |axis| { (to[axis] - from[axis]).abs() };

                    self.from[state.major_axis] += state.step[state.major_axis];
                    let rs_base = calc_residual_steps(state.major_axis);
                    for i in 0..3 {
                        let rs = calc_residual_steps(i);

                        if rs > 0 && i != state.major_axis {
                            state.d[i] += rs;
                            if state.d[i] >= rs_base {
                                state.d[i] -= rs_base;
                                self.from[i] += state.step[i];
                            }
                        }
                    }

                    Some(self.from)
                }
            },
        }
    }
}

fn main() {
    let mut canvas = Pixmap::new(300, 300, 0);

    let a = Vec3 { x: 0, y:0, z:0 };
    let b = Vec3 { x: 10, y: 5, z: -4 };

    let mut rasterizer = LineRasterizer::new(a, b);
    while let Some(point) = rasterizer.next_point() {
        let color = std::u32::MAX;
        canvas.set_pixel(point.x as usize, point.y as usize, color);
        println!("point: x: {}, y: {}, z: {}, color: #{:X}", point.x, point.y, point.z, color);
    }
}
<commit_msg>Impl iterator trait<commit_after>use std::ops::{ Index, IndexMut };

struct GenericPixmap<T> {
    w: usize,
    h: usize,

    data: Vec<T>
}

impl<T> GenericPixmap<T>
    where T: Copy + Clone
{
    fn new(w: usize, h: usize, fill_value: T) -> GenericPixmap<T> {
        GenericPixmap {
            w: w,
            h: h,
            data: vec![fill_value; w*h]
        }
    }
}

impl<T> Index<usize> for  GenericPixmap<T>
    where T: Copy + Clone
{
    type Output = [T];

    fn index<'a>(&'a self, i: usize) -> &'a Self::Output {
        let from = i*self.w;
        let to = from+self.w;
        &self.data[from..to]
    }
}
impl<T> IndexMut<usize> for GenericPixmap<T>
    where T: Copy + Clone
{
    fn index_mut<'a>(&'a mut self, i: usize) -> &'a mut Self::Output {
        let from = i*self.w;
        let to = from+self.w;
        &mut self.data[from..to]
    }
}

type Pixmap = GenericPixmap<u32>;

trait Canvas
{
    fn set_pixel(&mut self, x: usize, y:usize, color:u32);
}

impl Canvas for Pixmap
{
    fn set_pixel(&mut self, x: usize, y:usize, color:u32)
    {
        self[x][y] = color;
    }
}

#[derive(Copy, Clone, PartialEq)]
struct Vec3 {
    x: i32,
    y: i32,
    z: i32
}

impl Index<usize> for Vec3
{
    type Output = i32;

    fn index<'a>(&'a self, i: usize) -> &'a Self::Output {
        match i {
            0   => &self.x,
            1   => &self.y,
            2   => &self.z,
            _   => panic!("Wrong index"),
        }
    }
}
impl IndexMut<usize> for Vec3
{
    fn index_mut<'a>(&'a mut self, i: usize) -> &'a mut Self::Output {
        match i {
            0   => &mut self.x,
            1   => &mut self.y,
            2   => &mut self.z,
            _   => panic!("Wrong index"),
        }
    }
}

struct RasterState {
    step: Vec3,
    d: Vec3,
    major_axis: usize,
}

struct LineRasterizer {
    from: Vec3,
    to: Vec3,

    state: Option<RasterState>
}

impl LineRasterizer {

    fn new(from: Vec3, to: Vec3) -> LineRasterizer {
        LineRasterizer {
            from: from,
            to: to,
            state: None
        }
    }

    fn next_point(&mut self) -> Option<Vec3> {
        match self.state {
            None => {
                let mut state = RasterState {
                    step: Vec3 { x: 0, y: 0, z: 0 },
                    d: Vec3 { x: 0, y: 0, z: 0 },
                    major_axis: 0
                };

                let mut max = 0;
                for i in 0..3 {
                    let d = self.to[i] - self.from[i];
                    state.step[i] = if d > 0 { 1 } else { -1 };

                    let d = d.abs();
                    if d > max {
                        max = d;
                        state.major_axis = i as usize;
                    };
                }

                self.state = Some(state);
                Some(self.from)
            },
            Some(ref mut state) => {
                if self.from == self.to {
                    None
                } else {
                    let from = self.from; let to = self.to;
                    let calc_residual_steps = |axis| { (to[axis] - from[axis]).abs() };

                    self.from[state.major_axis] += state.step[state.major_axis];
                    let rs_base = calc_residual_steps(state.major_axis);
                    for i in 0..3 {
                        let rs = calc_residual_steps(i);

                        if rs > 0 && i != state.major_axis {
                            state.d[i] += rs;
                            if state.d[i] >= rs_base {
                                state.d[i] -= rs_base;
                                self.from[i] += state.step[i];
                            }
                        }
                    }

                    Some(self.from)
                }
            },
        }
    }
}

impl Iterator for LineRasterizer
{
    type Item = Vec3;

    fn next(&mut self) -> Option<Self::Item> {
        self.next_point()
    }
}

fn main() {
    let mut canvas = Pixmap::new(300, 300, 0);

    let a = Vec3 { x: 0, y:0, z:0 };
    let b = Vec3 { x: 10, y: 5, z: -4 };

    let rasterizer = LineRasterizer::new(a, b);
    for point in rasterizer {
        let color = std::u32::MAX;
        canvas.set_pixel(point.x as usize, point.y as usize, color);
        println!("point: x: {}, y: {}, z: {}, color: #{:X}", point.x, point.y, point.z, color);
    }
}
<|endoftext|>