<commit_before>use crate::bindings as br;
use crate::{compiler, spirv, ErrorCode};
use crate::ptr_util::read_into_vec_from_ptr;
use std::marker::PhantomData;
use std::ptr;
use std::ffi::c_void;

/// A GLSL target.
#[derive(Debug, Clone)]
pub enum Target {}

pub struct TargetData {
    combined_image_samplers_built: bool,
}

impl spirv::Target for Target {
    type Data = TargetData;
}

#[allow(non_snake_case, non_camel_case_types)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
pub enum Version {
    V1_10,
    V1_20,
    V1_30,
    V1_40,
    V1_50,
    V3_30,
    V4_00,
    V4_10,
    V4_20,
    V4_30,
    V4_40,
    V4_50,
    V4_60,
    V1_00Es,
    V3_00Es,
}

#[derive(Debug, Clone)]
pub struct CompilerVertexOptions {
    pub invert_y: bool,
    pub transform_clip_space: bool,
}

impl Default for CompilerVertexOptions {
    fn default() -> CompilerVertexOptions {
        CompilerVertexOptions {
            invert_y: false,
            transform_clip_space: false,
        }
    }
}

/// GLSL compiler options.
#[derive(Debug, Clone)]
pub struct CompilerOptions {
    pub version: Version,
    pub vertex: CompilerVertexOptions,
}

impl CompilerOptions {
    fn as_raw(&self) -> br::ScGlslCompilerOptions {
        use self::Version::*;
        let (version, es) = match self.version {
            V1_10 => (1_10, false),
            V1_20 => (1_20, false),
            V1_30 => (1_30, false),
            V1_40 => (1_40, false),
            V1_50 => (1_50, false),
            V3_30 => (3_30, false),
            V4_00 => (4_00, false),
            V4_10 => (4_10, false),
            V4_20 => (4_20, false),
            V4_30 => (4_30, false),
            V4_40 => (4_40, false),
            V4_50 => (4_50, false),
            V4_60 => (4_60, false),
            V1_00Es => (1_00, true),
            V3_00Es => (3_00, true),
        };
        br::ScGlslCompilerOptions {
            vertex_invert_y: self.vertex.invert_y,
            vertex_transform_clip_space: self.vertex.transform_clip_space,
            version,
            es,
        }
    }
}

impl Default for CompilerOptions {
    fn default() -> CompilerOptions {
        CompilerOptions {
            version: Version::V4_50,
            vertex: CompilerVertexOptions::default(),
        }
    }
}

impl spirv::Parse<Target> for spirv::Ast<Target> {
    fn parse(module: &spirv::Module) -> Result<Self, ErrorCode> {
        let compiler = {
            let mut compiler = ptr::null_mut();
            unsafe {
                check!(br::sc_internal_compiler_glsl_new(
                    &mut compiler,
                    module.words.as_ptr() as *const u32,
                    module.words.len() as usize,
                ));
            }

            compiler::Compiler {
                sc_compiler: compiler,
                target_data: TargetData {
                    combined_image_samplers_built: false,
                },
                has_been_compiled: false,
            }
        };

        Ok(spirv::Ast {
            compiler,
            target_type: PhantomData,
        })
    }
}

impl spirv::Compile<Target> for spirv::Ast<Target> {
    type CompilerOptions = CompilerOptions;

    /// Set GLSL compiler specific compilation settings.
    fn set_compiler_options(&mut self, options: &CompilerOptions) -> Result<(), ErrorCode> {
        let raw_options = options.as_raw();
        unsafe {
            check!(br::sc_internal_compiler_glsl_set_options(
                self.compiler.sc_compiler,
                &raw_options,
            ));
        }

        Ok(())
    }

    /// Generate GLSL shader from the AST.
    fn compile(&mut self) -> Result<String, ErrorCode> {
        self.build_combined_image_samplers()?;
        self.compiler.compile()
    }
}

impl spirv::Ast<Target> {
    pub fn build_combined_image_samplers(&mut self) -> Result<(), ErrorCode> {
        unsafe {
            if !self.compiler.target_data.combined_image_samplers_built {
                check!(br::sc_internal_compiler_glsl_build_combined_image_samplers(
                    self.compiler.sc_compiler
                ));
                self.compiler.target_data.combined_image_samplers_built = true
            }
        }

        Ok(())
    }

    pub fn get_combined_image_samplers(
        &mut self,
    ) -> Result<Vec<spirv::CombinedImageSampler>, ErrorCode> {
        self.build_combined_image_samplers()?;
        unsafe {
            let mut samplers_raw: *const br::ScCombinedImageSampler = std::ptr::null();
            let mut samplers_raw_length: usize = 0;

            check!(br::sc_internal_compiler_glsl_get_combined_image_samplers(
                self.compiler.sc_compiler,
                &mut samplers_raw as _,
                &mut samplers_raw_length as _,
            ));

            let samplers = read_into_vec_from_ptr(samplers_raw, samplers_raw_length)
                .iter()
                .map(|sc| spirv::CombinedImageSampler {
                    combined_id: sc.combined_id,
                    image_id: sc.image_id,
                    sampler_id: sc.sampler_id,
                })
                .collect();

            if samplers_raw_length > 0 {
                check!(br::sc_internal_free_pointer(samplers_raw as *mut c_void));
            }

            Ok(samplers)
        }
    }
}
<commit_msg>Do not attempt to free combined image samplers<commit_after>use crate::bindings as br;
use crate::{compiler, spirv, ErrorCode};
use crate::ptr_util::read_into_vec_from_ptr;
use std::marker::PhantomData;
use std::ptr;
use std::ffi::c_void;

/// A GLSL target.
#[derive(Debug, Clone)]
pub enum Target {}

pub struct TargetData {
    combined_image_samplers_built: bool,
}

impl spirv::Target for Target {
    type Data = TargetData;
}

#[allow(non_snake_case, non_camel_case_types)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
pub enum Version {
    V1_10,
    V1_20,
    V1_30,
    V1_40,
    V1_50,
    V3_30,
    V4_00,
    V4_10,
    V4_20,
    V4_30,
    V4_40,
    V4_50,
    V4_60,
    V1_00Es,
    V3_00Es,
}

#[derive(Debug, Clone)]
pub struct CompilerVertexOptions {
    pub invert_y: bool,
    pub transform_clip_space: bool,
}

impl Default for CompilerVertexOptions {
    fn default() -> CompilerVertexOptions {
        CompilerVertexOptions {
            invert_y: false,
            transform_clip_space: false,
        }
    }
}

/// GLSL compiler options.
#[derive(Debug, Clone)]
pub struct CompilerOptions {
    pub version: Version,
    pub vertex: CompilerVertexOptions,
}

impl CompilerOptions {
    fn as_raw(&self) -> br::ScGlslCompilerOptions {
        use self::Version::*;
        let (version, es) = match self.version {
            V1_10 => (1_10, false),
            V1_20 => (1_20, false),
            V1_30 => (1_30, false),
            V1_40 => (1_40, false),
            V1_50 => (1_50, false),
            V3_30 => (3_30, false),
            V4_00 => (4_00, false),
            V4_10 => (4_10, false),
            V4_20 => (4_20, false),
            V4_30 => (4_30, false),
            V4_40 => (4_40, false),
            V4_50 => (4_50, false),
            V4_60 => (4_60, false),
            V1_00Es => (1_00, true),
            V3_00Es => (3_00, true),
        };
        br::ScGlslCompilerOptions {
            vertex_invert_y: self.vertex.invert_y,
            vertex_transform_clip_space: self.vertex.transform_clip_space,
            version,
            es,
        }
    }
}

impl Default for CompilerOptions {
    fn default() -> CompilerOptions {
        CompilerOptions {
            version: Version::V4_50,
            vertex: CompilerVertexOptions::default(),
        }
    }
}

impl spirv::Parse<Target> for spirv::Ast<Target> {
    fn parse(module: &spirv::Module) -> Result<Self, ErrorCode> {
        let compiler = {
            let mut compiler = ptr::null_mut();
            unsafe {
                check!(br::sc_internal_compiler_glsl_new(
                    &mut compiler,
                    module.words.as_ptr() as *const u32,
                    module.words.len() as usize,
                ));
            }

            compiler::Compiler {
                sc_compiler: compiler,
                target_data: TargetData {
                    combined_image_samplers_built: false,
                },
                has_been_compiled: false,
            }
        };

        Ok(spirv::Ast {
            compiler,
            target_type: PhantomData,
        })
    }
}

impl spirv::Compile<Target> for spirv::Ast<Target> {
    type CompilerOptions = CompilerOptions;

    /// Set GLSL compiler specific compilation settings.
    fn set_compiler_options(&mut self, options: &CompilerOptions) -> Result<(), ErrorCode> {
        let raw_options = options.as_raw();
        unsafe {
            check!(br::sc_internal_compiler_glsl_set_options(
                self.compiler.sc_compiler,
                &raw_options,
            ));
        }

        Ok(())
    }

    /// Generate GLSL shader from the AST.
    fn compile(&mut self) -> Result<String, ErrorCode> {
        self.build_combined_image_samplers()?;
        self.compiler.compile()
    }
}

impl spirv::Ast<Target> {
    pub fn build_combined_image_samplers(&mut self) -> Result<(), ErrorCode> {
        unsafe {
            if !self.compiler.target_data.combined_image_samplers_built {
                check!(br::sc_internal_compiler_glsl_build_combined_image_samplers(
                    self.compiler.sc_compiler
                ));
                self.compiler.target_data.combined_image_samplers_built = true
            }
        }

        Ok(())
    }

    pub fn get_combined_image_samplers(
        &mut self,
    ) -> Result<Vec<spirv::CombinedImageSampler>, ErrorCode> {
        self.build_combined_image_samplers()?;
        unsafe {
            let mut samplers_raw: *const br::ScCombinedImageSampler = std::ptr::null();
            let mut samplers_raw_length: usize = 0;

            check!(br::sc_internal_compiler_glsl_get_combined_image_samplers(
                self.compiler.sc_compiler,
                &mut samplers_raw as _,
                &mut samplers_raw_length as _,
            ));

            let samplers = read_into_vec_from_ptr(samplers_raw, samplers_raw_length)
                .iter()
                .map(|sc| spirv::CombinedImageSampler {
                    combined_id: sc.combined_id,
                    image_id: sc.image_id,
                    sampler_id: sc.sampler_id,
                })
                .collect();

            Ok(samplers)
        }
    }
}
<|endoftext|>


