<commit_before>use types::*;
use amq_protocol::types::flags::*;
use amq_protocol::types::generation::*;
use amq_protocol::types::parsing::*;
use cookie_factory::*;
use nom::{be_i8,be_i16,be_i32,be_i64,be_u8,be_u16,be_u32,be_u64};

#[derive(Clone,Debug,PartialEq)]
pub enum Class {
  {{#each specs.classes as |class| ~}}
    {{camel class.name}}({{snake class.name}}::Methods),
  {{/each ~}}
  None,
}

macro_rules! call_path (
  ($i: expr, $p: path) => ($p($i))
);

named!(pub parse_class<Class>,
  switch!(be_u16,
    {{#each specs.classes as |class| ~}}
    {{class.id}} => call_path!({{snake class.name}}::parse) |
    {{/each ~}}
  _  => value!(Class::None)
  )
);

pub fn gen_class<'a>(input:(&'a mut [u8],usize), class: &Class) -> Result<(&'a mut [u8],usize),GenError> {
  match class {
    {{#each specs.classes as |class| ~}}
    &Class::{{camel class.name}}(ref {{snake class.name}}) => {
      {{snake class.name}}::gen(input, {{snake class.name}})
    },
    {{/each ~}}
    &Class::None => Err(GenError::CustomError(14)),
  }
}

{{#each specs.classes as |class|}}
  pub mod {{snake class.name}} {
    use super::Class;
    use types::*;
    use amq_protocol::types::flags::*;
    use amq_protocol::types::generation::*;
    use amq_protocol::types::parsing::*;
    use cookie_factory::*;
    use nom::{be_i8,be_i16,be_i32,be_i64,be_u8,be_u16,be_u32,be_u64};

    #[derive(Clone,Debug,PartialEq)]
    pub enum Methods {
      {{#each class.methods as |method| ~}}
        {{camel method.name}}({{camel method.name}}),
      {{/each ~}}
      None,
    }

    named!(pub parse<Class>,
      switch!(be_u16,
        {{#each class.methods as |method| ~}}
        {{method.id}} => map!(call!(parse_{{snake method.name}}), |m| Class::{{camel class.name}}(m)) |
        {{/each ~}}
        _  => value!(Class::{{camel class.name}}(Methods::None))
      )
    );

    pub fn gen<'a>(input:(&'a mut [u8],usize), method: &Methods) -> Result<(&'a mut [u8],usize),GenError> {
      match method {
        {{#each class.methods as |method| ~}}
        &Methods::{{camel method.name}}(ref {{snake method.name}}) => {
          do_gen!(input,
            gen_be_u16!({{class.id}}u16) >>
            gen_{{snake method.name}}({{snake method.name}})
          )
        },
        {{/each ~}}
        &Methods::None => Err(GenError::CustomError(15)),
      }
    }

    {{#each class.methods as |method|}}
      #[derive(Clone,Debug,PartialEq)]
      pub struct {{camel method.name}} {
        {{#each_argument method.arguments as |argument| ~}}
          {{#if argument_is_value ~}}
            pub {{snake argument.name}}: {{argument.type}},
          {{else}}
            {{#each_flag argument as |flag| ~}}
              pub {{snake flag.name}}: Boolean,
            {{/each_flag ~}}
          {{/if ~}}
        {{/each_argument ~}}
      }

      named!(parse_{{snake method.name}}<Methods>,
        do_parse!(
          {{#each_argument method.arguments as |argument| ~}}
            {{#if argument_is_value ~}}
              {{snake argument.name}} : parse_{{snake_type argument.type}} >>
            {{else}}
              flags : apply!(parse_flags, &vec![
                {{#each_flag argument as |flag| ~}}
                  "{{flag.name}}",
                {{/each_flag ~}}
              ]) >>
            {{/if ~}}
          {{/each_argument ~}}

          (Methods::{{camel method.name}}({{camel method.name}} {
            {{#each_argument method.arguments as |argument| ~}}
              {{#if argument_is_value ~}}
                {{snake argument.name}}: {{snake argument.name}},
              {{else}}
                {{#each_flag argument as |flag| ~}}
                  {{snake flag.name}}: flags.get_flag("{{snake flag.name}}").unwrap_or({{flag.default_value}}),
                {{/each_flag ~}}
              {{/if ~}}
            {{/each_argument ~}}
          }))
        )
      );

      pub fn gen_{{snake method.name}}<'a>(input:(&'a mut [u8],usize), method: &{{camel method.name}}) -> Result<(&'a mut [u8],usize),GenError> {
        {{#if method.has_flags ~}}
          let mut flags = AMQPFlags::new();
          {{#each_argument method.arguments as |argument| ~}}
            {{#unless argument_is_value ~}}
              {{#each_flag argument as |flag| ~}}
                flags.add_flag("{{snake flag.name}}".to_string(), method.{{snake flag.name}});
              {{/each_flag ~}}
            {{/unless ~}}
          {{/each_argument ~}}
        {{/if ~}}
        do_gen!(input,
          gen_be_u16!({{method.id}}u16)
          {{#each_argument method.arguments as |argument| ~}}
            {{#if argument_is_value ~}}
              >> gen_{{snake_type argument.type}}(&method.{{snake argument.name}})
            {{else}}
              >> gen_flags(&flags)
            {{/if ~}}
          {{/each_argument ~}}
        )
      }
    {{/each}}
    {{#if class.has_properties ~}}
    #[derive(Clone,Debug,PartialEq)]
    pub struct Properties {
      {{#each class.properties as |property| ~}}
        pub {{snake property.name}}: Option<{{property.type}}>,
      {{/each ~}}
    }

    impl Default for Properties {
      fn default() -> Properties {
        Properties {
          {{#each class.properties as |property| ~}}
            {{snake property.name}}: None,
          {{/each ~}}
        }
      }
    }

    impl Properties {
      {{#each class.properties as |property| ~}}
        pub fn with_{{snake property.name}}(mut self, value: {{property.type}}) -> Properties {
          self.{{snake property.name}} = Some(value);
          self
        }
      {{/each ~}}

      pub fn bitmask(&self) -> ShortUInt {
        {{#each class.properties as |property| ~}}
          (if self.{{snake property.name}}.is_some() { 1 << (15 - {{@index}}) } else { 0 }) {{#unless @last ~}} + {{/unless ~}}
        {{/each ~}}
      }
    }

    named!(pub properties<Properties>, do_parse!(
      flags: parse_short_uint >>
      {{#each class.properties as |property| ~}}
        {{snake property.name}}: cond!(flags & (1 << (15 - {{@index}})) != 0, parse_{{snake_type property.type}}) >>
      {{/each ~}}
      (Properties {
        {{#each class.properties as |property| ~}}
          {{snake property.name}}: {{snake property.name}},
        {{/each ~}}
      })
    ));

    pub fn gen_properties<'a>(input:(&'a mut [u8],usize), props: &Properties) -> Result<(&'a mut [u8],usize),GenError> {
      do_gen!(input,
        gen_short_uint(&props.bitmask())
        {{#each class.properties as |property| ~}}
          >> gen_cond!(props.{{snake property.name}}.is_some(), gen_call!(gen_{{snake_type property.type}}, &props.{{snake property.name}}.as_ref().unwrap()))
        {{/each ~}}
      )
    }
    {{/if ~}}
  }
{{/each}}
<commit_msg>async: don't use AMQPFlags::new<commit_after>use types::*;
use amq_protocol::types::flags::*;
use amq_protocol::types::generation::*;
use amq_protocol::types::parsing::*;
use cookie_factory::*;
use nom::{be_i8,be_i16,be_i32,be_i64,be_u8,be_u16,be_u32,be_u64};

#[derive(Clone,Debug,PartialEq)]
pub enum Class {
  {{#each specs.classes as |class| ~}}
    {{camel class.name}}({{snake class.name}}::Methods),
  {{/each ~}}
  None,
}

macro_rules! call_path (
  ($i: expr, $p: path) => ($p($i))
);

named!(pub parse_class<Class>,
  switch!(be_u16,
    {{#each specs.classes as |class| ~}}
    {{class.id}} => call_path!({{snake class.name}}::parse) |
    {{/each ~}}
  _  => value!(Class::None)
  )
);

pub fn gen_class<'a>(input:(&'a mut [u8],usize), class: &Class) -> Result<(&'a mut [u8],usize),GenError> {
  match class {
    {{#each specs.classes as |class| ~}}
    &Class::{{camel class.name}}(ref {{snake class.name}}) => {
      {{snake class.name}}::gen(input, {{snake class.name}})
    },
    {{/each ~}}
    &Class::None => Err(GenError::CustomError(14)),
  }
}

{{#each specs.classes as |class|}}
  pub mod {{snake class.name}} {
    use super::Class;
    use types::*;
    use amq_protocol::types::flags::*;
    use amq_protocol::types::generation::*;
    use amq_protocol::types::parsing::*;
    use cookie_factory::*;
    use nom::{be_i8,be_i16,be_i32,be_i64,be_u8,be_u16,be_u32,be_u64};

    #[derive(Clone,Debug,PartialEq)]
    pub enum Methods {
      {{#each class.methods as |method| ~}}
        {{camel method.name}}({{camel method.name}}),
      {{/each ~}}
      None,
    }

    named!(pub parse<Class>,
      switch!(be_u16,
        {{#each class.methods as |method| ~}}
        {{method.id}} => map!(call!(parse_{{snake method.name}}), |m| Class::{{camel class.name}}(m)) |
        {{/each ~}}
        _  => value!(Class::{{camel class.name}}(Methods::None))
      )
    );

    pub fn gen<'a>(input:(&'a mut [u8],usize), method: &Methods) -> Result<(&'a mut [u8],usize),GenError> {
      match method {
        {{#each class.methods as |method| ~}}
        &Methods::{{camel method.name}}(ref {{snake method.name}}) => {
          do_gen!(input,
            gen_be_u16!({{class.id}}u16) >>
            gen_{{snake method.name}}({{snake method.name}})
          )
        },
        {{/each ~}}
        &Methods::None => Err(GenError::CustomError(15)),
      }
    }

    {{#each class.methods as |method|}}
      #[derive(Clone,Debug,PartialEq)]
      pub struct {{camel method.name}} {
        {{#each_argument method.arguments as |argument| ~}}
          {{#if argument_is_value ~}}
            pub {{snake argument.name}}: {{argument.type}},
          {{else}}
            {{#each_flag argument as |flag| ~}}
              pub {{snake flag.name}}: Boolean,
            {{/each_flag ~}}
          {{/if ~}}
        {{/each_argument ~}}
      }

      named!(parse_{{snake method.name}}<Methods>,
        do_parse!(
          {{#each_argument method.arguments as |argument| ~}}
            {{#if argument_is_value ~}}
              {{snake argument.name}} : parse_{{snake_type argument.type}} >>
            {{else}}
              flags : apply!(parse_flags, &vec![
                {{#each_flag argument as |flag| ~}}
                  "{{flag.name}}",
                {{/each_flag ~}}
              ]) >>
            {{/if ~}}
          {{/each_argument ~}}

          (Methods::{{camel method.name}}({{camel method.name}} {
            {{#each_argument method.arguments as |argument| ~}}
              {{#if argument_is_value ~}}
                {{snake argument.name}}: {{snake argument.name}},
              {{else}}
                {{#each_flag argument as |flag| ~}}
                  {{snake flag.name}}: flags.get_flag("{{snake flag.name}}").unwrap_or({{flag.default_value}}),
                {{/each_flag ~}}
              {{/if ~}}
            {{/each_argument ~}}
          }))
        )
      );

      pub fn gen_{{snake method.name}}<'a>(input:(&'a mut [u8],usize), method: &{{camel method.name}}) -> Result<(&'a mut [u8],usize),GenError> {
        {{#if method.has_flags ~}}
          let mut flags = AMQPFlags::default();
          {{#each_argument method.arguments as |argument| ~}}
            {{#unless argument_is_value ~}}
              {{#each_flag argument as |flag| ~}}
                flags.add_flag("{{snake flag.name}}".to_string(), method.{{snake flag.name}});
              {{/each_flag ~}}
            {{/unless ~}}
          {{/each_argument ~}}
        {{/if ~}}
        do_gen!(input,
          gen_be_u16!({{method.id}}u16)
          {{#each_argument method.arguments as |argument| ~}}
            {{#if argument_is_value ~}}
              >> gen_{{snake_type argument.type}}(&method.{{snake argument.name}})
            {{else}}
              >> gen_flags(&flags)
            {{/if ~}}
          {{/each_argument ~}}
        )
      }
    {{/each}}
    {{#if class.has_properties ~}}
    #[derive(Clone,Debug,PartialEq)]
    pub struct Properties {
      {{#each class.properties as |property| ~}}
        pub {{snake property.name}}: Option<{{property.type}}>,
      {{/each ~}}
    }

    impl Default for Properties {
      fn default() -> Properties {
        Properties {
          {{#each class.properties as |property| ~}}
            {{snake property.name}}: None,
          {{/each ~}}
        }
      }
    }

    impl Properties {
      {{#each class.properties as |property| ~}}
        pub fn with_{{snake property.name}}(mut self, value: {{property.type}}) -> Properties {
          self.{{snake property.name}} = Some(value);
          self
        }
      {{/each ~}}

      pub fn bitmask(&self) -> ShortUInt {
        {{#each class.properties as |property| ~}}
          (if self.{{snake property.name}}.is_some() { 1 << (15 - {{@index}}) } else { 0 }) {{#unless @last ~}} + {{/unless ~}}
        {{/each ~}}
      }
    }

    named!(pub properties<Properties>, do_parse!(
      flags: parse_short_uint >>
      {{#each class.properties as |property| ~}}
        {{snake property.name}}: cond!(flags & (1 << (15 - {{@index}})) != 0, parse_{{snake_type property.type}}) >>
      {{/each ~}}
      (Properties {
        {{#each class.properties as |property| ~}}
          {{snake property.name}}: {{snake property.name}},
        {{/each ~}}
      })
    ));

    pub fn gen_properties<'a>(input:(&'a mut [u8],usize), props: &Properties) -> Result<(&'a mut [u8],usize),GenError> {
      do_gen!(input,
        gen_short_uint(&props.bitmask())
        {{#each class.properties as |property| ~}}
          >> gen_cond!(props.{{snake property.name}}.is_some(), gen_call!(gen_{{snake_type property.type}}, &props.{{snake property.name}}.as_ref().unwrap()))
        {{/each ~}}
      )
    }
    {{/if ~}}
  }
{{/each}}
<|endoftext|>


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

use dom::bindings::codegen::AttrBinding;
use dom::bindings::js::JS;
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::window::Window;
use servo_util::namespace::Namespace;
use servo_util::str::DOMString;

#[deriving(Encodable)]
pub struct Attr {
    reflector_: Reflector,
    local_name: DOMString,
    value: DOMString,
    name: DOMString,
    namespace: Namespace,
    prefix: Option<DOMString>
}

impl Reflectable for Attr {
    fn reflector<'a>(&'a self) -> &'a Reflector {
        &self.reflector_
    }

    fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
        &mut self.reflector_
    }
}

impl Attr {
    fn new_inherited(local_name: DOMString, value: DOMString,
                     name: DOMString, namespace: Namespace,
                     prefix: Option<DOMString>) -> Attr {
        Attr {
            reflector_: Reflector::new(),
            local_name: local_name,
            value: value,
            name: name, //TODO: Intern attribute names
            namespace: namespace,
            prefix: prefix
        }
    }

    pub fn new(window: &JS<Window>, local_name: DOMString, value: DOMString,
               name: DOMString, namespace: Namespace,
               prefix: Option<DOMString>) -> JS<Attr> {
        let attr = Attr::new_inherited(local_name, value, name, namespace, prefix);
        reflect_dom_object(~attr, window, AttrBinding::Wrap)
    }

    pub fn set_value(&mut self, value: DOMString) {
        self.value = value;
    }

    pub fn value_ref<'a>(&'a self) -> &'a str {
        self.value.as_slice()
    }
}

impl Attr {
    pub fn LocalName(&self) -> DOMString {
        self.local_name.clone()
    }

    pub fn Value(&self) -> DOMString {
        self.value.clone()
    }

    pub fn SetValue(&mut self, value: DOMString) {
        self.value = value;
    }

    pub fn Name(&self) -> DOMString {
        self.name.clone()
    }

    pub fn GetNamespaceURI(&self) -> Option<DOMString> {
        match self.namespace.to_str() {
            "" => None,
            url => Some(url.to_owned()),
        }
    }

    pub fn GetPrefix(&self) -> Option<DOMString> {
        self.prefix.clone()
    }
}
<commit_msg>Make Attr::SetValue uses the internal setter.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::bindings::codegen::AttrBinding;
use dom::bindings::js::JS;
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::window::Window;
use servo_util::namespace::Namespace;
use servo_util::str::DOMString;

#[deriving(Encodable)]
pub struct Attr {
    reflector_: Reflector,
    local_name: DOMString,
    value: DOMString,
    name: DOMString,
    namespace: Namespace,
    prefix: Option<DOMString>
}

impl Reflectable for Attr {
    fn reflector<'a>(&'a self) -> &'a Reflector {
        &self.reflector_
    }

    fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
        &mut self.reflector_
    }
}

impl Attr {
    fn new_inherited(local_name: DOMString, value: DOMString,
                     name: DOMString, namespace: Namespace,
                     prefix: Option<DOMString>) -> Attr {
        Attr {
            reflector_: Reflector::new(),
            local_name: local_name,
            value: value,
            name: name, //TODO: Intern attribute names
            namespace: namespace,
            prefix: prefix
        }
    }

    pub fn new(window: &JS<Window>, local_name: DOMString, value: DOMString,
               name: DOMString, namespace: Namespace,
               prefix: Option<DOMString>) -> JS<Attr> {
        let attr = Attr::new_inherited(local_name, value, name, namespace, prefix);
        reflect_dom_object(~attr, window, AttrBinding::Wrap)
    }

    pub fn set_value(&mut self, value: DOMString) {
        self.value = value;
    }

    pub fn value_ref<'a>(&'a self) -> &'a str {
        self.value.as_slice()
    }
}

impl Attr {
    pub fn LocalName(&self) -> DOMString {
        self.local_name.clone()
    }

    pub fn Value(&self) -> DOMString {
        self.value.clone()
    }

    pub fn SetValue(&mut self, value: DOMString) {
        self.set_value(value);
    }

    pub fn Name(&self) -> DOMString {
        self.name.clone()
    }

    pub fn GetNamespaceURI(&self) -> Option<DOMString> {
        match self.namespace.to_str() {
            "" => None,
            url => Some(url.to_owned()),
        }
    }

    pub fn GetPrefix(&self) -> Option<DOMString> {
        self.prefix.clone()
    }
}
<|endoftext|>


<commit_before>use cpu::common_defs::OpcodeExecInfo;
use cpu::CpuState;
use cpu::DecodeRegister;
use cpu::common_defs::address_mode::AddressMode;
use cpu::common_defs::opcode_class::OpcodeClass;
use memory::Memory;

macro_rules! set_zs {
    ($cpu_state:expr,$val:expr) => ($cpu_state.Z = $val == 0;$cpu_state.S = $val >= 0x80 );
}

macro_rules! stack_push8 {
    ($cpu_state:expr,$mem:expr,$val:expr) => (try!($mem.write8(0x0100 | $cpu_state.sp,$val)); $cpu_state.sp-=1;);
}
macro_rules! stack_push16 {
    ($cpu_state:expr,$mem:expr,$val:expr) => (try!($mem.write16(0x0100 as u16 | $cpu_state.sp as u16 -1,$val)); $cpu_state.sp-=2;);
}
macro_rules! stack_pull8 {
    ($cpu_state:expr,$mem:expr) => {
        {
            $cpu_state.pc+=1;
            $mem.read8(0x0100 | $cpu_state.sp;)
        }
    }
}
macro_rules! stack_pull16 {
    ($cpu_state:expr,$mem:expr) => {
        {
            $cpu_state.pc+=2;
            $mem.read16(0x0100 as u16 | $cpu_state.sp as u16 -1)
        }
    }
}

#[derive(Debug)]
pub enum ExecutionError {
  MemoryError(::memory::MemoryError),
  UnexpectedOpcode(String),
  UnexpectedAddressMode(String)
}
impl From<::memory::MemoryError> for ExecutionError {
    fn from(err: ::memory::MemoryError) -> ExecutionError {
        ExecutionError::MemoryError(err)
    }
}

pub struct CpuExecutor {
    op_table: Vec<OpcodeExecInfo>,
}

impl CpuExecutor {
	/// Construct a new CpuExecutor.
    pub fn new(opcodes: Vec<OpcodeExecInfo> ) -> CpuExecutor {
        CpuExecutor {
            op_table:  opcodes,
        }
    }

	/// Reset the given cpu_state.
    pub fn power_on(self: &CpuExecutor, cpu_state: &mut CpuState, mem:&mut Memory) {
        self.reset(cpu_state,mem);
    }
	/// Reset the given cpu_state.
    pub fn reset(self: &CpuExecutor, cpu_state: &mut CpuState, mem:&mut Memory) {
        cpu_state.pc = mem.read16(0xFFFC).unwrap();
        cpu_state.sp = 0xFD;
        cpu_state.pack_flags(0x24);
    }

    /// Execute a single instruction in the given memory and cpu_state context.
    pub fn step(self: &CpuExecutor, cpu_state: &mut CpuState,mem:&mut Memory) -> Result<(),ExecutionError> {
        try!(self.fetch_and_decode(cpu_state,mem));
        try!(self.execute(cpu_state,mem));
        Ok(())
    }

	/// Fetch the next instruction and perform address resolution.
    pub fn fetch_and_decode(self: &CpuExecutor, cpu_state: &mut CpuState,mem:&mut Memory) -> Result<(),ExecutionError> {
        cpu_state.instruction_register = mem.read8(cpu_state.pc).unwrap();
        cpu_state.decode_register = try!(self.decode(cpu_state,mem));
        cpu_state.pc = cpu_state.pc+1;
        Ok(())
    }

    /// Perform address resolution, returning the info in a DecodeRegister.
    fn decode(self: &CpuExecutor, cpu_state: &CpuState, mem: &Memory) -> Result<DecodeRegister,ExecutionError> {
        let mut dr = DecodeRegister {
            info : self.op_table[cpu_state.instruction_register as usize].clone(),
            ..Default::default()
        };
        match dr.info.address_mode {
            // no explicit addresses for the following modes
            AddressMode::Accumulator  => { },
            AddressMode::Implied      => { },

            // explicit addresses from here on out
            AddressMode::Absolute => {
                dr.addr_final  = Some(mem.read16(cpu_state.pc+1).unwrap());
                dr.value_final = Some(mem.read8(dr.addr_final.unwrap()).unwrap());
            },
            AddressMode::AbsoluteX       => {
                dr.addr_final  = Some( ((mem.read16(cpu_state.pc+1).unwrap() as u32 + cpu_state.x as u32) % 65536) as u16);
                dr.value_final = Some(mem.read8(dr.addr_final.unwrap()).unwrap());
            },
            AddressMode::AbsoluteY       => {
                dr.addr_final  = Some( ((mem.read16(cpu_state.pc+1).unwrap() as u32 + cpu_state.y as u32) % 65536) as u16);
                dr.value_final = Some(mem.read8(dr.addr_final.unwrap()).unwrap());
            },
            AddressMode::Immediate       => {
                dr.addr_final  = Some(cpu_state.pc+1);
                dr.value_final = Some(mem.read8(dr.addr_final.unwrap()).unwrap());
            },
            AddressMode::Indirect        => {
                dr.addr_intermediate = Some(mem.read16(cpu_state.pc+1).unwrap());
                dr.addr_final        = Some(mem.read16(dr.addr_intermediate.unwrap()).unwrap());
            },
            AddressMode::IndexedIndirect => {
                dr.addr_intermediate = Some( (mem.read8(cpu_state.pc+1).unwrap() + cpu_state.x) as u16);
                dr.addr_final        = Some(mem.read16(dr.addr_intermediate.unwrap()).unwrap());
                dr.value_final       = Some(mem.read8(dr.addr_final.unwrap()).unwrap());
            },
            AddressMode::IndirectIndexed => {
                dr.addr_init         = Some(mem.read8(cpu_state.pc+1).unwrap() as u16);
                dr.addr_intermediate = Some(mem.read16(dr.addr_init.unwrap()).unwrap());
                dr.addr_final        = Some( ((dr.addr_intermediate.unwrap() as u32 + cpu_state.y as u32) % 65536) as u16);
                dr.value_final       = Some(mem.read8(dr.addr_final.unwrap()).unwrap());
            },
            AddressMode::Relative        => {
                dr.value_final = Some(mem.read8(cpu_state.pc+1).unwrap());

                // NOTE: relative is from the end of the current instruction and relative
                // instructions are 2 bytes long, so we add 2 before adding in the specified offset
                //
                if dr.value_final.unwrap() < 0x80 { dr.addr_final  = Some(cpu_state.pc + 2 + dr.value_final.unwrap() as u16); }
                else                              { dr.addr_final  = Some(cpu_state.pc + 2 + dr.value_final.unwrap() as u16 - 0x100);}
            },
            AddressMode::ZeroPage        => {
                dr.addr_final  = Some(mem.read8(cpu_state.pc+1).unwrap() as u16);
                dr.value_final = Some(mem.read8(dr.addr_final.unwrap()).unwrap());
            },
            AddressMode::ZeroPageX       => {
                dr.addr_final  = Some( (mem.read8(cpu_state.pc+1).unwrap() as u16 + cpu_state.x as u16) % 256);
                dr.value_final = Some(mem.read8(dr.addr_final.unwrap()).unwrap());
            },
            AddressMode::ZeroPageY       => {
                dr.addr_final  = Some( (mem.read8(cpu_state.pc+1).unwrap() as u16 + cpu_state.y as u16) % 256);
                dr.value_final = Some(mem.read8(dr.addr_final.unwrap()).unwrap());
            },
            _ => { return Err(ExecutionError::UnexpectedAddressMode(format!("unrecognized addressing mode '{:?}' while decoding instruction_register!",dr.info.address_mode))); }
        }

        return Ok(dr);
    }

    /// Perform the current instruction, returning the CpuState after execution.
    pub fn execute(self: &CpuExecutor, cpu_state: &mut CpuState, mem:&mut Memory) -> Result<(),ExecutionError> {
    	// Figure out which opcode is being executed.
    	match cpu_state.decode_register.info.opcode_class {
    		OpcodeClass::ASL => {
				cpu_state.a = cpu_state.a << 1;
				cpu_state.C = (128 & cpu_state.a) > 0;
    			if cpu_state.a == 0 { cpu_state.Z = true; }

                cpu_state.pc += cpu_state.decode_register.info.len as u16-1;
    		},
    		OpcodeClass::BCC => {
                if !cpu_state.C { cpu_state.pc = cpu_state.decode_register.addr_final.unwrap(); }
                else            { cpu_state.pc += cpu_state.decode_register.info.len as u16-1; }
    		},
    		OpcodeClass::BCS => {
                if cpu_state.C { cpu_state.pc = cpu_state.decode_register.addr_final.unwrap(); }
                else           { cpu_state.pc += cpu_state.decode_register.info.len as u16-1; }
    		},
    		OpcodeClass::BEQ => {
                if cpu_state.Z { cpu_state.pc = cpu_state.decode_register.addr_final.unwrap(); }
                else           { cpu_state.pc += cpu_state.decode_register.info.len as u16-1; }
    		},
    		OpcodeClass::CLC => {
                cpu_state.C = false;
    		},
    		OpcodeClass::LDA => {
    			cpu_state.a = cpu_state.decode_register.value_final.unwrap();
                set_zs!(cpu_state,cpu_state.a);

                cpu_state.pc += cpu_state.decode_register.info.len as u16-1;
    		},
    		OpcodeClass::LDX => {
    			cpu_state.x = cpu_state.decode_register.value_final.unwrap();
                set_zs!(cpu_state,cpu_state.x);

                cpu_state.pc += cpu_state.decode_register.info.len as u16-1;
    		},
    		OpcodeClass::LDY => {
    			cpu_state.y = cpu_state.decode_register.value_final.unwrap();
                set_zs!(cpu_state,cpu_state.y);

                cpu_state.pc += cpu_state.decode_register.info.len as u16-1;
    		},
    		OpcodeClass::LSR => {
    			cpu_state.a = cpu_state.a >> 1;
    			cpu_state.C = 1 & cpu_state.a > 0;
    			if cpu_state.a == 0 { cpu_state.Z = true; }

                cpu_state.pc += cpu_state.decode_register.info.len as u16-1;
    		},
    		OpcodeClass::JMP => {
    			cpu_state.pc = cpu_state.decode_register.addr_final.unwrap();
    		},
    		OpcodeClass::JSR => {
                stack_push16!(cpu_state,mem,cpu_state.pc-1);
    			cpu_state.pc = cpu_state.decode_register.addr_final.unwrap();
    		},
    		OpcodeClass::NOP => {
            },
    		OpcodeClass::SEC => {
                cpu_state.C = true;
    		},
    		OpcodeClass::STX => {
                try!(mem.write8(cpu_state.decode_register.addr_final.unwrap(),cpu_state.decode_register.value_final.unwrap()));
                cpu_state.pc += cpu_state.decode_register.info.len as u16-1;
    		},

			_ => { return Err(ExecutionError::UnexpectedOpcode(format!("Unrecognised opcode class: {:?}", cpu_state.decode_register.info.opcode_class)));}

    	}
        Ok(())
    }
}

<commit_msg>implemented BNE opcode<commit_after>use cpu::common_defs::OpcodeExecInfo;
use cpu::CpuState;
use cpu::DecodeRegister;
use cpu::common_defs::address_mode::AddressMode;
use cpu::common_defs::opcode_class::OpcodeClass;
use memory::Memory;

macro_rules! set_zs {
    ($cpu_state:expr,$val:expr) => ($cpu_state.Z = $val == 0;$cpu_state.S = $val >= 0x80 );
}

macro_rules! stack_push8 {
    ($cpu_state:expr,$mem:expr,$val:expr) => (try!($mem.write8(0x0100 | $cpu_state.sp,$val)); $cpu_state.sp-=1;);
}
macro_rules! stack_push16 {
    ($cpu_state:expr,$mem:expr,$val:expr) => (try!($mem.write16(0x0100 as u16 | $cpu_state.sp as u16 -1,$val)); $cpu_state.sp-=2;);
}
macro_rules! stack_pull8 {
    ($cpu_state:expr,$mem:expr) => {
        {
            $cpu_state.pc+=1;
            $mem.read8(0x0100 | $cpu_state.sp;)
        }
    }
}
macro_rules! stack_pull16 {
    ($cpu_state:expr,$mem:expr) => {
        {
            $cpu_state.pc+=2;
            $mem.read16(0x0100 as u16 | $cpu_state.sp as u16 -1)
        }
    }
}

#[derive(Debug)]
pub enum ExecutionError {
  MemoryError(::memory::MemoryError),
  UnexpectedOpcode(String),
  UnexpectedAddressMode(String)
}
impl From<::memory::MemoryError> for ExecutionError {
    fn from(err: ::memory::MemoryError) -> ExecutionError {
        ExecutionError::MemoryError(err)
    }
}

pub struct CpuExecutor {
    op_table: Vec<OpcodeExecInfo>,
}

impl CpuExecutor {
	/// Construct a new CpuExecutor.
    pub fn new(opcodes: Vec<OpcodeExecInfo> ) -> CpuExecutor {
        CpuExecutor {
            op_table:  opcodes,
        }
    }

	/// Reset the given cpu_state.
    pub fn power_on(self: &CpuExecutor, cpu_state: &mut CpuState, mem:&mut Memory) {
        self.reset(cpu_state,mem);
    }
	/// Reset the given cpu_state.
    pub fn reset(self: &CpuExecutor, cpu_state: &mut CpuState, mem:&mut Memory) {
        cpu_state.pc = mem.read16(0xFFFC).unwrap();
        cpu_state.sp = 0xFD;
        cpu_state.pack_flags(0x24);
    }

    /// Execute a single instruction in the given memory and cpu_state context.
    pub fn step(self: &CpuExecutor, cpu_state: &mut CpuState,mem:&mut Memory) -> Result<(),ExecutionError> {
        try!(self.fetch_and_decode(cpu_state,mem));
        try!(self.execute(cpu_state,mem));
        Ok(())
    }

	/// Fetch the next instruction and perform address resolution.
    pub fn fetch_and_decode(self: &CpuExecutor, cpu_state: &mut CpuState,mem:&mut Memory) -> Result<(),ExecutionError> {
        cpu_state.instruction_register = mem.read8(cpu_state.pc).unwrap();
        cpu_state.decode_register = try!(self.decode(cpu_state,mem));
        cpu_state.pc = cpu_state.pc+1;
        Ok(())
    }

    /// Perform address resolution, returning the info in a DecodeRegister.
    fn decode(self: &CpuExecutor, cpu_state: &CpuState, mem: &Memory) -> Result<DecodeRegister,ExecutionError> {
        let mut dr = DecodeRegister {
            info : self.op_table[cpu_state.instruction_register as usize].clone(),
            ..Default::default()
        };
        match dr.info.address_mode {
            // no explicit addresses for the following modes
            AddressMode::Accumulator  => { },
            AddressMode::Implied      => { },

            // explicit addresses from here on out
            AddressMode::Absolute => {
                dr.addr_final  = Some(mem.read16(cpu_state.pc+1).unwrap());
                dr.value_final = Some(mem.read8(dr.addr_final.unwrap()).unwrap());
            },
            AddressMode::AbsoluteX       => {
                dr.addr_final  = Some( ((mem.read16(cpu_state.pc+1).unwrap() as u32 + cpu_state.x as u32) % 65536) as u16);
                dr.value_final = Some(mem.read8(dr.addr_final.unwrap()).unwrap());
            },
            AddressMode::AbsoluteY       => {
                dr.addr_final  = Some( ((mem.read16(cpu_state.pc+1).unwrap() as u32 + cpu_state.y as u32) % 65536) as u16);
                dr.value_final = Some(mem.read8(dr.addr_final.unwrap()).unwrap());
            },
            AddressMode::Immediate       => {
                dr.addr_final  = Some(cpu_state.pc+1);
                dr.value_final = Some(mem.read8(dr.addr_final.unwrap()).unwrap());
            },
            AddressMode::Indirect        => {
                dr.addr_intermediate = Some(mem.read16(cpu_state.pc+1).unwrap());
                dr.addr_final        = Some(mem.read16(dr.addr_intermediate.unwrap()).unwrap());
            },
            AddressMode::IndexedIndirect => {
                dr.addr_intermediate = Some( (mem.read8(cpu_state.pc+1).unwrap() + cpu_state.x) as u16);
                dr.addr_final        = Some(mem.read16(dr.addr_intermediate.unwrap()).unwrap());
                dr.value_final       = Some(mem.read8(dr.addr_final.unwrap()).unwrap());
            },
            AddressMode::IndirectIndexed => {
                dr.addr_init         = Some(mem.read8(cpu_state.pc+1).unwrap() as u16);
                dr.addr_intermediate = Some(mem.read16(dr.addr_init.unwrap()).unwrap());
                dr.addr_final        = Some( ((dr.addr_intermediate.unwrap() as u32 + cpu_state.y as u32) % 65536) as u16);
                dr.value_final       = Some(mem.read8(dr.addr_final.unwrap()).unwrap());
            },
            AddressMode::Relative        => {
                dr.value_final = Some(mem.read8(cpu_state.pc+1).unwrap());

                // NOTE: relative is from the end of the current instruction and relative
                // instructions are 2 bytes long, so we add 2 before adding in the specified offset
                //
                if dr.value_final.unwrap() < 0x80 { dr.addr_final  = Some(cpu_state.pc + 2 + dr.value_final.unwrap() as u16); }
                else                              { dr.addr_final  = Some(cpu_state.pc + 2 + dr.value_final.unwrap() as u16 - 0x100);}
            },
            AddressMode::ZeroPage        => {
                dr.addr_final  = Some(mem.read8(cpu_state.pc+1).unwrap() as u16);
                dr.value_final = Some(mem.read8(dr.addr_final.unwrap()).unwrap());
            },
            AddressMode::ZeroPageX       => {
                dr.addr_final  = Some( (mem.read8(cpu_state.pc+1).unwrap() as u16 + cpu_state.x as u16) % 256);
                dr.value_final = Some(mem.read8(dr.addr_final.unwrap()).unwrap());
            },
            AddressMode::ZeroPageY       => {
                dr.addr_final  = Some( (mem.read8(cpu_state.pc+1).unwrap() as u16 + cpu_state.y as u16) % 256);
                dr.value_final = Some(mem.read8(dr.addr_final.unwrap()).unwrap());
            },
            _ => { return Err(ExecutionError::UnexpectedAddressMode(format!("unrecognized addressing mode '{:?}' while decoding instruction_register!",dr.info.address_mode))); }
        }

        return Ok(dr);
    }

    /// Perform the current instruction, returning the CpuState after execution.
    pub fn execute(self: &CpuExecutor, cpu_state: &mut CpuState, mem:&mut Memory) -> Result<(),ExecutionError> {
    	// Figure out which opcode is being executed.
    	match cpu_state.decode_register.info.opcode_class {
    		OpcodeClass::ASL => {
				cpu_state.a = cpu_state.a << 1;
				cpu_state.C = (128 & cpu_state.a) > 0;
    			if cpu_state.a == 0 { cpu_state.Z = true; }

                cpu_state.pc += cpu_state.decode_register.info.len as u16-1;
    		},
    		OpcodeClass::BCC => {
                if !cpu_state.C { cpu_state.pc = cpu_state.decode_register.addr_final.unwrap(); }
                else            { cpu_state.pc += cpu_state.decode_register.info.len as u16-1;  }
    		},
    		OpcodeClass::BCS => {
                if cpu_state.C { cpu_state.pc = cpu_state.decode_register.addr_final.unwrap(); }
                else           { cpu_state.pc += cpu_state.decode_register.info.len as u16-1;  }
    		},
    		OpcodeClass::BEQ => {
                if cpu_state.Z { cpu_state.pc = cpu_state.decode_register.addr_final.unwrap(); }
                else           { cpu_state.pc += cpu_state.decode_register.info.len as u16-1;  }
    		},
    		OpcodeClass::BNE => {
                if !cpu_state.Z { cpu_state.pc = cpu_state.decode_register.addr_final.unwrap(); }
                else            { cpu_state.pc += cpu_state.decode_register.info.len as u16-1;  }
    		},
    		OpcodeClass::CLC => {
                cpu_state.C = false;
    		},
    		OpcodeClass::LDA => {
    			cpu_state.a = cpu_state.decode_register.value_final.unwrap();
                set_zs!(cpu_state,cpu_state.a);

                cpu_state.pc += cpu_state.decode_register.info.len as u16-1;
    		},
    		OpcodeClass::LDX => {
    			cpu_state.x = cpu_state.decode_register.value_final.unwrap();
                set_zs!(cpu_state,cpu_state.x);

                cpu_state.pc += cpu_state.decode_register.info.len as u16-1;
    		},
    		OpcodeClass::LDY => {
    			cpu_state.y = cpu_state.decode_register.value_final.unwrap();
                set_zs!(cpu_state,cpu_state.y);

                cpu_state.pc += cpu_state.decode_register.info.len as u16-1;
    		},
    		OpcodeClass::LSR => {
    			cpu_state.a = cpu_state.a >> 1;
    			cpu_state.C = 1 & cpu_state.a > 0;
    			if cpu_state.a == 0 { cpu_state.Z = true; }

                cpu_state.pc += cpu_state.decode_register.info.len as u16-1;
    		},
    		OpcodeClass::JMP => {
    			cpu_state.pc = cpu_state.decode_register.addr_final.unwrap();
    		},
    		OpcodeClass::JSR => {
                stack_push16!(cpu_state,mem,cpu_state.pc-1);
    			cpu_state.pc = cpu_state.decode_register.addr_final.unwrap();
    		},
    		OpcodeClass::NOP => {
            },
    		OpcodeClass::SEC => {
                cpu_state.C = true;
    		},
    		OpcodeClass::STX => {
                try!(mem.write8(cpu_state.decode_register.addr_final.unwrap(),cpu_state.decode_register.value_final.unwrap()));
                cpu_state.pc += cpu_state.decode_register.info.len as u16-1;
    		},

			_ => { return Err(ExecutionError::UnexpectedOpcode(format!("Unrecognised opcode class: {:?}", cpu_state.decode_register.info.opcode_class)));}

    	}
        Ok(())
    }
}

<|endoftext|>


<commit_before>// Copyright (c) 2019, The rav1e contributors. All rights reserved
//
// This source code is subject to the terms of the BSD 2 Clause License and
// the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
// was not distributed with this source code in the LICENSE file, you can
// obtain it at www.aomedia.org/license/software. If the Alliance for Open
// Media Patent License 1.0 was not distributed with this source code in the
// PATENTS file, you can obtain it at www.aomedia.org/license/patent.

use arg_enum_proc_macro::ArgEnum;
use std::env;
use std::str::FromStr;

#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, ArgEnum)]
pub enum CpuFeatureLevel {
  #[arg_enum(alias = "rust")]
  NATIVE,
  SSE2,
  SSSE3,
  #[arg_enum(alias = "sse4.1")]
  SSE4_1,
  AVX2,
}

impl CpuFeatureLevel {
  pub const fn len() -> usize {
    CpuFeatureLevel::AVX2 as usize + 1
  }

  #[inline(always)]
  pub fn as_index(self) -> usize {
    self as usize
  }
}

impl Default for CpuFeatureLevel {
  fn default() -> CpuFeatureLevel {
    let detected: CpuFeatureLevel = if is_x86_feature_detected!("avx2") {
      CpuFeatureLevel::AVX2
    } else if is_x86_feature_detected!("sse4.1") {
      CpuFeatureLevel::SSE4_1
    } else if is_x86_feature_detected!("ssse3") {
      CpuFeatureLevel::SSSE3
    } else if is_x86_feature_detected!("sse2") {
      CpuFeatureLevel::SSE2
    } else {
      CpuFeatureLevel::NATIVE
    };
    let manual: CpuFeatureLevel = match env::var("RAV1E_CPU_TARGET") {
      Ok(feature) => CpuFeatureLevel::from_str(&feature).unwrap_or(detected),
      Err(_e) => detected,
    };
    if manual > detected {
      detected
    } else {
      manual
    }
  }
}

// Create a static lookup table for CPUFeatureLevel enums
// Note: keys are CpuFeatureLevels without any prefix (no CpuFeatureLevel::)
macro_rules! cpu_function_lookup_table {
  ($pub:vis, $name:ident: [$type:ty], default: $empty:expr, [$(($key:ident, $value:expr)),*]) => {
    $pub static $name: [$type; crate::cpu_features::CpuFeatureLevel::len()] = {
      use crate::cpu_features::CpuFeatureLevel;
      #[allow(unused_mut)]
      let mut out: [$type; CpuFeatureLevel::len()] = [$empty; CpuFeatureLevel::len()];

      // Can't use out[0][.] == $empty in static as of rust 1.40
      #[allow(unused_mut)]
      let mut set: [bool; CpuFeatureLevel::len()] = [false; CpuFeatureLevel::len()];

      #[allow(unused_imports)]
      use CpuFeatureLevel::*;
      $(
        out[$key as usize] = $value;
        set[$key as usize] = true;
      )*
      cpu_function_lookup_table!(waterfall_cpu_features(out, set, [SSE2, SSSE3, SSE4_1, AVX2]));
      out
    };
  };

  // Fill empty output functions with the existent functions they support.
  // cpus should be in order of lowest cpu level to highest
  // Used like an internal function
  // Put in here to avoid adding more public macros
  (waterfall_cpu_features($out:ident, $set:ident, [$($cpu:ident),*])) => {
    // Use an array to emulate if statements (not supported in static as of
    // rust 1.40). Setting best[0] (false) and best[1] (true) is equivalent to
    // doing nothing and overriding our value respectively.
    #[allow(unused_assignments)]
    let mut best = [$out[0], $out[0]];
    $(
      // If the current entry has a function, update out best function.
      best[$set[$cpu as usize] as usize] = $out[$cpu as usize];
      // Update our current entry. Does nothing if it already had a function.
      $out[$cpu as usize] = best[1];
    )*
  };

  // version for default visibility
  ($name:ident: [$type:ty], default: $empty:expr, [$(($key:ident, $value:expr)),*]) => {
    cpu_function_lookup_table!(pub(self), $name: [$type], default: $empty, [$(($key, $value)),*]);
  };

  // use $name_$key as our values
  ($pub:vis, $name:ident: [$type:ty], default: $empty:expr, [$($key:ident),*]) => {
    paste::item!{
      cpu_function_lookup_table!(
        $pub, $name: [$type], default: $empty, [$(($key, [<$name _$key>])),*]
      );
    }
  };

  // version for default visibility
  ($name:ident: [$type:ty], default: $empty:expr, [$($key:ident),*]) => {
    cpu_function_lookup_table!(
      pub(self), $name: [$type], default: $empty, [$($key),*]
    );
  };
}
<commit_msg>Add avx512 group of features as detected cpu features<commit_after>// Copyright (c) 2019, The rav1e contributors. All rights reserved
//
// This source code is subject to the terms of the BSD 2 Clause License and
// the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
// was not distributed with this source code in the LICENSE file, you can
// obtain it at www.aomedia.org/license/software. If the Alliance for Open
// Media Patent License 1.0 was not distributed with this source code in the
// PATENTS file, you can obtain it at www.aomedia.org/license/patent.

use arg_enum_proc_macro::ArgEnum;
use std::env;
use std::str::FromStr;

#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, ArgEnum)]
pub enum CpuFeatureLevel {
  #[arg_enum(alias = "rust")]
  NATIVE,
  SSE2,
  SSSE3,
  #[arg_enum(alias = "sse4.1")]
  SSE4_1,
  AVX2,
  AVX512,
  AVX512ICL,
}

impl CpuFeatureLevel {
  pub const fn len() -> usize {
    CpuFeatureLevel::AVX512ICL as usize + 1
  }

  #[inline(always)]
  pub fn as_index(self) -> usize {
    self as usize
  }
}

impl Default for CpuFeatureLevel {
  fn default() -> CpuFeatureLevel {
    fn avx512_detected() -> bool {
      is_x86_feature_detected!("avx512bw")
        && is_x86_feature_detected!("avx512cd")
        && is_x86_feature_detected!("avx512dq")
        && is_x86_feature_detected!("avx512f")
        && is_x86_feature_detected!("avx512vl")
    }
    fn avx512icl_detected() -> bool {
      avx512_detected()
        // && is_x86_feature_detected!("avx512bitalg")
        // && is_x86_feature_detected!("avx512clmulqdq")
        && is_x86_feature_detected!("avx512ifma")
        // && is_x86_feature_detected!("avx512vaes")
        && is_x86_feature_detected!("avx512vbmi")
        // && is_x86_feature_detected!("avx512vbmi2")
        && is_x86_feature_detected!("avx512vpopcntdq")
    }

    let detected: CpuFeatureLevel = if avx512icl_detected() {
      CpuFeatureLevel::AVX512ICL
    } else if avx512_detected() {
      CpuFeatureLevel::AVX512
    } else if is_x86_feature_detected!("avx2") {
      CpuFeatureLevel::AVX2
    } else if is_x86_feature_detected!("sse4.1") {
      CpuFeatureLevel::SSE4_1
    } else if is_x86_feature_detected!("ssse3") {
      CpuFeatureLevel::SSSE3
    } else if is_x86_feature_detected!("sse2") {
      CpuFeatureLevel::SSE2
    } else {
      CpuFeatureLevel::NATIVE
    };
    let manual: CpuFeatureLevel = match env::var("RAV1E_CPU_TARGET") {
      Ok(feature) => CpuFeatureLevel::from_str(&feature).unwrap_or(detected),
      Err(_e) => detected,
    };
    if manual > detected {
      detected
    } else {
      manual
    }
  }
}

// Create a static lookup table for CPUFeatureLevel enums
// Note: keys are CpuFeatureLevels without any prefix (no CpuFeatureLevel::)
macro_rules! cpu_function_lookup_table {
  ($pub:vis, $name:ident: [$type:ty], default: $empty:expr, [$(($key:ident, $value:expr)),*]) => {
    $pub static $name: [$type; crate::cpu_features::CpuFeatureLevel::len()] = {
      use crate::cpu_features::CpuFeatureLevel;
      #[allow(unused_mut)]
      let mut out: [$type; CpuFeatureLevel::len()] = [$empty; CpuFeatureLevel::len()];

      // Can't use out[0][.] == $empty in static as of rust 1.40
      #[allow(unused_mut)]
      let mut set: [bool; CpuFeatureLevel::len()] = [false; CpuFeatureLevel::len()];

      #[allow(unused_imports)]
      use CpuFeatureLevel::*;
      $(
        out[$key as usize] = $value;
        set[$key as usize] = true;
      )*
      cpu_function_lookup_table!(waterfall_cpu_features(out, set, [SSE2, SSSE3, SSE4_1, AVX2, AVX512, AVX512ICL]));
      out
    };
  };

  // Fill empty output functions with the existent functions they support.
  // cpus should be in order of lowest cpu level to highest
  // Used like an internal function
  // Put in here to avoid adding more public macros
  (waterfall_cpu_features($out:ident, $set:ident, [$($cpu:ident),*])) => {
    // Use an array to emulate if statements (not supported in static as of
    // rust 1.40). Setting best[0] (false) and best[1] (true) is equivalent to
    // doing nothing and overriding our value respectively.
    #[allow(unused_assignments)]
    let mut best = [$out[0], $out[0]];
    $(
      // If the current entry has a function, update out best function.
      best[$set[$cpu as usize] as usize] = $out[$cpu as usize];
      // Update our current entry. Does nothing if it already had a function.
      $out[$cpu as usize] = best[1];
    )*
  };

  // version for default visibility
  ($name:ident: [$type:ty], default: $empty:expr, [$(($key:ident, $value:expr)),*]) => {
    cpu_function_lookup_table!(pub(self), $name: [$type], default: $empty, [$(($key, $value)),*]);
  };

  // use $name_$key as our values
  ($pub:vis, $name:ident: [$type:ty], default: $empty:expr, [$($key:ident),*]) => {
    paste::item!{
      cpu_function_lookup_table!(
        $pub, $name: [$type], default: $empty, [$(($key, [<$name _$key>])),*]
      );
    }
  };

  // version for default visibility
  ($name:ident: [$type:ty], default: $empty:expr, [$($key:ident),*]) => {
    cpu_function_lookup_table!(
      pub(self), $name: [$type], default: $empty, [$($key),*]
    );
  };
}
<|endoftext|>


<commit_before>extern crate chrono;
extern crate rusqlite;

use common::bookmark::Bookmark;
use dao::query_parser::*;
use self::rusqlite::Connection;

#[derive(Debug)]
pub struct BookmarkDao {
    connection: rusqlite::Connection,

    read_sql: String,
    delete_sql: String,
    insert_sql: String,
    update_sql: String,
    list_sql: String
}

impl BookmarkDao {
    pub fn new() -> BookmarkDao {

        BookmarkDao {
            connection: Connection::open_in_memory().unwrap(),
            read_sql: load_sql_file("res/sql/bookmark/read.sql"),
            delete_sql: load_sql_file("res/sql/bookmark/delete.sql"),
            insert_sql: load_sql_file("res/sql/bookmark/insert.sql"),
            update_sql: load_sql_file("res/sql/bookmark/update.sql"),
            list_sql: load_sql_file("res/sql/bookmark/list.sql")
        }
    }

    pub fn insert(&self, b: Bookmark ) {
        //self.connection.execute(query, params: &[&ToSql])

    }

    pub fn delete(&self) {

    }

    pub fn read(&self, b: Bookmark) {

    }

    pub fn update(&self, b: Bookmark ){

    }

    pub fn list(&self, b: Bookmark) {
        let parsed_query = parse_query(&b.to_btree(), String::from(&*self.list_sql));

        match self.connection.execute(parsed_query.as_str(), &[] ) {
            Ok(listed) => println!("{} rows were listed", listed),
            Err(err) => println!("listed failed: {}", err),
        }
    }
}

pub fn hello_from_dao() -> String {
    "Hello, I am bookmark dao!".to_string()
}
<commit_msg>BookmarkDAO finalized<commit_after>extern crate chrono;
extern crate rusqlite;

use common::bookmark::Bookmark;
use dao::query_parser::*;
use self::rusqlite::Connection;

#[derive(Debug)]
pub struct BookmarkDao {
    connection: rusqlite::Connection,

    read_sql: String,
    delete_sql: String,
    insert_sql: String,
    update_sql: String,
    list_sql: String
}

impl BookmarkDao {
    pub fn new() -> BookmarkDao {

        BookmarkDao {
            connection: Connection::open_in_memory().unwrap(),
            read_sql: load_sql_file("res/sql/bookmark/read.sql"),
            delete_sql: load_sql_file("res/sql/bookmark/delete.sql"),
            insert_sql: load_sql_file("res/sql/bookmark/insert.sql"),
            update_sql: load_sql_file("res/sql/bookmark/update.sql"),
            list_sql: load_sql_file("res/sql/bookmark/list.sql")
        }
    }

    pub fn insert(&self, b: Bookmark ) {
        let insert_query = parse_query(&b.to_btree(), String::from(&*self.insert_sql));

        match self.connection.execute(insert_query.as_str(), &[] ) {
            Ok(insert) => println!("{} rows were inserted", insert),
            Err(err) => println!("insert failed: {}", err),
        }
    }

    pub fn delete(&self, b: Bookmark) {
        let delete_query = parse_query(&b.to_btree(), String::from(&*self.delete_sql));

        match self.connection.execute(delete_query.as_str(), &[] ) {
            Ok(delete) => println!("{} row was deleted", delete),
            Err(err) => println!("delete failed: {}", err),
        }
    }

    pub fn read(&self, b: Bookmark) {
        let read_query = parse_query(&b.to_btree(), String::from(&*self.read_sql));

        match self.connection.execute(read_query.as_str(), &[] ) {
            Ok(read) => println!("{} rows were readed", read),
            Err(err) => println!("reading failed: {}", err),
        }
    }

    pub fn update(&self, b: Bookmark ){
        let update_query = parse_query(&b.to_btree(), String::from(&*self.update_sql));

        match self.connection.execute(update_query.as_str(), &[] ) {
            Ok(update) => println!("{} rows were listed", update),
            Err(err) => println!("listed failed: {}", err),
        }
    }

    pub fn list(&self, b: Bookmark) {
        let list_query = parse_query(&b.to_btree(), String::from(&*self.list_sql));

        match self.connection.execute(list_query.as_str(), &[] ) {
            Ok(list) => println!("{} rows were listed", list),
            Err(err) => println!("listed failed: {}", err),
        }
    }
}

pub fn hello_from_dao() -> String {
    "Hello, I am bookmark dao!".to_string()
}
<|endoftext|>


<commit_before>/// A simple static assertion macro. The first argument should be a unique
/// ALL_CAPS identifier that describes the condition.
#[macro_export]
#[allow_internal_unstable(type_ascription, underscore_const_names)]
macro_rules! static_assert {
    ($test:expr) => {
        // Use the bool to access an array such that if the bool is false, the access
        // is out-of-bounds.
        #[allow(dead_code)]
        const _: () = [()][!($test: bool) as usize];
    }
}

/// Type size assertion. The first argument is a type and the second argument is its expected size.
#[macro_export]
#[allow_internal_unstable(underscore_const_names)]
macro_rules! static_assert_size {
    ($ty:ty, $size:expr) => {
        const _: [(); $size] = [(); ::std::mem::size_of::<$ty>()];
    }
}
<commit_msg>update doc comment<commit_after>/// A simple static assertion macro.
#[macro_export]
#[allow_internal_unstable(type_ascription, underscore_const_names)]
macro_rules! static_assert {
    ($test:expr) => {
        // Use the bool to access an array such that if the bool is false, the access
        // is out-of-bounds.
        #[allow(dead_code)]
        const _: () = [()][!($test: bool) as usize];
    }
}

/// Type size assertion. The first argument is a type and the second argument is its expected size.
#[macro_export]
#[allow_internal_unstable(underscore_const_names)]
macro_rules! static_assert_size {
    ($ty:ty, $size:expr) => {
        const _: [(); $size] = [(); ::std::mem::size_of::<$ty>()];
    }
}
<|endoftext|>


<commit_before>extern crate tui;

use tui::Terminal;
use tui::backend::MouseBackend;
use tui::widgets::Widget;
use tui::buffer::Buffer;
use tui::layout::Rect;
use tui::style::Style;

struct Label<'a> {
    text: &'a str,
}

impl<'a> Default for Label<'a> {
    fn default() -> Label<'a> {
        Label { text: "" }
    }
}

impl<'a> Widget for Label<'a> {
    fn draw(&self, area: &Rect, buf: &mut Buffer) {
        buf.set_string(area.left(), area.top(), self.text, &Style::default());
    }
}

impl<'a> Label<'a> {
    fn text(&mut self, text: &'a str) -> &mut Label<'a> {
        self.text = text;
        self
    }
}

fn main() {
    let mut terminal = Terminal::new(MouseBackend::new().unwrap()).unwrap();
    let size = terminal.size().unwrap();
    terminal.clear().unwrap();
    Label::default().text("Test").render(&mut terminal, &size);
    terminal.draw().unwrap();
}
<commit_msg>Fix custom_widget example<commit_after>extern crate tui;

use tui::Terminal;
use tui::backend::MouseBackend;
use tui::widgets::Widget;
use tui::buffer::Buffer;
use tui::layout::Rect;
use tui::style::Style;

struct Label<'a> {
    text: &'a str,
}

impl<'a> Default for Label<'a> {
    fn default() -> Label<'a> {
        Label { text: "" }
    }
}

impl<'a> Widget for Label<'a> {
    fn draw(&mut self, area: &Rect, buf: &mut Buffer) {
        buf.set_string(area.left(), area.top(), self.text, &Style::default());
    }
}

impl<'a> Label<'a> {
    fn text(&mut self, text: &'a str) -> &mut Label<'a> {
        self.text = text;
        self
    }
}

fn main() {
    let mut terminal = Terminal::new(MouseBackend::new().unwrap()).unwrap();
    let size = terminal.size().unwrap();
    terminal.clear().unwrap();
    Label::default().text("Test").render(&mut terminal, &size);
    terminal.draw().unwrap();
}
<|endoftext|>


<commit_before>use std::iter::Peekable;

use ::opcodes::{AddressingMode, OpCode};
use assembler::token::{LexerToken, ParserToken};

#[derive(Debug, PartialEq)]
pub struct ParserError {
    pub message: String,
}

impl ParserError {
    fn expected_instruction(line: u32) -> ParserError {
        ParserError::from(format!("Instruction expected. Line {}", line))
    }

    fn invalid_opcode_addressing_mode_combination(line: u32) -> ParserError {
        ParserError::from(format!("Invalid addressing mode for opcode. Line {}", line))
    }

    fn unexpected_eol(line: u32) -> ParserError {
        ParserError::from(format!("Unexpected end of line. Line {}", line))
    }

    fn expected_eol(line: u32) -> ParserError {
        ParserError::from(format!("Expected end of line. Line {}", line))
    }
}

impl From<String> for ParserError {
    fn from(error: String) -> ParserError {
        ParserError { message: error }
    }
}

impl<'a> From<&'a str> for ParserError {
    fn from(error: &str) -> ParserError {
        ParserError { message: error.into() }
    }
}

pub struct Parser {
    line: u32,
}

/// Parser processes a list of 6502 Assembly tokens
impl Parser {
    pub fn new() -> Parser {
        Parser { line: 0 }
    }

    pub fn parse(&mut self, tokens: Vec<Vec<LexerToken>>) -> Result<Vec<ParserToken>, ParserError> {
        let mut result = Vec::new();

        for line in &tokens {
            self.line += 1;

            let mut peeker = line.iter().peekable();

            // Skip blank lines
            if let None = peeker.peek() {
                continue;
            }

            let next = *peeker.peek().unwrap();

            if let &LexerToken::Ident(ref ident) = next {
                // Check if this is an opcode
                if Self::is_opcode(ident.clone()) {
                    // Yep its an opcode, lets figure out its addressing mode
                    peeker.next();
                    let mut opcode = self.consume_opcode(&mut peeker, ident.clone())?;
                    result.append(&mut opcode);

                } else {
                    // Skip the ident and we'll check what is next
                    peeker.next();
                    // if there is nothing else - lets mark this as a Label and move on
                    if let None = peeker.peek() {
                        result.push(ParserToken::Label(ident.clone()));
                        continue;
                    }

                    // A colon after the ident also indicates a label
                    let next = *peeker.peek().unwrap();
                    if let &LexerToken::Colon = next {
                        result.push(ParserToken::Label(ident.clone()));
                        continue;
                    }

                    // Is the next one a label as well? Thats an error:
                    if let &LexerToken::Ident(ref ident) = next {
                        if !Self::is_opcode(ident.clone()) {
                            return Err(ParserError::expected_instruction(self.line));
                        }
                    }

                    let next = *peeker.peek().unwrap();
                }
            }
        }

        Ok(result)
    }

    fn is_opcode<S>(mnemonic: S) -> bool
        where S: Into<String>
    {
        if let Some(opcode) = OpCode::from_mnemonic(mnemonic) {
            true
        } else {
            false
        }
    }

    fn consume_opcode<'a, I, S>(&mut self,
                                mut peeker: &mut Peekable<I>,
                                ident: S)
                                -> Result<Vec<ParserToken>, ParserError>
        where I: Iterator<Item = &'a LexerToken>,
              S: Into<String>
    {
        // If there is nothing else after this opcode.. lets check if there is
        // a matching opcode with an implied addressing mode
        if let None = peeker.peek() {
            if let Some(opcode) =
                   OpCode::from_mnemonic_and_addressing_mode(ident, AddressingMode::Implied) {
                return Ok(vec![ParserToken::OpCode(opcode)]);
            } else {
                return Err(ParserError::invalid_opcode_addressing_mode_combination(self.line));
            }
        } else {
            // TODO: Complete this
            Ok(vec![ParserToken::Label("BLAH".into())])
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use ::assembler::token::{ImmediateBase, LexerToken, ParserToken};
    use ::opcodes::{AddressingMode, OpCode};

    #[test]
    fn can_detect_labels_via_lonely_label() {
        let tokens = vec![vec![LexerToken::Ident("MAIN".into())],
                          vec![LexerToken::Ident("START".into())]];

        let mut parser = Parser::new();
        let result = parser.parse(tokens).unwrap();

        assert_eq!(&[ParserToken::Label("MAIN".into()), ParserToken::Label("START".into())],
                   &result[..]);
    }

    #[test]
    fn can_detect_labels_via_colon_terminator() {
        let tokens = vec![vec![LexerToken::Ident("MAIN".into())], vec![LexerToken::Colon]];

        let mut parser = Parser::new();
        let result = parser.parse(tokens).unwrap();

        assert_eq!(&[ParserToken::Label("MAIN".into())], &result[..]);
    }

    #[test]
    fn can_detect_double_labels_on_one_line() {
        let tokens = vec![vec![LexerToken::Ident("MAIN".into()),
                               LexerToken::Ident("START".into())]];

        let mut parser = Parser::new();
        let result = parser.parse(tokens);

        assert_eq!(Err(ParserError::expected_instruction(1)), result);
    }

    #[test]
    fn can_detect_opcode_with_implied_addressing_mode() {
        let tokens = vec![vec![LexerToken::Ident("CLC".into())]];

        let mut parser = Parser::new();
        let result = parser.parse(tokens).unwrap();

        assert_eq!(&[ParserToken::OpCode(OpCode::from_mnemonic_and_addressing_mode("CLC", AddressingMode::Implied).unwrap())], &result[..]);
    }
}<commit_msg>Add basic addressing mode parsing<commit_after>use std::iter::Peekable;

use ::opcodes::{AddressingMode, OpCode};
use assembler::token::{LexerToken, ParserToken};

#[derive(Debug, PartialEq)]
pub struct ParserError {
    pub message: String,
}

impl ParserError {
    fn expected_instruction(line: u32) -> ParserError {
        ParserError::from(format!("Instruction expected. Line {}", line))
    }

    fn invalid_opcode_addressing_mode_combination(line: u32) -> ParserError {
        ParserError::from(format!("Invalid addressing mode for opcode. Line {}", line))
    }

    fn unexpected_eol(line: u32) -> ParserError {
        ParserError::from(format!("Unexpected end of line. Line {}", line))
    }

    fn expected_eol(line: u32) -> ParserError {
        ParserError::from(format!("Expected end of line. Line {}", line))
    }

    fn cannot_parse_address(line: u32) -> ParserError {
        ParserError::from(format!("Unable to parse address. Line {}", line))
    }

    fn unexpected_token(line: u32) -> ParserError {
        ParserError::from(format!("Unexpected token. Line {}", line))
    }
}

impl From<String> for ParserError {
    fn from(error: String) -> ParserError {
        ParserError { message: error }
    }
}

impl<'a> From<&'a str> for ParserError {
    fn from(error: &str) -> ParserError {
        ParserError { message: error.into() }
    }
}

pub struct Parser {
    line: u32,
}

/// Parser processes a list of 6502 Assembly tokens
impl Parser {
    pub fn new() -> Parser {
        Parser { line: 0 }
    }

    pub fn parse(&mut self, tokens: Vec<Vec<LexerToken>>) -> Result<Vec<ParserToken>, ParserError> {
        let mut result = Vec::new();

        for line in &tokens {
            self.line += 1;

            let mut peeker = line.iter().peekable();

            // Skip blank lines
            if let None = peeker.peek() {
                continue;
            }

            let next = *peeker.peek().unwrap();

            if let &LexerToken::Ident(ref ident) = next {
                // Check if this is an opcode
                if Self::is_opcode(ident.clone()) {
                    // Yep its an opcode, lets figure out its addressing mode
                    peeker.next();
                    let mut opcode = self.consume_opcode(&mut peeker, ident.clone())?;
                    result.append(&mut opcode);
                } else {
                    // Skip the ident and we'll check what is next
                    let original_ident = peeker.next().unwrap();
                    // if there is nothing else - lets mark this as a Label and move on
                    if let None = peeker.peek() {
                        result.push(ParserToken::Label(ident.clone()));
                        continue;
                    }

                    // A colon after the ident also indicates a label
                    let next = *peeker.peek().unwrap();
                    if let &LexerToken::Colon = next {
                        result.push(ParserToken::Label(ident.clone()));
                        continue;
                    }

                    // Is the next one a label as well? Thats an error:
                    if let &LexerToken::Ident(ref ident) = next {
                        // Lets add the original as a label
                        if let &LexerToken::Ident(ref original_ident) = original_ident {
                            result.push(ParserToken::Label(original_ident.clone()));
                        }

                        if !Self::is_opcode(ident.clone()) {
                            return Err(ParserError::expected_instruction(self.line));
                        } else {
                            // Oh it is an opcode after the label - consume it
                            let mut opcode = self.consume_opcode(&mut peeker, ident.clone())?;
                            result.append(&mut opcode);
                        }
                    }
                }
            }
        }

        Ok(result)
    }

    fn is_opcode<S>(mnemonic: S) -> bool
        where S: Into<String>
    {
        if let Some(opcode) = OpCode::from_mnemonic(mnemonic) {
            true
        } else {
            false
        }
    }

    fn consume_opcode<'a, I, S>(&mut self,
                                mut peeker: &mut Peekable<I>,
                                ident: S)
                                -> Result<Vec<ParserToken>, ParserError>
        where I: Iterator<Item = &'a LexerToken>,
              S: Into<String>
    {
        // If there is nothing else after this opcode.. lets check if there is
        // a matching opcode with an implied addressing mode
        if let None = peeker.peek() {
            if let Some(opcode) =
                   OpCode::from_mnemonic_and_addressing_mode(ident, AddressingMode::Implied) {
                return Ok(vec![ParserToken::OpCode(opcode)]);
            } else {
                return Err(ParserError::invalid_opcode_addressing_mode_combination(self.line));
            }
        } else {
            // TODO: Complete this
            // Jump over the opcode
            peeker.next();

            // Check the next token, is it an address?
            let next = *peeker.peek().unwrap();
            if let &LexerToken::Address(ref address) = next {
                // Its an address. What sort of address?
                if address.len() == 2 || address.len() == 4 {
                    // Its zero-page or absolute.. lets try and convert it to a raw byte
                    let (bytes, addressing_mode) = if address.len() == 2 {
                        // Its a 1 byte address
                        if let Ok(raw_byte) = u8::from_str_radix(&address[..], 16) {
                            (vec![raw_byte], AddressingMode::ZeroPage)
                        } else {
                            return Err(ParserError::cannot_parse_address(self.line));
                        }
                    } else {
                        // Its a 2 byte address
                        if let Ok(low_byte) = u8::from_str_radix(&address[2..], 16) {
                            if let Ok(high_byte) = u8::from_str_radix(&address[0..2], 16) {
                                (vec![low_byte, high_byte], AddressingMode::Absolute)
                            } else {
                                return Err(ParserError::cannot_parse_address(self.line));
                            }
                        } else {
                            return Err(ParserError::cannot_parse_address(self.line));
                        }
                    };
                    // consume the address and peek what is next:
                    peeker.next();
                    if let None = peeker.peek() {
                        // Nothing else.. find an opcode with this ident and addressing mode
                        if let Some(opcode) =
                               OpCode::from_mnemonic_and_addressing_mode(ident, addressing_mode) {
                            // We found one..
                            let mut final_vec = vec![ParserToken::OpCode(opcode)];
                            // Push the address bytes into the result
                            for b in bytes {
                                final_vec.push(ParserToken::RawByte(b));
                            }
                            return Ok(final_vec);
                        } else {
                            return Err(ParserError::invalid_opcode_addressing_mode_combination(self.line));
                        }
                    }

                    // There is something after this zero page address - if its
                    // a comma, then we're peachy. If its something else.. Thats
                    // an error.
                    let next = *peeker.peek().unwrap();
                    if let &LexerToken::Comma = next {
                        // Yes, its a comma. Consume it and check what is next
                        peeker.next();
                        // If theres nothing after the comma thats an error
                        if let None = peeker.peek() {
                            return Err(ParserError::unexpected_eol(self.line));
                        }

                        let next = *peeker.peek().unwrap();
                        if let &LexerToken::Ident(ref register) = next {
                            let register = register.to_uppercase();
                            if register != "X" && register != "Y" {
                                return Err(ParserError::unexpected_token(self.line));
                            }
                            let addressing_mode = if register == "X" {
                                if addressing_mode == AddressingMode::ZeroPage {
                                    AddressingMode::ZeroPageX
                                } else {
                                    AddressingMode::AbsoluteX
                                }
                            } else {
                                if addressing_mode == AddressingMode::ZeroPage {
                                    AddressingMode::ZeroPageY
                                } else {
                                    AddressingMode::AbsoluteY
                                }
                            };
                            if let Some(opcode) =
                                   OpCode::from_mnemonic_and_addressing_mode(ident, addressing_mode) {
                                // We found one..
                                let mut final_vec = vec![ParserToken::OpCode(opcode)];
                                // Push the address bytes into the result
                                for b in bytes {
                                    final_vec.push(ParserToken::RawByte(b));
                                }
                            } else {
                                return Err(ParserError::invalid_opcode_addressing_mode_combination(self.line));
                            }
                        } else {
                            return Err(ParserError::unexpected_token(self.line));
                        }
                    } else {
                        return Err(ParserError::unexpected_token(self.line));
                    }
                    let next = *peeker.peek().unwrap();

                } else {
                    return Err(ParserError::cannot_parse_address(self.line));
                }
            }
            Ok(vec![ParserToken::Label("BLAH".into())])
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use ::assembler::token::{ImmediateBase, LexerToken, ParserToken};
    use ::opcodes::{AddressingMode, OpCode};

    #[test]
    fn can_parse_labels_via_lonely_label() {
        let tokens = vec![vec![LexerToken::Ident("MAIN".into())],
                          vec![LexerToken::Ident("START".into())]];

        let mut parser = Parser::new();
        let result = parser.parse(tokens).unwrap();

        assert_eq!(&[ParserToken::Label("MAIN".into()), ParserToken::Label("START".into())],
                   &result[..]);
    }

    #[test]
    fn can_parse_labels_via_colon_terminator() {
        let tokens = vec![vec![LexerToken::Ident("MAIN".into())], vec![LexerToken::Colon]];

        let mut parser = Parser::new();
        let result = parser.parse(tokens).unwrap();

        assert_eq!(&[ParserToken::Label("MAIN".into())], &result[..]);
    }

    #[test]
    fn can_parse_opcodes_after_labels_on_one_line() {
        let tokens = vec![vec![LexerToken::Ident("MAIN".into()),
                               LexerToken::Ident("LDA".into()),
                               LexerToken::Address("4400".into())]];

        let mut parser = Parser::new();
        let result = parser.parse(tokens).unwrap();

        assert_eq!(&[ParserToken::Label("MAIN".into()),
                     ParserToken::OpCode(OpCode::from_mnemonic_and_addressing_mode("LDA", AddressingMode::Absolute).unwrap()),
                     ParserToken::RawByte(0),
                     ParserToken::RawByte(68)],
                   &result[..]);
    }

    #[test]
    fn can_detect_double_labels_on_one_line() {
        let tokens = vec![vec![LexerToken::Ident("MAIN".into()),
                               LexerToken::Ident("START".into())]];

        let mut parser = Parser::new();
        let result = parser.parse(tokens);

        assert_eq!(Err(ParserError::expected_instruction(1)), result);
    }

    #[test]
    fn can_detect_opcode_with_implied_addressing_mode() {
        let tokens = vec![vec![LexerToken::Ident("CLC".into())]];

        let mut parser = Parser::new();
        let result = parser.parse(tokens).unwrap();

        assert_eq!(&[ParserToken::OpCode(OpCode::from_mnemonic_and_addressing_mode("CLC", AddressingMode::Implied).unwrap())], &result[..]);
    }
}<|endoftext|>


<commit_before>use crate::rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
use rustc_hir as hir;
use rustc_hir::def_id::LOCAL_CRATE;
use rustc_infer::infer::{InferOk, TyCtxtInferExt};
use rustc_infer::traits;
use rustc_middle::ty::subst::Subst;
use rustc_middle::ty::{ToPredicate, WithConstness};
use rustc_span::DUMMY_SP;

use super::*;

crate struct BlanketImplFinder<'a, 'tcx> {
    crate cx: &'a mut core::DocContext<'tcx>,
}

impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
    crate fn get_blanket_impls(&mut self, item_def_id: DefId) -> Vec<Item> {
        let param_env = self.cx.tcx.param_env(item_def_id);
        let ty = self.cx.tcx.type_of(item_def_id);

        debug!("get_blanket_impls({:?})", ty);
        let mut impls = Vec::new();
        for &trait_def_id in self.cx.tcx.all_traits(LOCAL_CRATE).iter() {
            if !self.cx.cache.access_levels.is_public(trait_def_id)
                || self.cx.generated_synthetics.get(&(ty, trait_def_id)).is_some()
            {
                continue;
            }
            self.cx.tcx.for_each_relevant_impl(trait_def_id, ty, |impl_def_id| {
                debug!(
                    "get_blanket_impls: Considering impl for trait '{:?}' {:?}",
                    trait_def_id, impl_def_id
                );
                let trait_ref = self.cx.tcx.impl_trait_ref(impl_def_id).unwrap();
                let may_apply = self.cx.tcx.infer_ctxt().enter(|infcx| {
                    match trait_ref.self_ty().kind() {
                        ty::Param(_) => {}
                        _ => return false,
                    }

                    let substs = infcx.fresh_substs_for_item(DUMMY_SP, item_def_id);
                    let ty = ty.subst(infcx.tcx, substs);
                    let param_env = param_env.subst(infcx.tcx, substs);

                    let impl_substs = infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id);
                    let trait_ref = trait_ref.subst(infcx.tcx, impl_substs);

                    // Require the type the impl is implemented on to match
                    // our type, and ignore the impl if there was a mismatch.
                    let cause = traits::ObligationCause::dummy();
                    let eq_result = infcx.at(&cause, param_env).eq(trait_ref.self_ty(), ty);
                    if let Ok(InferOk { value: (), obligations }) = eq_result {
                        // FIXME(eddyb) ignoring `obligations` might cause false positives.
                        drop(obligations);

                        debug!(
                            "invoking predicate_may_hold: param_env={:?}, trait_ref={:?}, ty={:?}",
                            param_env, trait_ref, ty
                        );
                        let predicates = self
                            .cx
                            .tcx
                            .predicates_of(impl_def_id)
                            .instantiate(self.cx.tcx, impl_substs)
                            .predicates
                            .into_iter()
                            .chain(Some(trait_ref.without_const().to_predicate(infcx.tcx)));
                        for predicate in predicates {
                            debug!("testing predicate {:?}", predicate);
                            let obligation = traits::Obligation::new(
                                traits::ObligationCause::dummy(),
                                param_env,
                                predicate,
                            );
                            match infcx.evaluate_obligation(&obligation) {
                                Ok(eval_result) if eval_result.may_apply() => {}
                                Err(traits::OverflowError) => {}
                                _ => {
                                    return false;
                                }
                            }
                        }
                        true
                    } else {
                        false
                    }
                });
                debug!(
                    "get_blanket_impls: found applicable impl: {} for trait_ref={:?}, ty={:?}",
                    may_apply, trait_ref, ty
                );
                if !may_apply {
                    return;
                }

                self.cx.generated_synthetics.insert((ty, trait_def_id));
                let provided_trait_methods = self
                    .cx
                    .tcx
                    .provided_trait_methods(trait_def_id)
                    .map(|meth| meth.ident.name)
                    .collect();

                impls.push(Item {
                    source: self.cx.tcx.def_span(impl_def_id).clean(self.cx),
                    name: None,
                    attrs: Default::default(),
                    visibility: Inherited,
                    def_id: self.cx.next_def_id(impl_def_id.krate),
                    kind: box ImplItem(Impl {
                        unsafety: hir::Unsafety::Normal,
                        generics: (
                            self.cx.tcx.generics_of(impl_def_id),
                            self.cx.tcx.explicit_predicates_of(impl_def_id),
                        )
                            .clean(self.cx),
                        provided_trait_methods,
                        // FIXME(eddyb) compute both `trait_` and `for_` from
                        // the post-inference `trait_ref`, as it's more accurate.
                        trait_: Some(trait_ref.clean(self.cx).get_trait_type().unwrap()),
                        for_: ty.clean(self.cx),
                        items: self
                            .cx
                            .tcx
                            .associated_items(impl_def_id)
                            .in_definition_order()
                            .collect::<Vec<_>>()
                            .clean(self.cx),
                        negative_polarity: false,
                        synthetic: false,
                        blanket_impl: Some(trait_ref.self_ty().clean(self.cx)),
                    }),
                });
            });
        }
        impls
    }
}
<commit_msg>rustdoc: Don't enter an infer_ctxt in get_blanket_impls for impls that aren't blanket impls<commit_after>use crate::rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
use rustc_hir as hir;
use rustc_hir::def_id::LOCAL_CRATE;
use rustc_infer::infer::{InferOk, TyCtxtInferExt};
use rustc_infer::traits;
use rustc_middle::ty::subst::Subst;
use rustc_middle::ty::{ToPredicate, WithConstness};
use rustc_span::DUMMY_SP;

use super::*;

crate struct BlanketImplFinder<'a, 'tcx> {
    crate cx: &'a mut core::DocContext<'tcx>,
}

impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
    crate fn get_blanket_impls(&mut self, item_def_id: DefId) -> Vec<Item> {
        let param_env = self.cx.tcx.param_env(item_def_id);
        let ty = self.cx.tcx.type_of(item_def_id);

        debug!("get_blanket_impls({:?})", ty);
        let mut impls = Vec::new();
        for &trait_def_id in self.cx.tcx.all_traits(LOCAL_CRATE).iter() {
            if !self.cx.cache.access_levels.is_public(trait_def_id)
                || self.cx.generated_synthetics.get(&(ty, trait_def_id)).is_some()
            {
                continue;
            }
            self.cx.tcx.for_each_relevant_impl(trait_def_id, ty, |impl_def_id| {
                debug!(
                    "get_blanket_impls: Considering impl for trait '{:?}' {:?}",
                    trait_def_id, impl_def_id
                );
                let trait_ref = self.cx.tcx.impl_trait_ref(impl_def_id).unwrap();
                let is_param = matches!(trait_ref.self_ty().kind(), ty::Param(_));
                let may_apply = is_param && self.cx.tcx.infer_ctxt().enter(|infcx| {
                    let substs = infcx.fresh_substs_for_item(DUMMY_SP, item_def_id);
                    let ty = ty.subst(infcx.tcx, substs);
                    let param_env = param_env.subst(infcx.tcx, substs);

                    let impl_substs = infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id);
                    let trait_ref = trait_ref.subst(infcx.tcx, impl_substs);

                    // Require the type the impl is implemented on to match
                    // our type, and ignore the impl if there was a mismatch.
                    let cause = traits::ObligationCause::dummy();
                    let eq_result = infcx.at(&cause, param_env).eq(trait_ref.self_ty(), ty);
                    if let Ok(InferOk { value: (), obligations }) = eq_result {
                        // FIXME(eddyb) ignoring `obligations` might cause false positives.
                        drop(obligations);

                        debug!(
                            "invoking predicate_may_hold: param_env={:?}, trait_ref={:?}, ty={:?}",
                            param_env, trait_ref, ty
                        );
                        let predicates = self
                            .cx
                            .tcx
                            .predicates_of(impl_def_id)
                            .instantiate(self.cx.tcx, impl_substs)
                            .predicates
                            .into_iter()
                            .chain(Some(trait_ref.without_const().to_predicate(infcx.tcx)));
                        for predicate in predicates {
                            debug!("testing predicate {:?}", predicate);
                            let obligation = traits::Obligation::new(
                                traits::ObligationCause::dummy(),
                                param_env,
                                predicate,
                            );
                            match infcx.evaluate_obligation(&obligation) {
                                Ok(eval_result) if eval_result.may_apply() => {}
                                Err(traits::OverflowError) => {}
                                _ => {
                                    return false;
                                }
                            }
                        }
                        true
                    } else {
                        false
                    }
                });
                debug!(
                    "get_blanket_impls: found applicable impl: {} for trait_ref={:?}, ty={:?}",
                    may_apply, trait_ref, ty
                );
                if !may_apply {
                    return;
                }

                self.cx.generated_synthetics.insert((ty, trait_def_id));
                let provided_trait_methods = self
                    .cx
                    .tcx
                    .provided_trait_methods(trait_def_id)
                    .map(|meth| meth.ident.name)
                    .collect();

                impls.push(Item {
                    source: self.cx.tcx.def_span(impl_def_id).clean(self.cx),
                    name: None,
                    attrs: Default::default(),
                    visibility: Inherited,
                    def_id: self.cx.next_def_id(impl_def_id.krate),
                    kind: box ImplItem(Impl {
                        unsafety: hir::Unsafety::Normal,
                        generics: (
                            self.cx.tcx.generics_of(impl_def_id),
                            self.cx.tcx.explicit_predicates_of(impl_def_id),
                        )
                            .clean(self.cx),
                        provided_trait_methods,
                        // FIXME(eddyb) compute both `trait_` and `for_` from
                        // the post-inference `trait_ref`, as it's more accurate.
                        trait_: Some(trait_ref.clean(self.cx).get_trait_type().unwrap()),
                        for_: ty.clean(self.cx),
                        items: self
                            .cx
                            .tcx
                            .associated_items(impl_def_id)
                            .in_definition_order()
                            .collect::<Vec<_>>()
                            .clean(self.cx),
                        negative_polarity: false,
                        synthetic: false,
                        blanket_impl: Some(trait_ref.self_ty().clean(self.cx)),
                    }),
                });
            });
        }
        impls
    }
}
<|endoftext|>


<commit_before>enum SimpleList<T> {
    Cons(T, Box<SimpleList<T>>),
    Nil,
}

fn length<T>(xs: &SimpleList<T>) -> int {
    match xs {
        &Cons(_, ref ys) => 1 + length(*ys),
        &Nil => 0,
    }
}

fn main() {
    let mut xs = box Nil;
    xs = box Cons(3, xs);
    xs = box Cons(2, xs);
    xs = box Cons(1, xs);
    let ys = xs;
    println!("{}", length(ys)); // OK
    // xs is moved. It will be compiler error.
    // println!("{}", length(xs)); // NG!
}
<commit_msg>Add copyright notation<commit_after>// Copyright (c) 2014 liquid_amber
// This file is distributed under MIT license.
// See LICENSE file.

enum SimpleList<T> {
    Cons(T, Box<SimpleList<T>>),
    Nil,
}

fn length<T>(xs: &SimpleList<T>) -> int {
    match xs {
        &Cons(_, ref ys) => 1 + length(*ys),
        &Nil => 0,
    }
}

fn main() {
    let mut xs = box Nil;
    xs = box Cons(3, xs);
    xs = box Cons(2, xs);
    xs = box Cons(1, xs);
    let ys = xs;
    println!("{}", length(ys)); // OK
    // xs is moved. It will be compiler error.
    // println!("{}", length(xs)); // NG!
}
<|endoftext|>


<commit_before>use plat::*;
use vspace::*;
use panic::*;
use ::config::BootConfig;
use ::core::fmt::Write;
use ::core::marker::PhantomData;
use ::core::default::Default;
use super::halt::halt;
use super::vspace::*;
extern crate multiboot;

struct EarlyBootState<'h, 'l> {
    high_window : &'h BootHighWindow<'h>,
    low_window : &'l BootLowWindow<'l>,
    mbi_magic: usize,
    mbi: *const usize,
}

struct PostEarlyBootState<'a> {
    plat: PlatInterfaceType,
    /* currently just PhantomData as don't have anything
     * to return with a lifetime */
    phantom: PhantomData<&'a usize>,
}

/* Try and boot the system, potentially returning an error.
 * Since if we fail there is no way to display or do anything
 * with the error we do do not bother to have an error type
 * This is specifically the 'early' boot as it happens before
 * we switch to the final kernel address space
 */
fn try_early_boot_system<'h, 'l>(init: EarlyBootState<'h, 'l>) -> Result<PostEarlyBootState<'h>, PlatInterfaceType> {
    /* Initial the serial output of our platform first so that
     * we can get debugging output. */
    let mut plat = get_platform(&BootConfig);
    plat.init_serial();
    if let Err(_) = write!(plat, "R4: In early setup") { return Err(plat); }
    /* Initialize the panic function so we can see anything
     * really bad that happens */
    panic_set_plat(&mut plat);
    /* Now we can continue with the rest of init */
    Ok(PostEarlyBootState{ plat: plat, phantom: PhantomData })
}

/* Represent the multiboot info pointer as a pointer to
 * a usize for the moment. This will allow us to get the
 * lifetimes correct, and we will fill in the correct
 * type later */
#[no_mangle]
pub extern fn boot_system(magic: usize, mbi: *const usize) {
    /* This *will* be our final kernel window, but it is not our window
     * yet. We create it here so that our temporary high kernel window,
     * which is a subset of the final kernel window, can be constructed
     * from it as having the same lifetime. This allows any references
     * created from the boot high kernel window being able to live on
     * into the final kernel window */
    let final_window = KernelWindow::default();
    /* this variable will hold our system state as returned by early boot */
    let mut boot;
    {
        /* Construct our system state for boot */
        let boot_high_window;
        unsafe {
            boot_high_window = final_window.subwindow(BootHighWindow::default());
        }
        /* whilst doing early boot we can also access things in low memory */
        let boot_low_window = BootLowWindow::default();
        let boot_state = EarlyBootState {
            high_window: &boot_high_window,
            low_window: &boot_low_window,
            mbi_magic: magic,
            mbi: mbi,
        };
        boot = match try_early_boot_system(boot_state) {
            Err(mut plat) => {
                    write!(plat, "Failed early init. hlt'ing").unwrap();
                    halt();
                },
            Ok(b) => b,
        };
        /* The 'plat' definition got moved into boot. Reset the panic location */
        panic_set_plat(&mut boot.plat);
    }
    unimplemented!()
}
<commit_msg>Missing newlines on print functions<commit_after>use plat::*;
use vspace::*;
use panic::*;
use ::config::BootConfig;
use ::core::fmt::Write;
use ::core::marker::PhantomData;
use ::core::default::Default;
use super::halt::halt;
use super::vspace::*;
extern crate multiboot;

struct EarlyBootState<'h, 'l> {
    high_window : &'h BootHighWindow<'h>,
    low_window : &'l BootLowWindow<'l>,
    mbi_magic: usize,
    mbi: *const usize,
}

struct PostEarlyBootState<'a> {
    plat: PlatInterfaceType,
    /* currently just PhantomData as don't have anything
     * to return with a lifetime */
    phantom: PhantomData<&'a usize>,
}

/* Try and boot the system, potentially returning an error.
 * Since if we fail there is no way to display or do anything
 * with the error we do do not bother to have an error type
 * This is specifically the 'early' boot as it happens before
 * we switch to the final kernel address space
 */
fn try_early_boot_system<'h, 'l>(init: EarlyBootState<'h, 'l>) -> Result<PostEarlyBootState<'h>, PlatInterfaceType> {
    /* Initial the serial output of our platform first so that
     * we can get debugging output. */
    let mut plat = get_platform(&BootConfig);
    plat.init_serial();
    if let Err(_) = write!(plat, "R4: In early setup\n") { return Err(plat); }
    /* Initialize the panic function so we can see anything
     * really bad that happens */
    panic_set_plat(&mut plat);
    /* Now we can continue with the rest of init */
    Ok(PostEarlyBootState{ plat: plat, phantom: PhantomData })
}

/* Represent the multiboot info pointer as a pointer to
 * a usize for the moment. This will allow us to get the
 * lifetimes correct, and we will fill in the correct
 * type later */
#[no_mangle]
pub extern fn boot_system(magic: usize, mbi: *const usize) {
    /* This *will* be our final kernel window, but it is not our window
     * yet. We create it here so that our temporary high kernel window,
     * which is a subset of the final kernel window, can be constructed
     * from it as having the same lifetime. This allows any references
     * created from the boot high kernel window being able to live on
     * into the final kernel window */
    let final_window = KernelWindow::default();
    /* this variable will hold our system state as returned by early boot */
    let mut boot;
    {
        /* Construct our system state for boot */
        let boot_high_window;
        unsafe {
            boot_high_window = final_window.subwindow(BootHighWindow::default());
        }
        /* whilst doing early boot we can also access things in low memory */
        let boot_low_window = BootLowWindow::default();
        let boot_state = EarlyBootState {
            high_window: &boot_high_window,
            low_window: &boot_low_window,
            mbi_magic: magic,
            mbi: mbi,
        };
        boot = match try_early_boot_system(boot_state) {
            Err(mut plat) => {
                    write!(plat, "Failed early init. hlt'ing\n").unwrap();
                    halt();
                },
            Ok(b) => b,
        };
        /* The 'plat' definition got moved into boot. Reset the panic location */
        panic_set_plat(&mut boot.plat);
    }
    unimplemented!()
}
<|endoftext|>