<commit_before>mod stack;
mod pc;
mod memory;
mod params;
mod account;
mod storage;
mod cost;
mod run;
mod transaction;

pub use self::memory::{Memory, SeqMemory};
pub use self::stack::Stack;
pub use self::pc::PC;
pub use self::params::{BlockHeader, Context, Patch, Log};
pub use self::account::{Account, AccountCommitment};
pub use self::storage::{Storage, HashMapStorage};
pub use self::transaction::{Transaction, MessageCall, ContractCreation,
                            MessageCallMachine, ContractCreationMachine};

use self::account::AccountState;
use self::cost::{gas_cost, gas_refund, gas_stipend, CostAggregrator};
use self::run::run_opcode;
use std::collections::hash_map;
use utils::gas::Gas;
use utils::address::Address;
use utils::bigint::{M256, U256};

#[derive(Debug, Clone)]
pub enum ExecutionError {
    EmptyGas,
    EmptyBalance,
    StackUnderflow,
    StackOverflow,
    InvalidOpcode,
    PCOverflow,
    PCBadJumpDest,
    PCTooLarge, // The current implementation only support code size with usize::maximum.
    MemoryTooLarge,
    DataTooLarge,
    CodeTooLarge,
    RequireAccount(Address),
    RequireAccountCode(Address),
    RequireBlockhash(M256),
    Stopped
}

impl ExecutionError {
    pub fn is_require(&self) -> bool {
        match self {
            &ExecutionError::RequireAccount(_) |
            &ExecutionError::RequireAccountCode(_) |
            &ExecutionError::RequireBlockhash(_) => true,
            _ => false,
        }
    }
}

#[derive(Debug)]
pub enum CommitError {
    AlreadyCommitted,
    StateChanged,
    Invalid,
}

pub type ExecutionResult<T> = ::std::result::Result<T, ExecutionError>;
pub type CommitResult<T> = ::std::result::Result<T, CommitError>;

pub type SeqMachine = Machine<SeqMemory, HashMapStorage>;

pub trait VM<S: Storage> {
    fn step(&mut self) -> ExecutionResult<()>;
    fn peek_cost(&self) -> ExecutionResult<Gas>;
    fn fire(&mut self) -> ExecutionResult<()> {
        loop {
            let result = self.step();

            if result.is_err() {
                match result.err().unwrap() {
                    ExecutionError::Stopped => return Ok(()),
                    err => return Err(err),
                }
            }
        }
    }

    fn commit_account(&mut self, commitment: AccountCommitment<S>) -> CommitResult<()>;
    fn commit_blockhash(&mut self, number: M256, hash: M256) -> CommitResult<()>;
    fn accounts(&self) -> hash_map::Values<Address, Account<S>>;
    fn transactions(&self) -> &[Transaction];
    fn appending_logs(&self) -> &[Log];
    fn available_gas(&self) -> Gas;

    fn patch(&self) -> Patch;
}

pub struct Machine<M, S> {
    pc: PC,
    memory: M,
    stack: Stack,
    cost_aggregrator: CostAggregrator,
    return_values: Vec<u8>,

    context: Context,
    block: BlockHeader,

    account_state: AccountState<S>,
    blockhashes: hash_map::HashMap<M256, M256>,
    appending_logs: Vec<Log>,
    transactions: Vec<Transaction>,

    used_gas: Gas,
    refunded_gas: Gas,

    patch: Patch,
}

impl<M: Memory + Default, S: Storage + Default> Machine<M, S> {
    pub fn new(context: Context, block: BlockHeader) -> Self {
        Self {
            pc: PC::new(context.code.as_slice()),
            memory: M::default(),
            stack: Stack::default(),
            cost_aggregrator: CostAggregrator::default(),
            return_values: Vec::new(),

            context: context,
            block: block,

            account_state: AccountState::default(),
            blockhashes: hash_map::HashMap::new(),
            appending_logs: Vec::new(),
            transactions: Vec::new(),

            used_gas: Gas::zero(),
            refunded_gas: Gas::zero(),

            patch: Patch::None,
        }
    }
}

impl<M: Memory + Default, S: Storage + Default> VM<S> for Machine<M, S> {
    fn peek_cost(&self) -> ExecutionResult<Gas> {
        let opcode = self.pc.peek_opcode()?;
        let aggregrator = self.cost_aggregrator;
        let (gas, agg) = gas_cost(opcode, &self, aggregrator)?;
        Ok(gas)
    }

    fn step(&mut self) -> ExecutionResult<()> {
        begin_rescuable!(self, &mut Self, __);
        if self.pc.stopped() {
            trr!(Err(ExecutionError::Stopped), __);
        }

        let position = self.pc.position();
        on_rescue!(|machine| {
            machine.pc.jump_unchecked(position);
        }, __);

        let opcode = trr!(self.pc.read_opcode(), __);
        let available_gas = self.available_gas();
        let cost_aggregrator = self.cost_aggregrator;
        let (gas, agg) = trr!(gas_cost(opcode, self, cost_aggregrator), __);
        let refunded = trr!(gas_refund(opcode, self), __);
        let stipend = trr!(gas_stipend(opcode, self), __);

        if gas > self.available_gas() {
            trr!(Err(ExecutionError::EmptyGas), __);
        }

        trr!(run_opcode(opcode, self, stipend, available_gas - gas + stipend), __);

        self.cost_aggregrator = agg;
        self.used_gas = self.used_gas + gas - stipend;
        self.refunded_gas = self.refunded_gas + refunded;

        end_rescuable!(__);
        Ok(())
    }

    fn commit_account(&mut self, commitment: AccountCommitment<S>) -> CommitResult<()> {
        self.account_state.commit(commitment)
    }

    fn commit_blockhash(&mut self, number: M256, hash: M256) -> CommitResult<()> {
        if self.blockhashes.contains_key(&number) {
            return Err(CommitError::AlreadyCommitted);
        }

        self.blockhashes.insert(number, hash);
        Ok(())
    }

    fn accounts(&self) -> hash_map::Values<Address, Account<S>> {
        self.account_state.accounts()
    }

    fn transactions(&self) -> &[Transaction] {
        self.transactions.as_slice()
    }

    fn appending_logs(&self) -> &[Log] {
        self.appending_logs.as_slice()
    }

    fn available_gas(&self) -> Gas {
        self.context.gas_limit - self.used_gas
    }

    fn patch(&self) -> Patch {
        self.patch
    }
}

impl<M: Memory + Default, S: Storage + Default> Machine<M, S> {
    pub fn pc(&self) -> &PC {
        &self.pc
    }

    pub fn memory(&self) -> &M {
        &self.memory
    }

    pub fn stack(&self) -> &Stack {
        &self.stack
    }

    pub fn context(&self) -> &Context {
        &self.context
    }

    pub fn block(&self) -> &BlockHeader {
        &self.block
    }

    pub fn accounts(&self) -> hash_map::Values<Address, Account<S>> {
        self.account_state.accounts()
    }

    pub fn return_values(&self) -> &[u8] {
        self.return_values.as_slice()
    }

    pub fn active_memory_len(&self) -> M256 {
        self.cost_aggregrator.active_memory_len()
    }

    fn blockhash(&mut self, number: M256) -> ExecutionResult<M256> {
        match self.blockhashes.get(&number) {
            Some(val) => Ok(*val),
            None => Err(ExecutionError::RequireBlockhash(number)),
        }
    }

    fn append_log(&mut self, log: Log) {
        self.appending_logs.push(log);
    }

    fn fire_sub<V: VM<S>>(&self, submachine: &mut V) -> ExecutionResult<()> {
        loop {
            let result = submachine.fire();
            match result {
                Err(ExecutionError::RequireAccount(address)) => {
                    submachine.commit_account(AccountCommitment::Full {
                        nonce: self.account_state.nonce(address)?,
                        balance: self.account_state.balance(address)?,
                        storage: self.account_state.storage(address)?.derive(),
                        code: self.account_state.code(address)?.into(),
                        address: address,
                    });
                },
                Err(ExecutionError::RequireAccountCode(address)) => {
                    submachine.commit_account(AccountCommitment::Code {
                        code: self.account_state.code(address)?.into(),
                        address: address,
                    });
                },
                val => return val,
            }
        }
    }

    fn merge_sub(&mut self, submachine: &Machine<M, S>) {
        for account in submachine.accounts() {
            self.account_state.merge(account);
        }
        for transaction in submachine.transactions() {
            self.transactions.push(transaction.clone());
        }
    }
}
<commit_msg>Problem: Call overflow is not handled Solution: create error CallOverflow<commit_after>mod stack;
mod pc;
mod memory;
mod params;
mod account;
mod storage;
mod cost;
mod run;
mod transaction;

pub use self::memory::{Memory, SeqMemory};
pub use self::stack::Stack;
pub use self::pc::PC;
pub use self::params::{BlockHeader, Context, Patch, Log};
pub use self::account::{Account, AccountCommitment};
pub use self::storage::{Storage, HashMapStorage};
pub use self::transaction::{Transaction, MessageCall, ContractCreation,
                            MessageCallMachine, ContractCreationMachine};

use self::account::AccountState;
use self::cost::{gas_cost, gas_refund, gas_stipend, CostAggregrator};
use self::run::run_opcode;
use std::collections::hash_map;
use utils::gas::Gas;
use utils::address::Address;
use utils::bigint::{M256, U256};

#[derive(Debug, Clone)]
pub enum ExecutionError {
    EmptyGas,
    EmptyBalance,
    StackUnderflow,
    StackOverflow,
    CallOverflow,
    InvalidOpcode,
    PCOverflow,
    PCBadJumpDest,
    PCTooLarge, // The current implementation only support code size with usize::maximum.
    MemoryTooLarge,
    DataTooLarge,
    CodeTooLarge,
    RequireAccount(Address),
    RequireAccountCode(Address),
    RequireBlockhash(M256),
    Stopped
}

impl ExecutionError {
    pub fn is_require(&self) -> bool {
        match self {
            &ExecutionError::RequireAccount(_) |
            &ExecutionError::RequireAccountCode(_) |
            &ExecutionError::RequireBlockhash(_) => true,
            _ => false,
        }
    }
}

#[derive(Debug)]
pub enum CommitError {
    AlreadyCommitted,
    StateChanged,
    Invalid,
}

pub type ExecutionResult<T> = ::std::result::Result<T, ExecutionError>;
pub type CommitResult<T> = ::std::result::Result<T, CommitError>;

pub type SeqMachine = Machine<SeqMemory, HashMapStorage>;

pub trait VM<S: Storage> {
    fn step(&mut self) -> ExecutionResult<()>;
    fn peek_cost(&self) -> ExecutionResult<Gas>;
    fn fire(&mut self) -> ExecutionResult<()> {
        loop {
            let result = self.step();

            if result.is_err() {
                match result.err().unwrap() {
                    ExecutionError::Stopped => return Ok(()),
                    err => return Err(err),
                }
            }
        }
    }

    fn commit_account(&mut self, commitment: AccountCommitment<S>) -> CommitResult<()>;
    fn commit_blockhash(&mut self, number: M256, hash: M256) -> CommitResult<()>;
    fn accounts(&self) -> hash_map::Values<Address, Account<S>>;
    fn transactions(&self) -> &[Transaction];
    fn appending_logs(&self) -> &[Log];
    fn available_gas(&self) -> Gas;

    fn patch(&self) -> Patch;
}

pub struct Machine<M, S> {
    pc: PC,
    memory: M,
    stack: Stack,
    cost_aggregrator: CostAggregrator,
    return_values: Vec<u8>,

    context: Context,
    block: BlockHeader,

    account_state: AccountState<S>,
    blockhashes: hash_map::HashMap<M256, M256>,
    appending_logs: Vec<Log>,
    transactions: Vec<Transaction>,

    used_gas: Gas,
    refunded_gas: Gas,

    patch: Patch,
}

impl<M: Memory + Default, S: Storage + Default> Machine<M, S> {
    pub fn new(context: Context, block: BlockHeader) -> Self {
        Self {
            pc: PC::new(context.code.as_slice()),
            memory: M::default(),
            stack: Stack::default(),
            cost_aggregrator: CostAggregrator::default(),
            return_values: Vec::new(),

            context: context,
            block: block,

            account_state: AccountState::default(),
            blockhashes: hash_map::HashMap::new(),
            appending_logs: Vec::new(),
            transactions: Vec::new(),

            used_gas: Gas::zero(),
            refunded_gas: Gas::zero(),

            patch: Patch::None,
        }
    }
}

impl<M: Memory + Default, S: Storage + Default> VM<S> for Machine<M, S> {
    fn peek_cost(&self) -> ExecutionResult<Gas> {
        if self.context.depth >= 1024 {
            return Err(ExecutionError::CallOverflow);
        }

        let opcode = self.pc.peek_opcode()?;
        let aggregrator = self.cost_aggregrator;
        let (gas, agg) = gas_cost(opcode, &self, aggregrator)?;
        Ok(gas)
    }

    fn step(&mut self) -> ExecutionResult<()> {
        if self.context.depth >= 1024 {
            return Err(ExecutionError::CallOverflow);
        }

        begin_rescuable!(self, &mut Self, __);
        if self.pc.stopped() {
            trr!(Err(ExecutionError::Stopped), __);
        }

        let position = self.pc.position();
        on_rescue!(|machine| {
            machine.pc.jump_unchecked(position);
        }, __);

        let opcode = trr!(self.pc.read_opcode(), __);
        let available_gas = self.available_gas();
        let cost_aggregrator = self.cost_aggregrator;
        let (gas, agg) = trr!(gas_cost(opcode, self, cost_aggregrator), __);
        let refunded = trr!(gas_refund(opcode, self), __);
        let stipend = trr!(gas_stipend(opcode, self), __);

        if gas > self.available_gas() {
            trr!(Err(ExecutionError::EmptyGas), __);
        }

        trr!(run_opcode(opcode, self, stipend, available_gas - gas + stipend), __);

        self.cost_aggregrator = agg;
        self.used_gas = self.used_gas + gas - stipend;
        self.refunded_gas = self.refunded_gas + refunded;

        end_rescuable!(__);
        Ok(())
    }

    fn commit_account(&mut self, commitment: AccountCommitment<S>) -> CommitResult<()> {
        self.account_state.commit(commitment)
    }

    fn commit_blockhash(&mut self, number: M256, hash: M256) -> CommitResult<()> {
        if self.blockhashes.contains_key(&number) {
            return Err(CommitError::AlreadyCommitted);
        }

        self.blockhashes.insert(number, hash);
        Ok(())
    }

    fn accounts(&self) -> hash_map::Values<Address, Account<S>> {
        self.account_state.accounts()
    }

    fn transactions(&self) -> &[Transaction] {
        self.transactions.as_slice()
    }

    fn appending_logs(&self) -> &[Log] {
        self.appending_logs.as_slice()
    }

    fn available_gas(&self) -> Gas {
        self.context.gas_limit - self.used_gas
    }

    fn patch(&self) -> Patch {
        self.patch
    }
}

impl<M: Memory + Default, S: Storage + Default> Machine<M, S> {
    pub fn pc(&self) -> &PC {
        &self.pc
    }

    pub fn memory(&self) -> &M {
        &self.memory
    }

    pub fn stack(&self) -> &Stack {
        &self.stack
    }

    pub fn context(&self) -> &Context {
        &self.context
    }

    pub fn block(&self) -> &BlockHeader {
        &self.block
    }

    pub fn accounts(&self) -> hash_map::Values<Address, Account<S>> {
        self.account_state.accounts()
    }

    pub fn return_values(&self) -> &[u8] {
        self.return_values.as_slice()
    }

    pub fn active_memory_len(&self) -> M256 {
        self.cost_aggregrator.active_memory_len()
    }

    fn blockhash(&mut self, number: M256) -> ExecutionResult<M256> {
        match self.blockhashes.get(&number) {
            Some(val) => Ok(*val),
            None => Err(ExecutionError::RequireBlockhash(number)),
        }
    }

    fn append_log(&mut self, log: Log) {
        self.appending_logs.push(log);
    }

    fn fire_sub<V: VM<S>>(&self, submachine: &mut V) -> ExecutionResult<()> {
        loop {
            let result = submachine.fire();
            match result {
                Err(ExecutionError::RequireAccount(address)) => {
                    submachine.commit_account(AccountCommitment::Full {
                        nonce: self.account_state.nonce(address)?,
                        balance: self.account_state.balance(address)?,
                        storage: self.account_state.storage(address)?.derive(),
                        code: self.account_state.code(address)?.into(),
                        address: address,
                    });
                },
                Err(ExecutionError::RequireAccountCode(address)) => {
                    submachine.commit_account(AccountCommitment::Code {
                        code: self.account_state.code(address)?.into(),
                        address: address,
                    });
                },
                val => return val,
            }
        }
    }

    fn merge_sub(&mut self, submachine: &Machine<M, S>) {
        for account in submachine.accounts() {
            self.account_state.merge(account);
        }
        for transaction in submachine.transactions() {
            self.transactions.push(transaction.clone());
        }
    }
}
<|endoftext|>


<commit_before>#![allow(unused)]

use super::{Cell, Mesh, Point};
use crate::shapes::GeoKind;
use crate::{util::PI, StrError};
use tritet::Triangle;

/// Groups generators of unstructured meshes (Tri and Tet only)
pub struct Unstructured {}

impl Unstructured {
    /// Generates a mesh representing a quarter of a ring in 2D
    ///
    /// ```text
    /// y ^
    ///   |
    ///   ***=---__
    ///   |        '*._
    ///   |            *._
    ///   |               *.
    ///   ***=-__           *.
    ///   .      '-.          *
    ///             *.         *
    ///   .           *         *
    ///                *         *
    ///   .             *         *
    ///                 #         #
    ///   o -   -   -   # ------- # --> x
    ///               rmin       rmax
    /// ```
    ///
    /// # Input
    ///
    /// * `rmin` -- inner radius
    /// * `rmax` -- outer radius
    /// * `nr` -- number of divisions along the radius (must be > 0)
    /// * `na` -- number of divisions along alpha (must be > 0)
    /// * `o2` -- generate middle nodes
    pub fn quarter_ring_2d(
        rmin: f64,
        rmax: f64,
        nr: usize,
        na: usize,
        o2: bool,
        global_max_area: Option<f64>,
    ) -> Result<Mesh, StrError> {
        // check
        if nr < 1 {
            return Err("number of divisions along the radius must be > 0");
        }
        if na < 1 {
            return Err("number of divisions along alpha must be > 0");
        }

        // allocate data
        let npoint = 2 * (nr + 1) + 2 * (na - 1);
        let nsegment = npoint;
        let nregion = 1;
        let mut tri = Triangle::new(npoint, Some(nsegment), Some(nregion), None)?;

        // constants
        const AMIN: f64 = 0.0;
        const AMAX: f64 = PI / 2.0;
        let dr = (rmax - rmin) / (nr as f64);
        let da = (AMAX - AMIN) / (na as f64);

        // counters
        let mut index = 0;

        // horizontal line
        tri.set_point(index, rmin, 0.0)?;
        index += 1;
        for i in 1..(nr + 1) {
            let r = rmin + (i as f64) * dr;
            tri.set_point(index, r, 0.0)?;
            tri.set_segment(index - 1, index - 1, index)?;
            index += 1;
        }

        // outer circle
        for i in 1..(na + 1) {
            let a = AMIN + (i as f64) * da;
            let x = rmax * f64::cos(a);
            let y = rmax * f64::sin(a);
            tri.set_point(index, x, y)?;
            tri.set_segment(index - 1, index - 1, index)?;
            index += 1;
        }

        // vertical line
        for i in 1..(nr + 1) {
            let r = rmin + ((nr - i) as f64) * dr;
            tri.set_point(index, 0.0, r)?;
            tri.set_segment(index - 1, index - 1, index)?;
            index += 1;
        }

        // inner circle
        for i in 1..na {
            let a = AMIN + ((na - i) as f64) * da;
            let x = rmin * f64::cos(a);
            let y = rmin * f64::sin(a);
            tri.set_point(index, x, y)?;
            tri.set_segment(index - 1, index - 1, index)?;
            index += 1;
        }
        tri.set_segment(index - 1, index - 1, 0)?;

        // region
        tri.set_region(0, rmin + 1e-4, 1e-4, 1, None);

        // generate mesh
        tri.generate_mesh(false, o2, global_max_area, None)?;

        // allocate data
        const NDIM: usize = 2;
        let npoint = tri.npoint();
        let ncell = tri.ntriangle();
        let nnode = tri.nnode();
        let kind = if o2 { GeoKind::Tri6 } else { GeoKind::Tri3 };
        let zero_point = Point {
            id: 0,
            coords: vec![0.0; NDIM],
        };
        let zero_cell = Cell {
            id: 0,
            attribute_id: 1,
            kind,
            points: vec![0; nnode],
        };
        let mut mesh = Mesh {
            ndim: NDIM,
            points: vec![zero_point; npoint],
            cells: vec![zero_cell; ncell],
        };

        // set mesh data
        for i in 0..npoint {
            mesh.points[i].id = i;
            mesh.points[i].coords[0] = tri.point(i, 0);
            mesh.points[i].coords[1] = tri.point(i, 1);
        }
        for i in 0..ncell {
            mesh.cells[i].id = i;
            mesh.cells[i].attribute_id = tri.triangle_attribute(i);
            for m in 0..nnode {
                mesh.cells[i].points[m] = tri.triangle_node(i, m);
            }
        }

        // results
        Ok(mesh)
    }
}

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

#[cfg(test)]
mod tests {
    use super::Unstructured;
    use crate::mesh::draw_mesh;
    use crate::StrError;

    #[test]
    fn tri_quarter_ring_2d_works() -> Result<(), StrError> {
        let mesh = Unstructured::quarter_ring_2d(3.0, 6.0, 2, 4, false, None)?;
        assert_eq!(mesh.points.len(), 14);
        assert_eq!(mesh.cells.len(), 14);
        if false {
            draw_mesh(&mesh, true, "/tmp/gemlab/test_tri_quarter_ring_2d.svg")?;
        }
        Ok(())
    }
}
<commit_msg>Add tests to generator tri<commit_after>#![allow(unused)]

use super::{Cell, Mesh, Point};
use crate::shapes::GeoKind;
use crate::{util::PI, StrError};
use tritet::Triangle;

/// Groups generators of unstructured meshes (Tri and Tet only)
pub struct Unstructured {}

impl Unstructured {
    /// Generates a mesh representing a quarter of a ring in 2D
    ///
    /// ```text
    /// y ^
    ///   |
    ///   ***=---__
    ///   |        '*._
    ///   |            *._
    ///   |               *.
    ///   ***=-__           *.
    ///   .      '-.          *
    ///             *.         *
    ///   .           *         *
    ///                *         *
    ///   .             *         *
    ///                 #         #
    ///   o -   -   -   # ------- # --> x
    ///               rmin       rmax
    /// ```
    ///
    /// # Input
    ///
    /// * `rmin` -- inner radius
    /// * `rmax` -- outer radius
    /// * `nr` -- number of divisions along the radius (must be > 0)
    /// * `na` -- number of divisions along alpha (must be > 0)
    /// * `o2` -- generate middle nodes
    pub fn quarter_ring_2d(
        rmin: f64,
        rmax: f64,
        nr: usize,
        na: usize,
        o2: bool,
        global_max_area: Option<f64>,
    ) -> Result<Mesh, StrError> {
        // check
        if nr < 1 {
            return Err("number of divisions along the radius must be > 0");
        }
        if na < 1 {
            return Err("number of divisions along alpha must be > 0");
        }

        // allocate data
        let npoint = 2 * (nr + 1) + 2 * (na - 1);
        let nsegment = npoint;
        let nregion = 1;
        let mut tri = Triangle::new(npoint, Some(nsegment), Some(nregion), None)?;

        // constants
        const AMIN: f64 = 0.0;
        const AMAX: f64 = PI / 2.0;
        let dr = (rmax - rmin) / (nr as f64);
        let da = (AMAX - AMIN) / (na as f64);

        // counters
        let mut index = 0;

        // horizontal line
        tri.set_point(index, rmin, 0.0)?;
        index += 1;
        for i in 1..(nr + 1) {
            let r = rmin + (i as f64) * dr;
            tri.set_point(index, r, 0.0)?;
            tri.set_segment(index - 1, index - 1, index)?;
            index += 1;
        }

        // outer circle
        for i in 1..(na + 1) {
            let a = AMIN + (i as f64) * da;
            let x = rmax * f64::cos(a);
            let y = rmax * f64::sin(a);
            tri.set_point(index, x, y)?;
            tri.set_segment(index - 1, index - 1, index)?;
            index += 1;
        }

        // vertical line
        for i in 1..(nr + 1) {
            let r = rmin + ((nr - i) as f64) * dr;
            tri.set_point(index, 0.0, r)?;
            tri.set_segment(index - 1, index - 1, index)?;
            index += 1;
        }

        // inner circle
        for i in 1..na {
            let a = AMIN + ((na - i) as f64) * da;
            let x = rmin * f64::cos(a);
            let y = rmin * f64::sin(a);
            tri.set_point(index, x, y)?;
            tri.set_segment(index - 1, index - 1, index)?;
            index += 1;
        }
        tri.set_segment(index - 1, index - 1, 0)?;

        // region
        tri.set_region(0, rmin + 1e-4, 1e-4, 1, None);

        // generate mesh
        tri.generate_mesh(false, o2, global_max_area, None)?;

        // allocate data
        const NDIM: usize = 2;
        let npoint = tri.npoint();
        let ncell = tri.ntriangle();
        let nnode = tri.nnode();
        let kind = if o2 { GeoKind::Tri6 } else { GeoKind::Tri3 };
        let zero_point = Point {
            id: 0,
            coords: vec![0.0; NDIM],
        };
        let zero_cell = Cell {
            id: 0,
            attribute_id: 1,
            kind,
            points: vec![0; nnode],
        };
        let mut mesh = Mesh {
            ndim: NDIM,
            points: vec![zero_point; npoint],
            cells: vec![zero_cell; ncell],
        };

        // set mesh data
        for i in 0..npoint {
            mesh.points[i].id = i;
            mesh.points[i].coords[0] = tri.point(i, 0);
            mesh.points[i].coords[1] = tri.point(i, 1);
        }
        for i in 0..ncell {
            mesh.cells[i].id = i;
            mesh.cells[i].attribute_id = tri.triangle_attribute(i);
            for m in 0..nnode {
                mesh.cells[i].points[m] = tri.triangle_node(i, m);
            }
        }

        // results
        Ok(mesh)
    }
}

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

#[cfg(test)]
mod tests {
    use super::Unstructured;
    use crate::StrError;

    #[allow(unused_imports)]
    use crate::mesh::draw_mesh;

    #[test]
    fn tri_quarter_ring_2d_captures_errors() {
        assert_eq!(
            Unstructured::quarter_ring_2d(3.0, 6.0, 0, 4, false, None).err(),
            Some("number of divisions along the radius must be > 0")
        );
        assert_eq!(
            Unstructured::quarter_ring_2d(3.0, 6.0, 2, 0, false, None).err(),
            Some("number of divisions along alpha must be > 0")
        );
    }

    #[test]
    fn tri_quarter_ring_2d_works() {
        let mesh = Unstructured::quarter_ring_2d(3.0, 6.0, 2, 4, false, None).unwrap();
        assert_eq!(mesh.points.len(), 14);
        assert_eq!(mesh.cells.len(), 14);
        // draw_mesh(&mesh, true, "/tmp/gemlab/test_tri_quarter_ring_2d.svg").unwrap();
    }
}
<|endoftext|>


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

#![feature(rustc_private, plugin_registrar)]

extern crate syntax;
extern crate rustc_plugin;

use syntax::ast::{MetaItem, Expr};
use syntax::ast;
use syntax::codemap::Span;
use syntax::ext::base;
use syntax::ext::base::{ExtCtxt, Annotatable};
use syntax::ext::build::AstBuilder;
use syntax::ext::deriving::generic::*;
use syntax::ext::deriving::generic::ty::*;
use syntax::parse::token;
use syntax::ptr::P;
use rustc_plugin::Registry;

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_syntax_extension(token::intern("derive_Rand"),
                                  base::MultiDecorator(Box::new(expand_deriving_rand)));
}

pub fn expand_deriving_rand(cx: &mut ExtCtxt,
                            span: Span,
                            mitem: &MetaItem,
                            item: &Annotatable,
                            push: &mut FnMut(Annotatable)) {
    let trait_def = TraitDef {
        span: span,
        attributes: Vec::new(),
        path: Path::new(vec!("rand", "Rand")),
        additional_bounds: Vec::new(),
        generics: LifetimeBounds::empty(),
        is_unsafe: false,
        methods: vec!(
            MethodDef {
                name: "rand",
                is_unsafe: false,
                generics: LifetimeBounds {
                    lifetimes: Vec::new(),
                    bounds: vec!(("R",
                                  vec!( Path::new(vec!("rand", "Rng")) )))
                },
                explicit_self: None,
                args: vec!(
                    Ptr(Box::new(Literal(Path::new_local("R"))),
                        Borrowed(None, ast::MutMutable))
                ),
                ret_ty: Self_,
                attributes: Vec::new(),
                combine_substructure: combine_substructure(Box::new(|a, b, c| {
                    rand_substructure(a, b, c)
                }))
            }
        ),
        associated_types: Vec::new(),
    };
    trait_def.expand(cx, mitem, &item, &mut |i| push(i))
}

fn rand_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> P<Expr> {
    let rng = if substr.nonself_args.len() == 1 {
        &substr.nonself_args[0]
    } else {
        cx.bug("Incorrect number of arguments to `rand` in `derive(Rand)`")
    };
    let rand_ident = vec!(
        cx.ident_of("rand"),
        cx.ident_of("Rand"),
        cx.ident_of("rand")
    );
    let rand_call = |cx: &mut ExtCtxt, span| {
        cx.expr_call_global(span,
                            rand_ident.clone(),
                            vec!(rng.clone()))
    };

    return match *substr.fields {
        StaticStruct(_, ref summary) => {
            let path = cx.path_ident(trait_span, substr.type_ident);
            rand_thing(cx, trait_span, path, summary, rand_call)
        }
        StaticEnum(_, ref variants) => {
            if variants.is_empty() {
                cx.span_err(trait_span, "`Rand` cannot be derived for enums with no variants");
                // let compilation continue
                return cx.expr_usize(trait_span, 0);
            }

            let variant_count = cx.expr_usize(trait_span, variants.len());

            let rand_name = cx.path_all(trait_span,
                                        true,
                                        rand_ident.clone(),
                                        Vec::new(),
                                        Vec::new(),
                                        Vec::new());
            let rand_name = cx.expr_path(rand_name);

            // ::rand::Rand::rand(rng)
            let rv_call = cx.expr_call(trait_span,
                                       rand_name,
                                       vec!(rng.clone()));

            // need to specify the usize-ness of the random number
            let usize_ty = cx.ty_ident(trait_span, cx.ident_of("usize"));
            let value_ident = cx.ident_of("__value");
            let let_statement = cx.stmt_let_typed(trait_span,
                                                  false,
                                                  value_ident,
                                                  usize_ty,
                                                  rv_call);

            // rand() % variants.len()
            let value_ref = cx.expr_ident(trait_span, value_ident);
            let rand_variant = cx.expr_binary(trait_span,
                                              ast::BiRem,
                                              value_ref,
                                              variant_count);

            let mut arms = variants.iter().enumerate().map(|(i, &(ident, v_span, ref summary))| {
                let i_expr = cx.expr_usize(v_span, i);
                let pat = cx.pat_lit(v_span, i_expr);

                let path = cx.path(v_span, vec![substr.type_ident, ident]);
                let thing = rand_thing(cx, v_span, path, summary, |cx, sp| rand_call(cx, sp));
                cx.arm(v_span, vec!( pat ), thing)
            }).collect::<Vec<ast::Arm> >();

            // _ => {} at the end. Should never occur
            arms.push(cx.arm_unreachable(trait_span));

            let match_expr = cx.expr_match(trait_span, rand_variant, arms);

            let block = cx.block(trait_span, vec!( let_statement ), Some(match_expr));
            cx.expr_block(block)
        }
        _ => cx.bug("Non-static method in `derive(Rand)`")
    };

    fn rand_thing<F>(cx: &mut ExtCtxt,
                     trait_span: Span,
                     ctor_path: ast::Path,
                     summary: &StaticFields,
                     mut rand_call: F)
                     -> P<Expr> where
        F: FnMut(&mut ExtCtxt, Span) -> P<Expr>,
    {
        let path = cx.expr_path(ctor_path.clone());
        match *summary {
            Unnamed(ref fields) => {
                if fields.is_empty() {
                    path
                } else {
                    let exprs = fields.iter().map(|span| rand_call(cx, *span)).collect();
                    cx.expr_call(trait_span, path, exprs)
                }
            }
            Named(ref fields) => {
                let rand_fields = fields.iter().map(|&(ident, span)| {
                    let e = rand_call(cx, span);
                    cx.field_imm(span, ident, e)
                }).collect();
                cx.expr_struct(trait_span, ctor_path, rand_fields)
            }
        }
    }
}
<commit_msg>Fix rand_macros for syntax/syntax_ext crate split<commit_after>// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(rustc_private, plugin_registrar)]

extern crate syntax;
extern crate syntax_ext;
extern crate rustc_plugin;

use syntax::ast::{MetaItem, Expr};
use syntax::ast;
use syntax::codemap::Span;
use syntax::ext::base;
use syntax::ext::base::{ExtCtxt, Annotatable};
use syntax::ext::build::AstBuilder;
use syntax_ext::deriving::generic::*;
use syntax_ext::deriving::generic::ty::*;
use syntax::parse::token;
use syntax::ptr::P;
use rustc_plugin::Registry;

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_syntax_extension(token::intern("derive_Rand"),
                                  base::MultiDecorator(Box::new(expand_deriving_rand)));
}

pub fn expand_deriving_rand(cx: &mut ExtCtxt,
                            span: Span,
                            mitem: &MetaItem,
                            item: &Annotatable,
                            push: &mut FnMut(Annotatable)) {
    let trait_def = TraitDef {
        span: span,
        attributes: Vec::new(),
        path: Path::new(vec!("rand", "Rand")),
        additional_bounds: Vec::new(),
        generics: LifetimeBounds::empty(),
        is_unsafe: false,
        methods: vec!(
            MethodDef {
                name: "rand",
                is_unsafe: false,
                generics: LifetimeBounds {
                    lifetimes: Vec::new(),
                    bounds: vec!(("R",
                                  vec!( Path::new(vec!("rand", "Rng")) )))
                },
                explicit_self: None,
                args: vec!(
                    Ptr(Box::new(Literal(Path::new_local("R"))),
                        Borrowed(None, ast::MutMutable))
                ),
                ret_ty: Self_,
                attributes: Vec::new(),
                combine_substructure: combine_substructure(Box::new(|a, b, c| {
                    rand_substructure(a, b, c)
                }))
            }
        ),
        associated_types: Vec::new(),
    };
    trait_def.expand(cx, mitem, &item, &mut |i| push(i))
}

fn rand_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> P<Expr> {
    let rng = if substr.nonself_args.len() == 1 {
        &substr.nonself_args[0]
    } else {
        cx.bug("Incorrect number of arguments to `rand` in `derive(Rand)`")
    };
    let rand_ident = vec!(
        cx.ident_of("rand"),
        cx.ident_of("Rand"),
        cx.ident_of("rand")
    );
    let rand_call = |cx: &mut ExtCtxt, span| {
        cx.expr_call_global(span,
                            rand_ident.clone(),
                            vec!(rng.clone()))
    };

    return match *substr.fields {
        StaticStruct(_, ref summary) => {
            let path = cx.path_ident(trait_span, substr.type_ident);
            rand_thing(cx, trait_span, path, summary, rand_call)
        }
        StaticEnum(_, ref variants) => {
            if variants.is_empty() {
                cx.span_err(trait_span, "`Rand` cannot be derived for enums with no variants");
                // let compilation continue
                return cx.expr_usize(trait_span, 0);
            }

            let variant_count = cx.expr_usize(trait_span, variants.len());

            let rand_name = cx.path_all(trait_span,
                                        true,
                                        rand_ident.clone(),
                                        Vec::new(),
                                        Vec::new(),
                                        Vec::new());
            let rand_name = cx.expr_path(rand_name);

            // ::rand::Rand::rand(rng)
            let rv_call = cx.expr_call(trait_span,
                                       rand_name,
                                       vec!(rng.clone()));

            // need to specify the usize-ness of the random number
            let usize_ty = cx.ty_ident(trait_span, cx.ident_of("usize"));
            let value_ident = cx.ident_of("__value");
            let let_statement = cx.stmt_let_typed(trait_span,
                                                  false,
                                                  value_ident,
                                                  usize_ty,
                                                  rv_call);

            // rand() % variants.len()
            let value_ref = cx.expr_ident(trait_span, value_ident);
            let rand_variant = cx.expr_binary(trait_span,
                                              ast::BiRem,
                                              value_ref,
                                              variant_count);

            let mut arms = variants.iter().enumerate().map(|(i, &(ident, v_span, ref summary))| {
                let i_expr = cx.expr_usize(v_span, i);
                let pat = cx.pat_lit(v_span, i_expr);

                let path = cx.path(v_span, vec![substr.type_ident, ident]);
                let thing = rand_thing(cx, v_span, path, summary, |cx, sp| rand_call(cx, sp));
                cx.arm(v_span, vec!( pat ), thing)
            }).collect::<Vec<ast::Arm> >();

            // _ => {} at the end. Should never occur
            arms.push(cx.arm_unreachable(trait_span));

            let match_expr = cx.expr_match(trait_span, rand_variant, arms);

            let block = cx.block(trait_span, vec!( let_statement ), Some(match_expr));
            cx.expr_block(block)
        }
        _ => cx.bug("Non-static method in `derive(Rand)`")
    };

    fn rand_thing<F>(cx: &mut ExtCtxt,
                     trait_span: Span,
                     ctor_path: ast::Path,
                     summary: &StaticFields,
                     mut rand_call: F)
                     -> P<Expr> where
        F: FnMut(&mut ExtCtxt, Span) -> P<Expr>,
    {
        let path = cx.expr_path(ctor_path.clone());
        match *summary {
            Unnamed(ref fields) => {
                if fields.is_empty() {
                    path
                } else {
                    let exprs = fields.iter().map(|span| rand_call(cx, *span)).collect();
                    cx.expr_call(trait_span, path, exprs)
                }
            }
            Named(ref fields) => {
                let rand_fields = fields.iter().map(|&(ident, span)| {
                    let e = rand_call(cx, span);
                    cx.field_imm(span, ident, e)
                }).collect();
                cx.expr_struct(trait_span, ctor_path, rand_fields)
            }
        }
    }
}
<|endoftext|>


<commit_before>
use super::*;

//

tests_impls!
{
  fn basic_no_args()
  {
    let path = std::ffi::OsStr::new( "../../../target/debug/wpublisher" );
    let proc = std::process::Command::new( path ).output().unwrap();
    assert!( !proc.status.success() );
    let stderr = std::str::from_utf8( proc.stderr.as_slice() ).unwrap();
    assert_eq!( stderr, "Ambiguity. Did you mean?\n" );
    let stdout = std::str::from_utf8( proc.stdout.as_slice() ).unwrap();
    assert!( stdout.contains( ".list - List packages." ) );
  }

  //

  fn basic_with_args()
  {
    let path = std::ffi::OsStr::new( "../../../target/debug/wpublisher" );
    let proc = std::process::Command::new( path ).arg( ".list" ).output().unwrap();
    assert!( proc.status.success() );
    let stdout = std::str::from_utf8( proc.stdout.as_slice() ).unwrap();
    assert_eq!( stdout, "" );
    let stderr = std::str::from_utf8( proc.stderr.as_slice() ).unwrap();
    assert_eq!( stderr, "" );
  }
}

//

tests_index!
{
  basic_no_args,
  basic_with_args,
}
<commit_msg>Fix tests of utility `wpublisher`, use compile mode directives<commit_after>
use super::*;

//

tests_impls!
{
  fn basic_no_args()
  {
    #[ cfg( debug_assertions ) ]
    let path = std::ffi::OsStr::new( "../../../target/debug/wpublisher" );
    #[ cfg( not( debug_assertions ) ) ]
    let path = std::ffi::OsStr::new( "../../../target/release/wpublisher" );
    let proc = std::process::Command::new( path ).output().unwrap();
    assert!( !proc.status.success() );
    let stderr = std::str::from_utf8( proc.stderr.as_slice() ).unwrap();
    assert_eq!( stderr, "Ambiguity. Did you mean?\n" );
    let stdout = std::str::from_utf8( proc.stdout.as_slice() ).unwrap();
    assert!( stdout.contains( ".list - List packages." ) );
  }

  //

  fn basic_with_args()
  {
    #[ cfg( debug_assertions ) ]
    let path = std::ffi::OsStr::new( "../../../target/debug/wpublisher" );
    #[ cfg( not( debug_assertions ) ) ]
    let path = std::ffi::OsStr::new( "../../../target/release/wpublisher" );
    let proc = std::process::Command::new( path ).arg( ".list" ).output().unwrap();
    assert!( proc.status.success() );
    let stdout = std::str::from_utf8( proc.stdout.as_slice() ).unwrap();
    assert_eq!( stdout, "" );
    let stderr = std::str::from_utf8( proc.stderr.as_slice() ).unwrap();
    assert_eq!( stderr, "" );
  }
}

//

tests_index!
{
  basic_no_args,
  basic_with_args,
}
<|endoftext|>


<commit_before>const VALID_TAGS: [&'static str; 9] = ["*", "_", "**", "__", "***", "~~", "`", "``", "```"];

pub fn parse(escaped: &str) -> String {
  let mut symbols = 0;
  let mut skip = 0;
  let mut in_tag = false;

  let mut result = String::new();
  let mut buffer = String::new();

  let owned = escaped.to_owned();
  let mut iter = owned.chars().peekable();
  while let Some(c) = iter.next() {
    if skip > 0 {
      skip -= 1;
      continue;
    }
    match c {
      '*' | '_' | '`' => {
        if symbols == 0 {
          result.push_str(&buffer);
          buffer.clear();
        }
        symbols += 1;
      },
      '<' => in_tag = true,
      '>' => in_tag = false,
      _ => {}
    }
    buffer.push(c);
    if in_tag {
      continue;
    }
    if let Some(&next) = iter.peek() {
      if next != c && symbols > 0 && VALID_TAGS.contains(&buffer.as_ref()) {
        let s = iter.clone().collect::<String>();
        if let Some(m) = s.find(&buffer) {
          let mut content = &s[..m];
          skip = content.chars().count() + buffer.len();
          let (tag, styles) = match buffer.as_ref() {
            "_" | "*" => ("span", Some("emphasis")),
            "__" => ("span", Some("underline")),
            "**" => ("span", Some("strong")),
            "***" => ("span", Some("strong emphasis")),
            "~~" => ("span", Some("strikethrough")),
            "`" | "``" => ("span", Some("code")),
            "```" => {
              content = content.trim_matches('\n');
              ("pre", None)
            },
            _ => unreachable!()
          };
          let is_code = if let Some("code") = styles { false } else { true };
          let class = styles.map(|x| format!(" class=\"{}\"", x)).unwrap_or_else(Default::default);
          result += &format!("<{tag}{class}>{content}</{tag}>",
            tag = tag,
            class = class,
            content = if is_code { parse(content) } else { content.to_owned() });
          buffer.clear();
          symbols = 0;
        }
      }
    }
  }
  result += &buffer;
  result
}

#[cfg(test)]
mod test {
  extern crate test;

  const TEST_STRING: &'static str = "blah __underline__ blah **bold** and ***bold italic*** with __***underline bold italics***__";
  const TEST_EXPECTED: &'static str = "blah underline blah bold and bold italic with underline bold italics";

  #[test]
  fn parse() {
    assert_eq!(TEST_EXPECTED, super::parse(TEST_STRING));
  }

  #[test]
  fn parse_weird() {
    assert_eq!("kek gon give it **to ya**",
      super::parse("__kek gon give it **to ya__**"));
  }

  #[test]
  fn parse_text() {
    let text = "this is some normal text";
    assert_eq!(text, super::parse(text));
  }

  #[test]
  fn parse_two_asterisks() {
    assert_eq!("**", super::parse("**"));
  }

  #[test]
  fn parse_three_asterisks() {
    assert_eq!("***", super::parse("***"));
  }

  #[test]
  #[ignore]
  // honestly, I can't be bothered to fix this. sure, it doesn't match discord's markdown parser
  // exactly, but it's late, this is hard for my brain, and who types this kind of shit anyway
  fn parse_four_asterisks() {
    assert_eq!("**four!**",
      super::parse("****four!****"));
  }

  #[test]
  fn parse_inner() {
    let source = "*italicized __underlines__ yo*";
    let output = "italicized underlines yo";
    assert_eq!(output, super::parse(source));
  }

  #[test]
  fn parse_tag() {
    let source = "some text yo";
    assert_eq!(source, super::parse(source));
  }

  #[bench]
  fn parse_benchmark(b: &mut self::test::Bencher) {
    b.iter(|| super::parse(TEST_STRING));
  }
}
<commit_msg>fix(archive_viewer): don't make needless copies<commit_after>const VALID_TAGS: [&'static str; 9] = ["*", "_", "**", "__", "***", "~~", "`", "``", "```"];

// FIXME: process line breaks as <br/>

pub fn parse(escaped: &str) -> String {
  let mut symbols = 0;
  let mut skip = 0;
  let mut in_tag = false;

  let mut result = String::new();
  let mut buffer = String::new();

  let mut iter = escaped.chars().peekable();
  while let Some(c) = iter.next() {
    if skip > 0 {
      skip -= 1;
      continue;
    }
    match c {
      '*' | '_' | '`' => {
        if symbols == 0 {
          result.push_str(&buffer);
          buffer.clear();
        }
        symbols += 1;
      },
      '<' => in_tag = true,
      '>' => in_tag = false,
      _ => {}
    }
    buffer.push(c);
    if in_tag {
      continue;
    }
    if let Some(&next) = iter.peek() {
      if next != c && symbols > 0 && VALID_TAGS.contains(&buffer.as_ref()) {
        let s = iter.clone().collect::<String>();
        if let Some(m) = s.find(&buffer) {
          let mut content = &s[..m];
          skip = content.chars().count() + buffer.len();
          let (tag, styles) = match buffer.as_ref() {
            "_" | "*" => ("span", Some("emphasis")),
            "__" => ("span", Some("underline")),
            "**" => ("span", Some("strong")),
            "***" => ("span", Some("strong emphasis")),
            "~~" => ("span", Some("strikethrough")),
            "`" | "``" => ("span", Some("code")),
            "```" => {
              content = content.trim_matches('\n');
              ("pre", None)
            },
            _ => unreachable!()
          };
          let is_code = if let Some("code") = styles { false } else { true };
          let class = styles.map(|x| format!(" class=\"{}\"", x)).unwrap_or_else(Default::default);
          if is_code {
            result.push_str(&format!("<{tag}{class}>{content}</{tag}>",
            tag = tag,
            class = class,
            content = content));
          } else {
            result.push_str(&format!("<{tag}{class}>{content}</{tag}>",
            tag = tag,
            class = class,
            content = parse(content)));
          }
          buffer.clear();
          symbols = 0;
        }
      }
    }
  }
  result += &buffer;
  result
}

#[cfg(test)]
mod test {
  extern crate test;

  const TEST_STRING: &'static str = "blah __underline__ blah **bold** and ***bold italic*** with __***underline bold italics***__";
  const TEST_EXPECTED: &'static str = "blah underline blah bold and bold italic with underline bold italics";

  #[test]
  fn parse() {
    assert_eq!(TEST_EXPECTED, super::parse(TEST_STRING));
  }

  #[test]
  fn parse_weird() {
    assert_eq!("kek gon give it **to ya**",
      super::parse("__kek gon give it **to ya__**"));
  }

  #[test]
  fn parse_text() {
    let text = "this is some normal text";
    assert_eq!(text, super::parse(text));
  }

  #[test]
  fn parse_two_asterisks() {
    assert_eq!("**", super::parse("**"));
  }

  #[test]
  fn parse_three_asterisks() {
    assert_eq!("***", super::parse("***"));
  }

  #[test]
  #[ignore]
  // honestly, I can't be bothered to fix this. sure, it doesn't match discord's markdown parser
  // exactly, but it's late, this is hard for my brain, and who types this kind of shit anyway
  fn parse_four_asterisks() {
    assert_eq!("**four!**",
      super::parse("****four!****"));
  }

  #[test]
  fn parse_inner() {
    let source = "*italicized __underlines__ yo*";
    let output = "italicized underlines yo";
    assert_eq!(output, super::parse(source));
  }

  #[test]
  fn parse_tag() {
    let source = "some text yo";
    assert_eq!(source, super::parse(source));
  }

  #[bench]
  fn parse_benchmark(b: &mut self::test::Bencher) {
    b.iter(|| super::parse(TEST_STRING));
  }
}
<|endoftext|>


<commit_before>#[allow(dead_code)]
const IMPASSABLE_TILES: [[i32; 2]; 12] = [[1, 1], [2, 2], [2, 3], [2, 4], [2, 5], [3, 0], [3, 5], [4, 0], [4, 2], [4, 3], [4, 4], [4, 5]];

#[test]
fn path_finding_test_1() {
  use cgmath::Point2;
  use crate::game::constants::Y_OFFSET;
  use crate::shaders::Position;
  use crate::terrain::path_finding::calc_route;

  let expected_result_1: Vec<Point2<i32>> = vec![[0, 0], [1, 0], [2, 1], [3, 2], [4, 1], [5, 2], [5, 3], [5, 4], [5, 5]]
    .iter()
    .map(|e| Point2::new(e[0], e[1]))
    .collect();

  assert_eq!(expected_result_1,
             calc_route(Position::new(0.0, -Y_OFFSET), Position::new(0.0, -Y_OFFSET + 5.0 * 46.0), &IMPASSABLE_TILES.to_vec())
               .map_or_else(|| vec![],
                            |(f, _)| f),
             "path_finding_test_1");
}

#[test]
fn path_finding_test_2() {
  use cgmath::Point2;
  use crate::game::constants::Y_OFFSET;
  use crate::shaders::Position;
  use crate::terrain::path_finding::calc_route;

  let expected_result: Vec<Point2<i32>> = vec![[3, 3], [3, 2], [4, 1], [5, 2], [5, 3], [5, 4], [5, 5]]
    .iter()
    .map(|e| Point2::new(e[0], e[1]))
    .collect();

  assert_eq!(expected_result,
             calc_route(Position::new(0.0, -Y_OFFSET + 3.0 * 46.0), Position::new(0.0, -Y_OFFSET + 5.0 * 46.0), &IMPASSABLE_TILES.to_vec())
               .map_or_else(|| vec![],
                            |(f, _)| f),
             "path_finding_test_2");
}
<commit_msg>Fix unit tests<commit_after>use crate::game::constants::TILE_WIDTH;

#[allow(dead_code)]
const IMPASSABLE_TILES: [[i32; 2]; 12] = [[1, 1], [2, 2], [2, 3], [2, 4], [2, 5], [3, 0], [3, 5], [4, 0], [4, 2], [4, 3], [4, 4], [4, 5]];

#[test]
fn path_finding_test_1() {
  use cgmath::Point2;
  use crate::game::constants::Y_OFFSET;
  use crate::shaders::Position;
  use crate::terrain::path_finding::calc_route;

  let expected_result_1: Vec<Point2<i32>> = vec![[0, 0], [1, 0], [2, 1], [3, 2], [4, 1], [5, 2], [5, 3], [5, 4], [5, 5]]
    .iter()
    .map(|e| Point2::new(e[0], e[1]))
    .collect();

  assert_eq!(expected_result_1,
             calc_route(Position::new(0.0, -Y_OFFSET), Position::new(0.0, -Y_OFFSET + 5.0 * TILE_WIDTH), &IMPASSABLE_TILES.to_vec())
               .map_or_else(|| vec![],
                            |(f, _)| f),
             "path_finding_test_1");
}

#[test]
fn path_finding_test_2() {
  use cgmath::Point2;
  use crate::game::constants::Y_OFFSET;
  use crate::shaders::Position;
  use crate::terrain::path_finding::calc_route;

  let expected_result: Vec<Point2<i32>> = vec![[3, 3], [3, 2], [4, 1], [5, 2], [5, 3], [5, 4], [5, 5]]
    .iter()
    .map(|e| Point2::new(e[0], e[1]))
    .collect();

  assert_eq!(expected_result,
             calc_route(Position::new(0.0, -Y_OFFSET + 3.0 * TILE_WIDTH), Position::new(0.0, -Y_OFFSET + 5.0 * TILE_WIDTH), &IMPASSABLE_TILES.to_vec())
               .map_or_else(|| vec![],
                            |(f, _)| f),
             "path_finding_test_2");
}
<|endoftext|>


<commit_before>/* Cymbalum, Molecular Simulation in Rust - Copyright (C) 2015 Guillaume Fraux
 *
 * 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/
 */
//! A Monte-Carlo simulation is based on a set of applicables moves.
//!
//! For example, NVT Monte-Carlo will use the `Translate` move only for particles
//! and add the `Rotate` moves for molecules. NPT Monte-Carlo will add the
//! `VolumeResize` move.
//!
//! In all this module, beta refers to the Boltzmann factor 1/(kB T)
extern crate rand;
use self::rand::distributions::{Sample, Range};
use self::rand::Rng;

use std::usize;

use types::Vector3D;
use universe::Universe;

/// The `MCMove` trait correspond to the set of methods used in Monte-Carlo
/// simulations.
pub trait MCMove {
    /// Give a short description of this move
    fn describe(&self) -> &str;

    /// Prepare the move, by selecting the particles to move, and the parameters
    /// of the move. The `rng` random number generator should be used to
    /// generate the parameters of the move.
    fn prepare(&mut self, universe: &mut Universe, rng: &mut Box<Rng>);

    /// Get the cost of performing this move, as the exponential factor. For
    /// simple NVT simulations, this cost is the energetic difference over
    /// `beta`.
    ///
    /// The cost must be dimmensionless, and will be placed in an exponential.
    fn cost(&self, universe: &Universe, beta: f64) -> f64;

    /// Effectivelly apply the move, if it has not already been done in
    /// `prepare`.
    fn apply(&mut self, universe: &mut Universe);

    /// Restore the universe to it's initial state, if it has been changed in
    /// `prepare`.
    fn restore(&mut self, universe: &mut Universe);
}

/******************************************************************************/

/// Monte-Carlo move for translating a molecule
pub struct Translate {
    /// Index of the molecule to translate
    molecule: usize,
    /// Translation vector
    delta: Vector3D,
    /// Translation range
    delta_range: Range<f64>,
    /// Potential energy before the move
    e_before: f64,
}

impl Translate {
    /// Create a new `Translate` move, with maximum displacement of `dr`.
    pub fn new(dr: f64) -> Translate {
        assert!(dr > 0.0, "dr must be positive in Translate move");
        let dr = dr / f64::sqrt(3.0);
        Translate {
            molecule: usize::MAX,
            delta: Vector3D::new(0.0, 0.0, 0.0),
            delta_range: Range::new(-dr, dr),
            e_before: 0.0,
        }
    }
}

impl MCMove for Translate {
    fn describe(&self) -> &str {
        "molecular translation"
    }

    fn prepare(&mut self, universe: &mut Universe, rng: &mut Box<Rng>) {
        self.delta.x = self.delta_range.sample(rng);
        self.delta.y = self.delta_range.sample(rng);
        self.delta.z = self.delta_range.sample(rng);

        let nmols = universe.molecules().len();
        self.molecule = rng.gen_range(0, nmols);

        self.e_before = universe.potential_energy();
        for i in universe.molecules()[self.molecule].clone() {
            universe[i].position = universe[i].position + self.delta;
        }
    }

    fn cost(&self, universe: &Universe, beta: f64) -> f64 {
        let e_after = universe.potential_energy();
        return (e_after - self.e_before)/beta;
    }

    fn apply(&mut self, _: &mut Universe) {
        // Nothing to do
    }

    fn restore(&mut self, universe: &mut Universe) {
        for i in universe.molecules()[self.molecule].clone() {
            universe[i].position = universe[i].position - self.delta;
        }
    }
}
<commit_msg>Add implementation of Default for Translate move<commit_after>/* Cymbalum, Molecular Simulation in Rust - Copyright (C) 2015 Guillaume Fraux
 *
 * 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/
 */
//! A Monte-Carlo simulation is based on a set of applicables moves.
//!
//! For example, NVT Monte-Carlo will use the `Translate` move only for particles
//! and add the `Rotate` moves for molecules. NPT Monte-Carlo will add the
//! `VolumeResize` move.
//!
//! In all this module, beta refers to the Boltzmann factor 1/(kB T)
extern crate rand;
use self::rand::distributions::{Sample, Range};
use self::rand::Rng;

use std::usize;

use types::Vector3D;
use universe::Universe;

/// The `MCMove` trait correspond to the set of methods used in Monte-Carlo
/// simulations.
pub trait MCMove {
    /// Give a short description of this move
    fn describe(&self) -> &str;

    /// Prepare the move, by selecting the particles to move, and the parameters
    /// of the move. The `rng` random number generator should be used to
    /// generate the parameters of the move.
    fn prepare(&mut self, universe: &mut Universe, rng: &mut Box<Rng>);

    /// Get the cost of performing this move, as the exponential factor. For
    /// simple NVT simulations, this cost is the energetic difference over
    /// `beta`.
    ///
    /// The cost must be dimmensionless, and will be placed in an exponential.
    fn cost(&self, universe: &Universe, beta: f64) -> f64;

    /// Effectivelly apply the move, if it has not already been done in
    /// `prepare`.
    fn apply(&mut self, universe: &mut Universe);

    /// Restore the universe to it's initial state, if it has been changed in
    /// `prepare`.
    fn restore(&mut self, universe: &mut Universe);
}

/******************************************************************************/

/// Monte-Carlo move for translating a molecule
pub struct Translate {
    /// Index of the molecule to translate
    molecule: usize,
    /// Translation vector
    delta: Vector3D,
    /// Translation range
    delta_range: Range<f64>,
    /// Potential energy before the move
    e_before: f64,
}

impl Translate {
    /// Create a new `Translate` move, with maximum displacement of `dr`.
    pub fn new(dr: f64) -> Translate {
        assert!(dr > 0.0, "dr must be positive in Translate move");
        let dr = dr / f64::sqrt(3.0);
        Translate {
            molecule: usize::MAX,
            delta: Vector3D::new(0.0, 0.0, 0.0),
            delta_range: Range::new(-dr, dr),
            e_before: 0.0,
        }
    }
}

impl Default for Translate {
    fn default() -> Translate {
        Translate::new(1.0)
    }
}

impl MCMove for Translate {
    fn describe(&self) -> &str {
        "molecular translation"
    }

    fn prepare(&mut self, universe: &mut Universe, rng: &mut Box<Rng>) {
        self.delta.x = self.delta_range.sample(rng);
        self.delta.y = self.delta_range.sample(rng);
        self.delta.z = self.delta_range.sample(rng);

        let nmols = universe.molecules().len();
        self.molecule = rng.gen_range(0, nmols);

        self.e_before = universe.potential_energy();
        for i in universe.molecules()[self.molecule].clone() {
            universe[i].position = universe[i].position + self.delta;
        }
    }

    fn cost(&self, universe: &Universe, beta: f64) -> f64 {
        let e_after = universe.potential_energy();
        return (e_after - self.e_before)/beta;
    }

    fn apply(&mut self, _: &mut Universe) {
        // Nothing to do
    }

    fn restore(&mut self, universe: &mut Universe) {
        for i in universe.molecules()[self.molecule].clone() {
            universe[i].position = universe[i].position - self.delta;
        }
    }
}
<|endoftext|>


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

use either::*;
enum X = Either<(uint,uint),fn()>;
impl &X {
    fn with(blk: fn(x: &Either<(uint,uint),fn()>)) {
        blk(&**self)
    }
}
fn main() {
    let mut x = X(Right(main));
    do (&mut x).with |opt| {  //~ ERROR illegal borrow
        match *opt {
            Right(f) => {
                x = X(Left((0,0)));
                f()
            },
            _ => fail
        }
    }
}<commit_msg>Fix broken test<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use either::*;
enum X = Either<(uint,uint),fn()>;
impl &X {
    fn with(blk: fn(x: &Either<(uint,uint),fn()>)) {
        blk(&**self)
    }
}
fn main() {
    let mut x = X(Right(main));
    do (&mut x).with |opt| {  //~ ERROR illegal borrow
        match opt {
            &Right(f) => {
                x = X(Left((0,0)));
                f()
            },
            _ => fail
        }
    }
}<|endoftext|>


<commit_before>#[macro_use]
extern crate criterion;
extern crate ipnetwork;

use ipnetwork::{Ipv4Network, Ipv6Network};
use criterion::Criterion;

fn parse_ipv4_benchmark(c: &mut Criterion) {
    c.bench_function("parse ipv4", |b| b.iter(|| {
        "127.1.0.0/24".parse::<Ipv4Network>().unwrap()
    }));
}

fn parse_ipv6_benchmark(c: &mut Criterion) {
    c.bench_function("parse ipv6", |b| b.iter(|| {
        "FF01:0:0:17:0:0:0:2/64".parse::<Ipv6Network>().unwrap()
    }));
}

criterion_group!(benches, parse_ipv4_benchmark, parse_ipv6_benchmark);
criterion_main!(benches);
<commit_msg>Track benchmark for contains<commit_after>#[macro_use]
extern crate criterion;
extern crate ipnetwork;

use ipnetwork::{Ipv4Network, Ipv6Network};
use criterion::Criterion;

use std::net::{Ipv4Addr, Ipv6Addr};

fn parse_ipv4_benchmark(c: &mut Criterion) {
    c.bench_function("parse ipv4", |b| b.iter(|| {
        "127.1.0.0/24".parse::<Ipv4Network>().unwrap()
    }));
}

fn parse_ipv6_benchmark(c: &mut Criterion) {
    c.bench_function("parse ipv6", |b| b.iter(|| {
        "FF01:0:0:17:0:0:0:2/64".parse::<Ipv6Network>().unwrap()
    }));
}

fn contains_ipv4_benchmark(c: &mut Criterion) {
    c.bench_function("contains ipv4", |b| b.iter(|| {
        let cidr = "74.125.227.0/25".parse::<Ipv4Network>().unwrap();
        cidr.contains(Ipv4Addr::new(74, 125, 227, 4))
    }));
}

fn contains_ipv6_benchmark(c: &mut Criterion) {
    c.bench_function("contains ipv6", |b| b.iter(|| {
        let cidr = "FF01:0:0:17:0:0:0:2/65".parse::<Ipv6Network>().unwrap();
        cidr.contains(Ipv6Addr::new(0xff01, 0, 0, 0x17, 0x7fff, 0, 0, 0x2))
    }));
}

criterion_group!(benches, parse_ipv4_benchmark, parse_ipv6_benchmark, contains_ipv4_benchmark, contains_ipv6_benchmark);
criterion_main!(benches);
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2013, David Renshaw (dwrenshaw@gmail.com)
 *
 * See the LICENSE file in the capnproto-rust root directory.
 */

use rand::*;
use std::i32;

pub struct FastRand {
    state : u32
}

impl Rng for FastRand {
    #[inline]
    fn next_u32(&mut self) -> u32 {
        let a = 1664525;
        let c = 1013904223;
        self.state = a * self.state + c;
        self.state
    }
}

impl FastRand {
    pub fn new() -> FastRand {
        FastRand {state : 1013904223}
    }

    #[inline]
    pub fn next_less_than(&mut self, range : u32) -> u32 {
        self.next_u32() % range
    }

    #[inline]
    pub fn next_double(&mut self, range : f64) -> f64 {
        use std::u32;
        self.next_u32() as f64 * range / (u32::MAX as f64)
    }
}

#[inline]
pub fn div(a : i32, b: i32) -> i32 {
    if b == 0 { return i32::MAX }
    if a == i32::MIN && b == -1 {
        return i32::MAX;
    }
    return a / b;
}

#[inline]
pub fn modulus(a : i32, b: i32) -> i32 {
    if b == 0 { return i32::MAX }
    if a == i32::MIN && b == -1 {
        return i32::MAX;
    }
    return a % b;
}

pub static WORDS : [&'static str, .. 13] = [
    "foo ", "bar ", "baz ", "qux ", "quux ", "corge ", "grault ", "garply ", "waldo ", "fred ",
    "plugh ", "xyzzy ", "thud "];

<commit_msg>update to use Xorshift random number generation<commit_after>/*
 * Copyright (c) 2013, David Renshaw (dwrenshaw@gmail.com)
 *
 * See the LICENSE file in the capnproto-rust root directory.
 */

use rand::*;
use std::i32;

pub struct FastRand {
    x : u32,
    y : u32,
    z : u32,
    w : u32,
}

impl Rng for FastRand {
    #[inline]
    fn next_u32(&mut self) -> u32 {
        let tmp = self.x ^ (self.x << 11);
        self.x = self.y;
        self.y = self.z;
        self.z = self.w;
        self.w = self.w ^ (self.w >> 19) ^ tmp ^ (tmp >> 8);
        return self.w;
    }
}

impl FastRand {
    pub fn new() -> FastRand {
        FastRand {
            x : 0x1d2acd47,
            y : 0x58ca3e14,
            z : 0xf563f232,
            w : 0x0bc76199,
        }
    }

    #[inline]
    pub fn next_less_than(&mut self, range : u32) -> u32 {
        self.next_u32() % range
    }

    #[inline]
    pub fn next_double(&mut self, range : f64) -> f64 {
        use std::u32;
        self.next_u32() as f64 * range / (u32::MAX as f64)
    }
}

#[inline]
pub fn div(a : i32, b: i32) -> i32 {
    if b == 0 { return i32::MAX }
    if a == i32::MIN && b == -1 {
        return i32::MAX;
    }
    return a / b;
}

#[inline]
pub fn modulus(a : i32, b: i32) -> i32 {
    if b == 0 { return i32::MAX }
    if a == i32::MIN && b == -1 {
        return i32::MAX;
    }
    return a % b;
}

pub static WORDS : [&'static str, .. 13] = [
    "foo ", "bar ", "baz ", "qux ", "quux ", "corge ", "grault ", "garply ", "waldo ", "fred ",
    "plugh ", "xyzzy ", "thud "];

<|endoftext|>


<commit_before>// Issue #66530: We would ICE if someone compiled with `-o /dev/null`,
// because we would try to generate auxiliary files in `/dev/` (which
// at least the OS X file system rejects).
//
// An attempt to `-o` into a directory we cannot write into should indeed
// be an error; but not an ICE.

// compile-flags: -o /dev/null

// The error-pattern check occurs *before* normalization, and the error patterns
// are wildly different between build environments. So this is a cop-out (and we
// rely on the checking of the normalized stderr output as our actual
// "verification" of the diagnostic).

// error-pattern: error

// On Mac OS X, we get an error like the below
// normalize-stderr-test "failed to write bytecode to /dev/null.non_ice_error_on_worker_io_fail.*" -> "io error modifying /dev/"

// On Linux, we get an error like the below
// normalize-stderr-test "couldn't create a temp dir.*" -> "io error modifying /dev/"

// ignore-tidy-linelength
// ignore-windows - this is a unix-specific test
// ignore-emscripten - the file-system issues do not replicate here
// ignore-wasm - the file-system issues do not replicate here

#![crate_type="lib"]

#![cfg_attr(not(feature = "std"), no_std)]
pub mod task {
    pub mod __internal {
        use crate::task::Waker;
    }
    pub use core::task::Waker;
}
<commit_msg>Keep plugging holes in the test to placate CI.<commit_after>// Issue #66530: We would ICE if someone compiled with `-o /dev/null`,
// because we would try to generate auxiliary files in `/dev/` (which
// at least the OS X file system rejects).
//
// An attempt to `-o` into a directory we cannot write into should indeed
// be an error; but not an ICE.

// compile-flags: -o /dev/null

// The error-pattern check occurs *before* normalization, and the error patterns
// are wildly different between build environments. So this is a cop-out (and we
// rely on the checking of the normalized stderr output as our actual
// "verification" of the diagnostic).

// error-pattern: error

// On Mac OS X, we get an error like the below
// normalize-stderr-test "failed to write bytecode to /dev/null.non_ice_error_on_worker_io_fail.*" -> "io error modifying /dev/"

// On Linux, we get an error like the below
// normalize-stderr-test "couldn't create a temp dir.*" -> "io error modifying /dev/"

// ignore-tidy-linelength
// ignore-windows - this is a unix-specific test
// ignore-emscripten - the file-system issues do not replicate here
// ignore-wasm - the file-system issues do not replicate here
// ignore-arm - the file-system issues do not replicate here, at least on armhf-gnu

#![crate_type="lib"]

#![cfg_attr(not(feature = "std"), no_std)]
pub mod task {
    pub mod __internal {
        use crate::task::Waker;
    }
    pub use core::task::Waker;
}
<|endoftext|>