<commit_before>#[macro_use]
extern crate log;

extern crate abstract_ns;
extern crate futures;
extern crate getopts;
extern crate ns_dns_tokio;
extern crate rand;
extern crate tokio_core;
extern crate tokio_io;

// the device under test
extern crate net_interceptor;

use abstract_ns::Resolver;
use futures::{Future, Map, Stream, Async, Poll};
use futures::future;
use futures::sync::oneshot;
use futures::sync::oneshot::{Sender};
use ns_dns_tokio::DnsResolver;
use tokio_core::net::{TcpStream, TcpListener};
use tokio_core::reactor::{Core, Handle};
use tokio_io::{AsyncRead, io};

use std::net::{IpAddr, Ipv4Addr, SocketAddr};
use std::fmt::{Debug, Display};
use std::time::{Duration};

use std::io::Error;

use net_interceptor::logging::unittestlogger;

fn add_ten<F>(future: F) -> Map<F, fn(i32) -> i32>
    where F: Future<Item=i32>,
{
    error!("shutdown");
    fn add(a: i32) -> i32 { a + 10 }
    future.map(add)
}

pub struct AbortCondition {
    condition: bool,
    reactor_handle: futures::task::Task,
}

#[derive(Copy, Clone)]
pub struct Releaser {
    block: *const AbortCondition
}

impl AbortCondition {

    fn set(&mut self) {
        debug!("abort condition met");
        self.condition = true;
        self.reactor_handle.unpark();
    }

}

impl Future for AbortCondition {

    type Item = ();
    type Error = Error;

    fn poll(&mut self) -> Poll<(), Error> {
        if  self.condition {
            Ok(Async::Ready(()))
        } else {
            self.reactor_handle = futures::task::park();
            Ok(Async::NotReady)
        }
    }

}
/*
#[derive(Clone)]
pub struct Stopper {
    signal: futures::sync::oneshot::Sender<i64>,
}

impl Stopper {

    pub fn stop(&mut self) {
        self.signal = 1;
    }

}
*/

/*impl Copy for Abort {
    fn clone(&self) -> Abort {
        *self
    }
}
*/
// Here we'll express the handling of `client` and return it as a future
// to be spawned onto the event loop.
/*fn process(client: TcpStream) -> Box<Future<Item = (i64), Error = error>> {
    warn!("received");
    Box::new(futures::future::ok(0));
}
*/
#[test]
fn test_infra_connect() {
    unittestlogger();

    // this is the main event loop, powered by tokio core
    let mut core = Core::new().unwrap();
    let handle = core.handle();

    let bind_socket_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 12000);
    let listener = TcpListener::bind(&bind_socket_addr, &handle)
        .expect(&format!("Unable to bind to {}", &bind_socket_addr));
    warn!("Listening on {}", listener.local_addr().unwrap());

    let addr = listener.local_addr().unwrap();
    assert!(addr.port() == 12000, "should accept {}");

//    let mut abort = AbortCondition { condition: false, reactor_handle: futures::task::park() };

    let connections = listener.incoming();
    let (tx, stop) = oneshot::channel();
//    let mut stopper = Stopper { signal: tx };
    let server = connections.for_each(move |(socket, _peer_addr)| {
        warn!("connection received");
        /*let (writer, reader) = socket.framed(LineCodec).split();
        let service = s.new_service()?;

        let responses = reader.and_then(move |req| service.call(req));
        let server = writer.send_all(responses)
            .then(|_| Ok(()));
        handle.spawn(server);
        */
//        tx.send(1);
//        tx.send(1).unwrap();
//        abort.set();
        Ok(())
    });

    core.handle().spawn(server.map_err(|_|()));

    fn abortCondition() -> futures::Poll<(), std::io::Error> {
        warn!("poll");
        if true {
            Ok(Async::Ready(()))
        }
        else {
            futures::task::park().unpark();
            Ok(Async::NotReady)
        }
    }

    //let abort = futures::future::poll_fn(abortCondition);

    //let timeout = tokio_core::reactor::Timeout::new_at(std::time::Duration::seconds(1));
    // run server, stop on panic
//    core.run(server.select2(timeout)).unwrap();
//    core.run(abort).unwrap();
    // core.spawn(server);
//    core.run(server.select(abort)).unwrap();
    core.run(stop).unwrap();

    // dummy
    tx.send(1);
}
<commit_msg>broken!<commit_after>#[macro_use]
extern crate log;

extern crate abstract_ns;
extern crate futures;
extern crate getopts;
extern crate ns_dns_tokio;
extern crate rand;
extern crate tokio_core;
extern crate tokio_io;

// the device under test
extern crate net_interceptor;

use abstract_ns::Resolver;
use futures::{Future, Map, Stream, Async, Poll};
use futures::future;
use futures::sync::oneshot;
use futures::sync::oneshot::{Sender};
use ns_dns_tokio::DnsResolver;
use tokio_core::net::{TcpStream, TcpListener};
use tokio_core::reactor::{Core, Handle};
use tokio_io::{AsyncRead, io};

use std::net::{IpAddr, Ipv4Addr, SocketAddr};
use std::fmt::{Debug, Display};
use std::time::{Duration};
use std::sync::{Arc, Mutex};
use std::thread;

use std::io::Error;
use std::ops::Deref;
use std::ops::DerefMut;
use std::borrow::BorrowMut;

use net_interceptor::logging::unittestlogger;

fn add_ten<F>(future: F) -> Map<F, fn(i32) -> i32>
    where F: Future<Item=i32>,
{
    error!("shutdown");
    fn add(a: i32) -> i32 { a + 10 }
    future.map(add)
}

pub struct AbortCondition {
    condition: bool,
    reactor_handle: futures::task::Task,
}

#[derive(Copy, Clone)]
pub struct Releaser {
    block: *const AbortCondition
}

impl AbortCondition {

    fn set(&mut self) {
        debug!("abort condition met");
        self.condition = true;
        self.reactor_handle.unpark();
    }

}

impl Future for AbortCondition {

    type Item = ();
    type Error = Error;

    fn poll(&mut self) -> Poll<(), Error> {
        if  self.condition {
            Ok(Async::Ready(()))
        } else {
            self.reactor_handle = futures::task::park();
            Ok(Async::NotReady)
        }
    }

}

pub struct Stopper {
    sender: Sender<i64>,
}

impl Stopper {

    pub fn stop(&mut self) {
        //self.sender.send(1).unwrap();
    }

}

/*impl Copy for Abort {
    fn clone(&self) -> Abort {
        *self
    }
}
*/
// Here we'll express the handling of `client` and return it as a future
// to be spawned onto the event loop.
/*fn process(client: TcpStream) -> Box<Future<Item = (i64), Error = error>> {
    warn!("received");
    Box::new(futures::future::ok(0));
}
*/
fn blank() -> Result<(), std::io::Error> {
    warn!("blank");
    Ok(())
}

fn direct(stopper: & mut Option<Sender<i64>>) -> Result<(), std::io::Error> {
    warn!("connection received");
//    let mut s = Box::borrow_mut(stopper);
    let mut s : Sender<i64> = stopper.unwrap();
    s.send(1).unwrap();
    Ok(())
}

fn stopper(sender: Sender<i64>) -> Arc<Mutex> {
    let counting = Arc::new(Mutex::new(0));
    thread::spawn(move |sender| {
        debug!("waiting for end")
        let mut num = sender.lock().unwrap();
        debug!("signalling end");
        sender.send(1).unwrap();
    });
    counting
}

#[test]
fn test_infra_connect() {
    unittestlogger();

    // this is the main event loop, powered by tokio core
    let mut core = Core::new().unwrap();
    let handle = core.handle();

    let bind_socket_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 12000);
    let listener = TcpListener::bind(&bind_socket_addr, &handle)
        .expect(&format!("Unable to bind to {}", &bind_socket_addr));
    warn!("Listening on {}", listener.local_addr().unwrap());

    let addr = listener.local_addr().unwrap();
    assert!(addr.port() == 12000, "should accept {}");

//    let mut abort = AbortCondition { condition: false, reactor_handle: futures::task::park() };

    let connections = listener.incoming();
    let (tx, signal) = oneshot::channel::<i64>();

//    let stopper = Arc::new(tx);
    let mut boxed = Some(tx);
    {

    //        let copy = Arc::clone(&stopper);
            //let server = connections.for_each(move |(socket, _peer_addr)| fx(&stopper));
        let server = connections.for_each(move |(socket, _peer_addr)| direct(& mut boxed));
        let wait = core.handle().spawn(server.map_err(|_|()));

    }

    fn abortCondition() -> futures::Poll<(), std::io::Error> {
        warn!("poll");
        if true {
            Ok(Async::Ready(()))
        }
        else {
            futures::task::park().unpark();
            Ok(Async::NotReady)
        }
    }

    //let abort = futures::future::poll_fn(abortCondition);

    //let timeout = tokio_core::reactor::Timeout::new_at(std::time::Duration::seconds(1));
    // run server, stop on panic
//    core.run(server.select2(timeout)).unwrap();
//    core.run(abort).unwrap();
    // core.spawn(server);
//    core.run(server.select(abort)).unwrap();
    core.run(signal).unwrap();
}
<|endoftext|>


<commit_before>extern crate inkwell;

use self::inkwell::context::Context;
use self::inkwell::targets::{InitializationConfig, Target};

use std::ptr::null;
use std::mem::transmute;

#[test]
fn test_build_call() {
    let context = Context::create();
    let module = context.create_module("sum");
    let builder = context.create_builder();

    let f32_type = context.f32_type();
    let fn_type = f32_type.fn_type(&[], false);

    let function = module.add_function("get_pi", &fn_type, None);
    let basic_block = context.append_basic_block(&function, "entry");

    builder.position_at_end(&basic_block);

    let pi = f32_type.const_float(::std::f64::consts::PI);

    builder.build_return(Some(&pi));

    let function2 = module.add_function("wrapper", &fn_type, None);
    let basic_block2 = context.append_basic_block(&function2, "entry");

    builder.position_at_end(&basic_block2);

    let pi2 = builder.build_call(&function, &[], "get_pi", false).left().unwrap();

    builder.build_return(Some(&pi2));
}

#[test]
fn test_null_checked_ptr_ops() {
    Target::initialize_native(&InitializationConfig::default()).expect("Failed to initialize native target");

    let context = Context::create();
    let module = context.create_module("unsafe");
    let builder = context.create_builder();
    let execution_engine = module.create_jit_execution_engine(0).unwrap();
    let module = execution_engine.get_module_at(0);

    // Here we're going to create a function that looks roughly like:
    // fn check_null_index1(ptr: *const i8) -> i8 {
    //     if ptr.is_null() {
    //         -1
    //     } else {
    //         ptr[1]
    //     }
    // }

    let i8_type = context.i8_type();
    let i8_ptr_type = i8_type.ptr_type(0);
    let i64_type = context.i64_type();
    let fn_type = i8_type.fn_type(&[&i8_ptr_type], false);
    let neg_one = i8_type.const_all_ones();
    let one = i64_type.const_int(1, false);

    let function = module.add_function("check_null_index1", &fn_type, None);
    let entry = context.append_basic_block(&function, "entry");

    builder.position_at_end(&entry);

    let ptr = function.get_first_param().unwrap().into_pointer_value();

    let is_null = builder.build_is_null(&ptr, "is_null");

    let ret_0 = function.append_basic_block("ret_0");
    let ret_idx = function.append_basic_block("ret_idx");

    builder.build_conditional_branch(&is_null, &ret_0, &ret_idx);

    builder.position_at_end(&ret_0);
    builder.build_return(Some(&neg_one));

    builder.position_at_end(&ret_idx);

    // FIXME: This might not work if compiled on non 64bit devices. Ideally we'd
    // be able to create pointer sized ints easily
    let ptr_as_int = builder.build_ptr_to_int(&ptr, &i64_type, "ptr_as_int");
    let new_ptr_as_int = builder.build_int_add(&ptr_as_int, &one, "add");
    let new_ptr = builder.build_int_to_ptr(&new_ptr_as_int, &i8_ptr_type, "int_as_ptr");
    let index1 = builder.build_load(&new_ptr, "deref");

    builder.build_return(Some(&index1));

    let addr = execution_engine.get_function_address("check_null_index1").unwrap();

    let check_null_index1: extern "C" fn(*const i8) -> i8 = unsafe { transmute(addr) };

    assert_eq!(check_null_index1(null()), -1i8);

    let array = &[100i8, 42i8];

    assert_eq!(check_null_index1(array.as_ptr()), 42i8);
}

#[test]
fn test_binary_ops() {
    Target::initialize_native(&InitializationConfig::default()).expect("Failed to initialize native target");

    let context = Context::create();
    let module = context.create_module("unsafe");
    let builder = context.create_builder();
    let execution_engine = module.create_jit_execution_engine(0).unwrap();
    let module = execution_engine.get_module_at(0);

    // Here we're going to create an and function which looks roughly like:
    // fn and(left: bool, right: bool) -> bool {
    //     left && right
    // }

    let bool_type = context.bool_type();
    let fn_type = bool_type.fn_type(&[&bool_type, &bool_type], false);
    let fn_value = module.add_function("and", &fn_type, None);
    let entry = fn_value.append_basic_block("entry");

    builder.position_at_end(&entry);

    let left = fn_value.get_first_param().unwrap().into_int_value();
    let right = fn_value.get_last_param().unwrap().into_int_value();

    let and = builder.build_and(&left, &right, "and_op");

    builder.build_return(Some(&and));

    // Here we're going to create an or function which looks roughly like:
    // fn or(left: bool, right: bool) -> bool {
    //     left || right
    // }

    let fn_value = module.add_function("or", &fn_type, None);
    let entry = fn_value.append_basic_block("entry");

    builder.position_at_end(&entry);

    let left = fn_value.get_first_param().unwrap().into_int_value();
    let right = fn_value.get_last_param().unwrap().into_int_value();

    let or = builder.build_or(&left, &right, "or_op");

    builder.build_return(Some(&or));

    // Here we're going to create a xor function which looks roughly like:
    // fn xor(left: bool, right: bool) -> bool {
    //     left || right
    // }

    let fn_value = module.add_function("xor", &fn_type, None);
    let entry = fn_value.append_basic_block("entry");

    builder.position_at_end(&entry);

    let left = fn_value.get_first_param().unwrap().into_int_value();
    let right = fn_value.get_last_param().unwrap().into_int_value();

    let xor = builder.build_xor(&left, &right, "xor_op");

    builder.build_return(Some(&xor));

    let addr = execution_engine.get_function_address("and").unwrap();
    let and: extern "C" fn(bool, bool) -> bool = unsafe { transmute(addr) };
    let addr = execution_engine.get_function_address("or").unwrap();
    let or: extern "C" fn(bool, bool) -> bool = unsafe { transmute(addr) };
    let addr = execution_engine.get_function_address("xor").unwrap();
    let xor: extern "C" fn(bool, bool) -> bool = unsafe { transmute(addr) };

    assert!(!and(false, false));
    assert!(!and(true, false));
    assert!(!and(false, true));
    assert!(and(true, true));

    assert!(!or(false, false));
    assert!(or(true, false));
    assert!(or(false, true));
    assert!(or(true, true));

    assert!(!xor(false, false));
    assert!(xor(true, false));
    assert!(xor(false, true));
    assert!(!xor(true, true));
}

#[test]
fn test_switch() {
    Target::initialize_native(&InitializationConfig::default()).expect("Failed to initialize native target");

    let context = Context::create();
    let module = context.create_module("unsafe");
    let builder = context.create_builder();
    let execution_engine = module.create_jit_execution_engine(0).unwrap();
    let module = execution_engine.get_module_at(0);

    // Here we're going to create a function which looks roughly like:
    // fn switch(val: u8) -> u8 {
    //     if val == 0 {
    //         1
    //     } else if val == 42 {
    //         255
    //     } else {
    //         val * 2
    //     }
    // }

    let i8_type = context.i8_type();
    let fn_type = i8_type.fn_type(&[&i8_type], false);
    let fn_value = module.add_function("switch", &fn_type, None);
    let i8_zero = i8_type.const_int(0, false);
    let i8_one = i8_type.const_int(1, false);
    let i8_two = i8_type.const_int(2, false);
    let i8_42 = i8_type.const_int(42, false);
    let i8_255 = i8_type.const_int(255, false);
    let entry = fn_value.append_basic_block("entry");
    let check = fn_value.append_basic_block("check");
    let elif = fn_value.append_basic_block("elif");
    let else_ = fn_value.append_basic_block("else");
    let value = fn_value.get_first_param().unwrap().into_int_value();

    builder.position_at_end(&entry);
    builder.build_switch(&value, &else_, &[(&i8_zero, &check), (&i8_42, &elif)]);

    builder.position_at_end(&check);
    builder.build_return(Some(&i8_one));

    builder.position_at_end(&elif);
    builder.build_return(Some(&i8_255));

    builder.position_at_end(&else_);

    let double = builder.build_int_mul(&value, &i8_two, "double");

    builder.build_return(Some(&double));

    let addr = execution_engine.get_function_address("switch").unwrap();
    let switch: extern "C" fn(u8) -> u8 = unsafe { transmute(addr) };

    assert_eq!(switch(0), 1);
    assert_eq!(switch(1), 2);
    assert_eq!(switch(3), 6);
    assert_eq!(switch(10), 20);
    assert_eq!(switch(42), 255);
}

#[test]
fn test_bit_shifts() {
    Target::initialize_native(&InitializationConfig::default()).expect("Failed to initialize native target");

    let context = Context::create();
    let module = context.create_module("unsafe");
    let builder = context.create_builder();
    let execution_engine = module.create_jit_execution_engine(0).unwrap();
    let module = execution_engine.get_module_at(0);

    // Here we're going to create a function which looks roughly like:
    // fn left_shift(value: u8, bits: u8) -> u8 {
    //     value << bits
    // }
    let i8_type = context.i8_type();
    let fn_type = i8_type.fn_type(&[&i8_type, &i8_type], false);
    let fn_value = module.add_function("left_shift", &fn_type, None);
    let value = fn_value.get_first_param().unwrap().into_int_value();
    let bits = fn_value.get_nth_param(1).unwrap().into_int_value();

    let entry = fn_value.append_basic_block("entry");

    builder.position_at_end(&entry);

    let shift = builder.build_left_shift(&value, &bits, "shl");

    builder.build_return(Some(&shift));

    // Here we're going to create a function which looks roughly like:
    // fn right_shift(value: u8, bits: u8) -> u8 {
    //     value >> bits
    // }
    let fn_value = module.add_function("right_shift", &fn_type, None);
    let value = fn_value.get_first_param().unwrap().into_int_value();
    let bits = fn_value.get_nth_param(1).unwrap().into_int_value();

    let entry = fn_value.append_basic_block("entry");

    builder.position_at_end(&entry);

    let shift = builder.build_right_shift(&value, &bits, false, "shr");

    builder.build_return(Some(&shift));

    // Here we're going to create a function which looks roughly like:
    // fn right_shift(value: u8, bits: u8) -> u8 {
    //     value >> bits
    // }
    let fn_value = module.add_function("right_shift_sign_extend", &fn_type, None);
    let value = fn_value.get_first_param().unwrap().into_int_value();
    let bits = fn_value.get_nth_param(1).unwrap().into_int_value();

    let entry = fn_value.append_basic_block("entry");

    builder.position_at_end(&entry);

    let shift = builder.build_right_shift(&value, &bits, true, "shr");

    builder.build_return(Some(&shift));

    let addr = execution_engine.get_function_address("left_shift").unwrap();
    let left_shift: extern "C" fn(u8, u8) -> u8 = unsafe { transmute(addr) };
    let addr = execution_engine.get_function_address("right_shift").unwrap();
    let right_shift: extern "C" fn(u8, u8) -> u8 = unsafe { transmute(addr) };
    let addr = execution_engine.get_function_address("right_shift_sign_extend").unwrap();
    let right_shift_sign_extend: extern "C" fn(i8, u8) -> i8 = unsafe { transmute(addr) };

    assert_eq!(left_shift(0, 0), 0);
    assert_eq!(left_shift(0, 4), 0);
    assert_eq!(left_shift(1, 0), 1);
    assert_eq!(left_shift(1, 1), 2);
    assert_eq!(left_shift(1, 2), 4);
    assert_eq!(left_shift(1, 3), 8);
    assert_eq!(left_shift(64, 1), 128);

    assert_eq!(right_shift(128, 1), 64);
    assert_eq!(right_shift(8, 3), 1);
    assert_eq!(right_shift(4, 2), 1);
    assert_eq!(right_shift(2, 1), 1);
    assert_eq!(right_shift(1, 0), 1);
    assert_eq!(right_shift(0, 4), 0);
    assert_eq!(right_shift(0, 0), 0);

    assert_eq!(right_shift_sign_extend(8, 3), 1);
    assert_eq!(right_shift_sign_extend(4, 2), 1);
    assert_eq!(right_shift_sign_extend(2, 1), 1);
    assert_eq!(right_shift_sign_extend(1, 0), 1);
    assert_eq!(right_shift_sign_extend(0, 4), 0);
    assert_eq!(right_shift_sign_extend(0, 0), 0);
    assert_eq!(right_shift_sign_extend(-127, 1), -64);
    assert_eq!(right_shift_sign_extend(-127, 8), -1);
    assert_eq!(right_shift_sign_extend(-65, 3), -9);
    assert_eq!(right_shift_sign_extend(-64, 3), -8);
    assert_eq!(right_shift_sign_extend(-63, 3), -8);
}
<commit_msg>Tiny test for creating global Builder instance<commit_after>extern crate inkwell;

use self::inkwell::context::Context;
use self::inkwell::builder::Builder;
use self::inkwell::targets::{InitializationConfig, Target};

use std::ptr::null;
use std::mem::transmute;

#[test]
fn test_build_call() {
    let context = Context::create();
    let module = context.create_module("sum");
    let builder = context.create_builder();

    let f32_type = context.f32_type();
    let fn_type = f32_type.fn_type(&[], false);

    let function = module.add_function("get_pi", &fn_type, None);
    let basic_block = context.append_basic_block(&function, "entry");

    builder.position_at_end(&basic_block);

    let pi = f32_type.const_float(::std::f64::consts::PI);

    builder.build_return(Some(&pi));

    let function2 = module.add_function("wrapper", &fn_type, None);
    let basic_block2 = context.append_basic_block(&function2, "entry");

    builder.position_at_end(&basic_block2);

    let pi2 = builder.build_call(&function, &[], "get_pi", false).left().unwrap();

    builder.build_return(Some(&pi2));
}

#[test]
fn test_null_checked_ptr_ops() {
    Target::initialize_native(&InitializationConfig::default()).expect("Failed to initialize native target");

    let context = Context::create();
    let module = context.create_module("unsafe");
    let builder = context.create_builder();
    let execution_engine = module.create_jit_execution_engine(0).unwrap();
    let module = execution_engine.get_module_at(0);

    // Here we're going to create a function that looks roughly like:
    // fn check_null_index1(ptr: *const i8) -> i8 {
    //     if ptr.is_null() {
    //         -1
    //     } else {
    //         ptr[1]
    //     }
    // }

    let i8_type = context.i8_type();
    let i8_ptr_type = i8_type.ptr_type(0);
    let i64_type = context.i64_type();
    let fn_type = i8_type.fn_type(&[&i8_ptr_type], false);
    let neg_one = i8_type.const_all_ones();
    let one = i64_type.const_int(1, false);

    let function = module.add_function("check_null_index1", &fn_type, None);
    let entry = context.append_basic_block(&function, "entry");

    builder.position_at_end(&entry);

    let ptr = function.get_first_param().unwrap().into_pointer_value();

    let is_null = builder.build_is_null(&ptr, "is_null");

    let ret_0 = function.append_basic_block("ret_0");
    let ret_idx = function.append_basic_block("ret_idx");

    builder.build_conditional_branch(&is_null, &ret_0, &ret_idx);

    builder.position_at_end(&ret_0);
    builder.build_return(Some(&neg_one));

    builder.position_at_end(&ret_idx);

    // FIXME: This might not work if compiled on non 64bit devices. Ideally we'd
    // be able to create pointer sized ints easily
    let ptr_as_int = builder.build_ptr_to_int(&ptr, &i64_type, "ptr_as_int");
    let new_ptr_as_int = builder.build_int_add(&ptr_as_int, &one, "add");
    let new_ptr = builder.build_int_to_ptr(&new_ptr_as_int, &i8_ptr_type, "int_as_ptr");
    let index1 = builder.build_load(&new_ptr, "deref");

    builder.build_return(Some(&index1));

    let addr = execution_engine.get_function_address("check_null_index1").unwrap();

    let check_null_index1: extern "C" fn(*const i8) -> i8 = unsafe { transmute(addr) };

    assert_eq!(check_null_index1(null()), -1i8);

    let array = &[100i8, 42i8];

    assert_eq!(check_null_index1(array.as_ptr()), 42i8);
}

#[test]
fn test_binary_ops() {
    Target::initialize_native(&InitializationConfig::default()).expect("Failed to initialize native target");

    let context = Context::create();
    let module = context.create_module("unsafe");
    let builder = context.create_builder();
    let execution_engine = module.create_jit_execution_engine(0).unwrap();
    let module = execution_engine.get_module_at(0);

    // Here we're going to create an and function which looks roughly like:
    // fn and(left: bool, right: bool) -> bool {
    //     left && right
    // }

    let bool_type = context.bool_type();
    let fn_type = bool_type.fn_type(&[&bool_type, &bool_type], false);
    let fn_value = module.add_function("and", &fn_type, None);
    let entry = fn_value.append_basic_block("entry");

    builder.position_at_end(&entry);

    let left = fn_value.get_first_param().unwrap().into_int_value();
    let right = fn_value.get_last_param().unwrap().into_int_value();

    let and = builder.build_and(&left, &right, "and_op");

    builder.build_return(Some(&and));

    // Here we're going to create an or function which looks roughly like:
    // fn or(left: bool, right: bool) -> bool {
    //     left || right
    // }

    let fn_value = module.add_function("or", &fn_type, None);
    let entry = fn_value.append_basic_block("entry");

    builder.position_at_end(&entry);

    let left = fn_value.get_first_param().unwrap().into_int_value();
    let right = fn_value.get_last_param().unwrap().into_int_value();

    let or = builder.build_or(&left, &right, "or_op");

    builder.build_return(Some(&or));

    // Here we're going to create a xor function which looks roughly like:
    // fn xor(left: bool, right: bool) -> bool {
    //     left || right
    // }

    let fn_value = module.add_function("xor", &fn_type, None);
    let entry = fn_value.append_basic_block("entry");

    builder.position_at_end(&entry);

    let left = fn_value.get_first_param().unwrap().into_int_value();
    let right = fn_value.get_last_param().unwrap().into_int_value();

    let xor = builder.build_xor(&left, &right, "xor_op");

    builder.build_return(Some(&xor));

    let addr = execution_engine.get_function_address("and").unwrap();
    let and: extern "C" fn(bool, bool) -> bool = unsafe { transmute(addr) };
    let addr = execution_engine.get_function_address("or").unwrap();
    let or: extern "C" fn(bool, bool) -> bool = unsafe { transmute(addr) };
    let addr = execution_engine.get_function_address("xor").unwrap();
    let xor: extern "C" fn(bool, bool) -> bool = unsafe { transmute(addr) };

    assert!(!and(false, false));
    assert!(!and(true, false));
    assert!(!and(false, true));
    assert!(and(true, true));

    assert!(!or(false, false));
    assert!(or(true, false));
    assert!(or(false, true));
    assert!(or(true, true));

    assert!(!xor(false, false));
    assert!(xor(true, false));
    assert!(xor(false, true));
    assert!(!xor(true, true));
}

#[test]
fn test_switch() {
    Target::initialize_native(&InitializationConfig::default()).expect("Failed to initialize native target");

    let context = Context::create();
    let module = context.create_module("unsafe");
    let builder = context.create_builder();
    let execution_engine = module.create_jit_execution_engine(0).unwrap();
    let module = execution_engine.get_module_at(0);

    // Here we're going to create a function which looks roughly like:
    // fn switch(val: u8) -> u8 {
    //     if val == 0 {
    //         1
    //     } else if val == 42 {
    //         255
    //     } else {
    //         val * 2
    //     }
    // }

    let i8_type = context.i8_type();
    let fn_type = i8_type.fn_type(&[&i8_type], false);
    let fn_value = module.add_function("switch", &fn_type, None);
    let i8_zero = i8_type.const_int(0, false);
    let i8_one = i8_type.const_int(1, false);
    let i8_two = i8_type.const_int(2, false);
    let i8_42 = i8_type.const_int(42, false);
    let i8_255 = i8_type.const_int(255, false);
    let entry = fn_value.append_basic_block("entry");
    let check = fn_value.append_basic_block("check");
    let elif = fn_value.append_basic_block("elif");
    let else_ = fn_value.append_basic_block("else");
    let value = fn_value.get_first_param().unwrap().into_int_value();

    builder.position_at_end(&entry);
    builder.build_switch(&value, &else_, &[(&i8_zero, &check), (&i8_42, &elif)]);

    builder.position_at_end(&check);
    builder.build_return(Some(&i8_one));

    builder.position_at_end(&elif);
    builder.build_return(Some(&i8_255));

    builder.position_at_end(&else_);

    let double = builder.build_int_mul(&value, &i8_two, "double");

    builder.build_return(Some(&double));

    let addr = execution_engine.get_function_address("switch").unwrap();
    let switch: extern "C" fn(u8) -> u8 = unsafe { transmute(addr) };

    assert_eq!(switch(0), 1);
    assert_eq!(switch(1), 2);
    assert_eq!(switch(3), 6);
    assert_eq!(switch(10), 20);
    assert_eq!(switch(42), 255);
}

#[test]
fn test_bit_shifts() {
    Target::initialize_native(&InitializationConfig::default()).expect("Failed to initialize native target");

    let context = Context::create();
    let module = context.create_module("unsafe");
    let builder = context.create_builder();
    let execution_engine = module.create_jit_execution_engine(0).unwrap();
    let module = execution_engine.get_module_at(0);

    // Here we're going to create a function which looks roughly like:
    // fn left_shift(value: u8, bits: u8) -> u8 {
    //     value << bits
    // }
    let i8_type = context.i8_type();
    let fn_type = i8_type.fn_type(&[&i8_type, &i8_type], false);
    let fn_value = module.add_function("left_shift", &fn_type, None);
    let value = fn_value.get_first_param().unwrap().into_int_value();
    let bits = fn_value.get_nth_param(1).unwrap().into_int_value();

    let entry = fn_value.append_basic_block("entry");

    builder.position_at_end(&entry);

    let shift = builder.build_left_shift(&value, &bits, "shl");

    builder.build_return(Some(&shift));

    // Here we're going to create a function which looks roughly like:
    // fn right_shift(value: u8, bits: u8) -> u8 {
    //     value >> bits
    // }
    let fn_value = module.add_function("right_shift", &fn_type, None);
    let value = fn_value.get_first_param().unwrap().into_int_value();
    let bits = fn_value.get_nth_param(1).unwrap().into_int_value();

    let entry = fn_value.append_basic_block("entry");

    builder.position_at_end(&entry);

    let shift = builder.build_right_shift(&value, &bits, false, "shr");

    builder.build_return(Some(&shift));

    // Here we're going to create a function which looks roughly like:
    // fn right_shift(value: u8, bits: u8) -> u8 {
    //     value >> bits
    // }
    let fn_value = module.add_function("right_shift_sign_extend", &fn_type, None);
    let value = fn_value.get_first_param().unwrap().into_int_value();
    let bits = fn_value.get_nth_param(1).unwrap().into_int_value();

    let entry = fn_value.append_basic_block("entry");

    builder.position_at_end(&entry);

    let shift = builder.build_right_shift(&value, &bits, true, "shr");

    builder.build_return(Some(&shift));

    let addr = execution_engine.get_function_address("left_shift").unwrap();
    let left_shift: extern "C" fn(u8, u8) -> u8 = unsafe { transmute(addr) };
    let addr = execution_engine.get_function_address("right_shift").unwrap();
    let right_shift: extern "C" fn(u8, u8) -> u8 = unsafe { transmute(addr) };
    let addr = execution_engine.get_function_address("right_shift_sign_extend").unwrap();
    let right_shift_sign_extend: extern "C" fn(i8, u8) -> i8 = unsafe { transmute(addr) };

    assert_eq!(left_shift(0, 0), 0);
    assert_eq!(left_shift(0, 4), 0);
    assert_eq!(left_shift(1, 0), 1);
    assert_eq!(left_shift(1, 1), 2);
    assert_eq!(left_shift(1, 2), 4);
    assert_eq!(left_shift(1, 3), 8);
    assert_eq!(left_shift(64, 1), 128);

    assert_eq!(right_shift(128, 1), 64);
    assert_eq!(right_shift(8, 3), 1);
    assert_eq!(right_shift(4, 2), 1);
    assert_eq!(right_shift(2, 1), 1);
    assert_eq!(right_shift(1, 0), 1);
    assert_eq!(right_shift(0, 4), 0);
    assert_eq!(right_shift(0, 0), 0);

    assert_eq!(right_shift_sign_extend(8, 3), 1);
    assert_eq!(right_shift_sign_extend(4, 2), 1);
    assert_eq!(right_shift_sign_extend(2, 1), 1);
    assert_eq!(right_shift_sign_extend(1, 0), 1);
    assert_eq!(right_shift_sign_extend(0, 4), 0);
    assert_eq!(right_shift_sign_extend(0, 0), 0);
    assert_eq!(right_shift_sign_extend(-127, 1), -64);
    assert_eq!(right_shift_sign_extend(-127, 8), -1);
    assert_eq!(right_shift_sign_extend(-65, 3), -9);
    assert_eq!(right_shift_sign_extend(-64, 3), -8);
    assert_eq!(right_shift_sign_extend(-63, 3), -8);
}

#[test]
fn test_global_builder() {
    // Unfortunately LLVM doesn't provide us with a get_context method like it does for
    // modules and types, so we can't assert it actualy is of the same global context...
    Builder::create();
}
<|endoftext|>


<commit_before>use std::fmt::Display;
use thiserror::Error;

fn assert<T: Display>(expected: &str, value: T) {
    assert_eq!(expected, value.to_string());
}

#[test]
fn test_braced() {
    #[derive(Error, Debug)]
    #[error("braced error: {msg}")]
    struct Error {
        msg: String,
    }

    let msg = "T".to_owned();
    assert("braced error: T", Error { msg });
}

#[test]
fn test_braced_unused() {
    #[derive(Error, Debug)]
    #[error("braced error")]
    struct Error {
        extra: usize,
    }

    assert("braced error", Error { extra: 0 });
}

#[test]
fn test_tuple() {
    #[derive(Error, Debug)]
    #[error("tuple error: {0}")]
    struct Error(usize);

    assert("tuple error: 0", Error(0));
}

#[test]
fn test_unit() {
    #[derive(Error, Debug)]
    #[error("unit error")]
    struct Error;

    assert("unit error", Error);
}

#[test]
fn test_enum() {
    #[derive(Error, Debug)]
    enum Error {
        #[error("braced error: {id}")]
        Braced { id: usize },
        #[error("tuple error: {0}")]
        Tuple(usize),
        #[error("unit error")]
        Unit,
    }

    assert("braced error: 0", Error::Braced { id: 0 });
    assert("tuple error: 0", Error::Tuple(0));
    assert("unit error", Error::Unit);
}

#[test]
fn test_constants() {
    #[derive(Error, Debug)]
    #[error("{MSG}: {id:?} (code {CODE:?})")]
    struct Error {
        id: &'static str,
    }

    const MSG: &str = "failed to do";
    const CODE: usize = 9;

    assert("failed to do: \"\" (code 9)", Error { id: "" });
}

#[test]
fn test_inherit() {
    #[derive(Error, Debug)]
    #[error("{0}")]
    enum Error {
        Some(&'static str),
        #[error("other error")]
        Other(&'static str),
    }

    assert("some error", Error::Some("some error"));
    assert("other error", Error::Other("..."));
}

#[test]
fn test_brace_escape() {
    #[derive(Error, Debug)]
    #[error("fn main() {{}}")]
    struct Error;

    assert("fn main() {}", Error);
}

#[test]
fn test_expr() {
    #[derive(Error, Debug)]
    #[error("1 + 1 = {}", 1 + 1)]
    struct Error;
    assert("1 + 1 = 2", Error);
}

#[test]
fn test_nested() {
    #[derive(Error, Debug)]
    #[error("!bool = {}", not(.0))]
    struct Error(bool);

    fn not(bool: &bool) -> bool {
        !*bool
    }

    assert("!bool = false", Error(true));
}

#[test]
fn test_match() {
    #[derive(Error, Debug)]
    #[error("{}: {0}", match .1 {
        Some(n) => format!("error occurred with {}", n),
        None => format!("there was an empty error"),
    })]
    struct Error(String, Option<usize>);

    assert(
        "error occurred with 1: ...",
        Error("...".to_owned(), Some(1)),
    );
    assert(
        "there was an empty error: ...",
        Error("...".to_owned(), None),
    );
}

#[test]
fn test_void() {
    #[derive(Error, Debug)]
    #[error("...")]
    pub enum Error {}
}

#[test]
fn test_mixed() {
    #[derive(Error, Debug)]
    #[error("a={a} :: b={} :: c={c} :: d={d}", 1, c = 2, d = 3)]
    struct Error {
        a: usize,
        d: usize,
    }

    assert("a=0 :: b=1 :: c=2 :: d=3", Error { a: 0, d: 0 });
}

#[test]
fn test_ints() {
    #[derive(Error, Debug)]
    enum Error {
        #[error("error {0}")]
        Tuple(usize, usize),
        #[error("error {0}", '?')]
        Struct { v: usize },
    }

    assert("error 9", Error::Tuple(9, 0));
    assert("error ?", Error::Struct { v: 0 });
}

#[test]
fn test_trailing_comma() {
    #[derive(Error, Debug)]
    #[error(
        "error {0}",
    )]
    #[rustfmt::skip]
    struct Error(char);

    assert("error ?", Error('?'));
}

#[test]
fn test_field() {
    #[derive(Debug)]
    struct Inner {
        data: usize,
    }

    #[derive(Error, Debug)]
    #[error("{}", .0.data)]
    struct Error(Inner);

    assert("0", Error(Inner { data: 0 }));
}
<commit_msg>Add failing regression test for issue 86<commit_after>use std::fmt::Display;
use thiserror::Error;

fn assert<T: Display>(expected: &str, value: T) {
    assert_eq!(expected, value.to_string());
}

#[test]
fn test_braced() {
    #[derive(Error, Debug)]
    #[error("braced error: {msg}")]
    struct Error {
        msg: String,
    }

    let msg = "T".to_owned();
    assert("braced error: T", Error { msg });
}

#[test]
fn test_braced_unused() {
    #[derive(Error, Debug)]
    #[error("braced error")]
    struct Error {
        extra: usize,
    }

    assert("braced error", Error { extra: 0 });
}

#[test]
fn test_tuple() {
    #[derive(Error, Debug)]
    #[error("tuple error: {0}")]
    struct Error(usize);

    assert("tuple error: 0", Error(0));
}

#[test]
fn test_unit() {
    #[derive(Error, Debug)]
    #[error("unit error")]
    struct Error;

    assert("unit error", Error);
}

#[test]
fn test_enum() {
    #[derive(Error, Debug)]
    enum Error {
        #[error("braced error: {id}")]
        Braced { id: usize },
        #[error("tuple error: {0}")]
        Tuple(usize),
        #[error("unit error")]
        Unit,
    }

    assert("braced error: 0", Error::Braced { id: 0 });
    assert("tuple error: 0", Error::Tuple(0));
    assert("unit error", Error::Unit);
}

#[test]
fn test_constants() {
    #[derive(Error, Debug)]
    #[error("{MSG}: {id:?} (code {CODE:?})")]
    struct Error {
        id: &'static str,
    }

    const MSG: &str = "failed to do";
    const CODE: usize = 9;

    assert("failed to do: \"\" (code 9)", Error { id: "" });
}

#[test]
fn test_inherit() {
    #[derive(Error, Debug)]
    #[error("{0}")]
    enum Error {
        Some(&'static str),
        #[error("other error")]
        Other(&'static str),
    }

    assert("some error", Error::Some("some error"));
    assert("other error", Error::Other("..."));
}

#[test]
fn test_brace_escape() {
    #[derive(Error, Debug)]
    #[error("fn main() {{}}")]
    struct Error;

    assert("fn main() {}", Error);
}

#[test]
fn test_expr() {
    #[derive(Error, Debug)]
    #[error("1 + 1 = {}", 1 + 1)]
    struct Error;
    assert("1 + 1 = 2", Error);
}

#[test]
fn test_nested() {
    #[derive(Error, Debug)]
    #[error("!bool = {}", not(.0))]
    struct Error(bool);

    fn not(bool: &bool) -> bool {
        !*bool
    }

    assert("!bool = false", Error(true));
}

#[test]
fn test_match() {
    #[derive(Error, Debug)]
    #[error("{}: {0}", match .1 {
        Some(n) => format!("error occurred with {}", n),
        None => format!("there was an empty error"),
    })]
    struct Error(String, Option<usize>);

    assert(
        "error occurred with 1: ...",
        Error("...".to_owned(), Some(1)),
    );
    assert(
        "there was an empty error: ...",
        Error("...".to_owned(), None),
    );
}

#[test]
fn test_void() {
    #[derive(Error, Debug)]
    #[error("...")]
    pub enum Error {}
}

#[test]
fn test_mixed() {
    #[derive(Error, Debug)]
    #[error("a={a} :: b={} :: c={c} :: d={d}", 1, c = 2, d = 3)]
    struct Error {
        a: usize,
        d: usize,
    }

    assert("a=0 :: b=1 :: c=2 :: d=3", Error { a: 0, d: 0 });
}

#[test]
fn test_ints() {
    #[derive(Error, Debug)]
    enum Error {
        #[error("error {0}")]
        Tuple(usize, usize),
        #[error("error {0}", '?')]
        Struct { v: usize },
    }

    assert("error 9", Error::Tuple(9, 0));
    assert("error ?", Error::Struct { v: 0 });
}

#[test]
fn test_trailing_comma() {
    #[derive(Error, Debug)]
    #[error(
        "error {0}",
    )]
    #[rustfmt::skip]
    struct Error(char);

    assert("error ?", Error('?'));
}

#[test]
fn test_field() {
    #[derive(Debug)]
    struct Inner {
        data: usize,
    }

    #[derive(Error, Debug)]
    #[error("{}", .0.data)]
    struct Error(Inner);

    assert("0", Error(Inner { data: 0 }));
}

#[test]
fn test_macro_rules() {
    // Regression test for https://github.com/dtolnay/thiserror/issues/86

    macro_rules! decl_error {
        ($variant:ident($value:ident)) => {
            #[derive(Debug, Error)]
            pub enum Error {
                #[error("{0:?}")]
                $variant($value),
            }
        };
    }

    decl_error!(Repro(u8));

    assert("0", Error::Repro(0));
}
<|endoftext|>


<commit_before>// https://github.com/colin-kiegel/rust-derive-builder/issues/15
#[macro_use]
extern crate pretty_assertions;
#[macro_use]
extern crate derive_builder;

#[derive(Debug, Clone, PartialEq)]
struct NotDefaultable(String);

fn new_notdefaultable() -> NotDefaultable {
    NotDefaultable("Lorem".to_string())
}

#[derive(Debug, PartialEq, Default, Builder, Clone)]
#[builder(setter(skip="false"))]
struct SetterOptOut {
    setter_present_by_explicit_default: u32,
    #[builder(setter(skip="true"))]
    setter_skipped_by_explicit_opt_out: u32,
    #[builder(setter(skip))]
    setter_skipped_by_shorthand_opt_out: u32,
    #[builder(setter(skip), default = "4")]
    setter_skipped_with_explicit_default: u32,
}

#[derive(Debug, PartialEq, Default, Builder, Clone)]
#[builder(setter(skip))]
struct SetterOptIn {
    setter_skipped_by_shorthand_default: u32,
    #[builder(setter(skip="false"))]
    setter_present_by_explicit_opt_in: u32,
    #[builder(setter)]
    setter_present_by_shorthand_opt_in: u32,
    #[builder(setter(prefix="set"))]
    setter_present_by_shorthand_opt_in_2: u32,
}

#[derive(Debug, PartialEq, Builder, Clone)]
#[builder(default, setter(skip))]
struct SetterOptInStructDefault {
    setter_skipped_with_struct_default: NotDefaultable,
    setter_skipped_with_type_default: u32,
}

#[derive(Debug, PartialEq, Builder, Clone)]
#[builder(setter(into))]
struct SetterOptInFieldDefault {
    #[builder(setter(skip), default = "new_notdefaultable()")]
    setter_skipped_with_field_default: NotDefaultable,

    #[builder(default)]
    setter_present_by_default: u32
}

// compile test
#[allow(dead_code)]
impl SetterOptOut {
    // only possible if setter was skipped
    fn setter_skipped_by_explicit_opt_out() {}
    // only possible if setter was skipped
    fn setter_skipped_by_shorthand_opt_out() {}
}

// compile test
#[allow(dead_code)]
impl SetterOptIn {
    // only possible if setter was skipped
    fn setter_skipped_by_shorthand_default() {}
}

impl Default for SetterOptInStructDefault {
    fn default() -> Self {
        SetterOptInStructDefault {
            setter_skipped_with_struct_default: new_notdefaultable(),
            setter_skipped_with_type_default: Default::default(),
        }
    }
}

#[test]
fn setter_opt_out() {
    let x: SetterOptOut =
        SetterOptOutBuilder::default().setter_present_by_explicit_default(42u32).build().unwrap();

    assert_eq!(x,
               SetterOptOut {
                   setter_present_by_explicit_default: 42,
                   setter_skipped_by_explicit_opt_out: 0,
                   setter_skipped_by_shorthand_opt_out: 0,
                   setter_skipped_with_explicit_default: 4,
               });
}

#[test]
fn setter_opt_in() {
    let x: SetterOptIn = SetterOptInBuilder::default()
        .setter_present_by_explicit_opt_in(47u32)
        .setter_present_by_shorthand_opt_in(11u32)
        .set_setter_present_by_shorthand_opt_in_2(815u32)
        .build()
        .unwrap();

    assert_eq!(x,
               SetterOptIn {
                   setter_skipped_by_shorthand_default: 0,
                   setter_present_by_explicit_opt_in: 47,
                   setter_present_by_shorthand_opt_in: 11,
                   setter_present_by_shorthand_opt_in_2: 815,
               });
}

#[test]
fn setter_skipped_with_struct_default() {
    let x = SetterOptInStructDefaultBuilder::default().build().unwrap();
    assert_eq!(x, SetterOptInStructDefault::default());
}

#[test]
fn setter_skipped_with_field_default() {
    let x = SetterOptInFieldDefaultBuilder::default().build().expect("All fields were defaulted");
    assert_eq!(x, SetterOptInFieldDefault {
        setter_skipped_with_field_default: new_notdefaultable(),
        setter_present_by_default: Default::default(),
    });
}<commit_msg>feature = "struct_default" guard to avoid broken tests<commit_after>// https://github.com/colin-kiegel/rust-derive-builder/issues/15
#[macro_use]
extern crate pretty_assertions;
#[macro_use]
extern crate derive_builder;

#[derive(Debug, Clone, PartialEq)]
struct NotDefaultable(String);

fn new_notdefaultable() -> NotDefaultable {
    NotDefaultable("Lorem".to_string())
}

#[derive(Debug, PartialEq, Default, Builder, Clone)]
#[builder(setter(skip="false"))]
struct SetterOptOut {
    setter_present_by_explicit_default: u32,
    #[builder(setter(skip="true"))]
    setter_skipped_by_explicit_opt_out: u32,
    #[builder(setter(skip))]
    setter_skipped_by_shorthand_opt_out: u32,
    #[builder(setter(skip), default = "4")]
    setter_skipped_with_explicit_default: u32,
}

#[derive(Debug, PartialEq, Default, Builder, Clone)]
#[builder(setter(skip))]
struct SetterOptIn {
    setter_skipped_by_shorthand_default: u32,
    #[builder(setter(skip="false"))]
    setter_present_by_explicit_opt_in: u32,
    #[builder(setter)]
    setter_present_by_shorthand_opt_in: u32,
    #[builder(setter(prefix="set"))]
    setter_present_by_shorthand_opt_in_2: u32,
}

#[cfg(feature = "struct_default")]
#[derive(Debug, PartialEq, Builder, Clone)]
#[builder(default, setter(skip))]
struct SetterOptInStructDefault {
    setter_skipped_with_struct_default: NotDefaultable,
    setter_skipped_with_type_default: u32,
}

#[derive(Debug, PartialEq, Builder, Clone)]
#[builder(setter(into))]
struct SetterOptInFieldDefault {
    #[builder(setter(skip), default = "new_notdefaultable()")]
    setter_skipped_with_field_default: NotDefaultable,

    #[builder(default)]
    setter_present_by_default: u32
}

// compile test
#[allow(dead_code)]
impl SetterOptOut {
    // only possible if setter was skipped
    fn setter_skipped_by_explicit_opt_out() {}
    // only possible if setter was skipped
    fn setter_skipped_by_shorthand_opt_out() {}
}

// compile test
#[allow(dead_code)]
impl SetterOptIn {
    // only possible if setter was skipped
    fn setter_skipped_by_shorthand_default() {}
}

#[cfg(feature = "struct_default")]
impl Default for SetterOptInStructDefault {
    fn default() -> Self {
        SetterOptInStructDefault {
            setter_skipped_with_struct_default: new_notdefaultable(),
            setter_skipped_with_type_default: Default::default(),
        }
    }
}

#[test]
fn setter_opt_out() {
    let x: SetterOptOut =
        SetterOptOutBuilder::default().setter_present_by_explicit_default(42u32).build().unwrap();

    assert_eq!(x,
               SetterOptOut {
                   setter_present_by_explicit_default: 42,
                   setter_skipped_by_explicit_opt_out: 0,
                   setter_skipped_by_shorthand_opt_out: 0,
                   setter_skipped_with_explicit_default: 4,
               });
}

#[test]
fn setter_opt_in() {
    let x: SetterOptIn = SetterOptInBuilder::default()
        .setter_present_by_explicit_opt_in(47u32)
        .setter_present_by_shorthand_opt_in(11u32)
        .set_setter_present_by_shorthand_opt_in_2(815u32)
        .build()
        .unwrap();

    assert_eq!(x,
               SetterOptIn {
                   setter_skipped_by_shorthand_default: 0,
                   setter_present_by_explicit_opt_in: 47,
                   setter_present_by_shorthand_opt_in: 11,
                   setter_present_by_shorthand_opt_in_2: 815,
               });
}

#[test]
#[cfg(feature = "struct_default")]
fn setter_skipped_with_struct_default() {
    let x = SetterOptInStructDefaultBuilder::default().build().unwrap();
    assert_eq!(x, SetterOptInStructDefault::default());
}

#[test]
fn setter_skipped_with_field_default() {
    let x = SetterOptInFieldDefaultBuilder::default().build().expect("All fields were defaulted");
    assert_eq!(x, SetterOptInFieldDefault {
        setter_skipped_with_field_default: new_notdefaultable(),
        setter_present_by_default: Default::default(),
    });
}<|endoftext|>


<commit_before>// Copyright 2012-2014 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.

// The crate store - a central repo for information collected about external
// crates and libraries

use schema;

use rustc::hir::def_id::{CRATE_DEF_INDEX, CrateNum, DefIndex};
use rustc::hir::map::definitions::DefPathTable;
use rustc::hir::svh::Svh;
use rustc::middle::cstore::{DepKind, ExternCrate, MetadataLoader};
use rustc::session::{Session, CrateDisambiguator};
use rustc_target::spec::PanicStrategy;
use rustc_data_structures::indexed_vec::IndexVec;
use rustc::util::nodemap::{FxHashMap, NodeMap};

use rustc_data_structures::sync::{Lrc, RwLock, Lock};
use syntax::{ast, attr};
use syntax::ext::base::SyntaxExtension;
use syntax::symbol::Symbol;
use syntax_pos;

pub use rustc::middle::cstore::{NativeLibrary, NativeLibraryKind, LinkagePreference};
pub use rustc::middle::cstore::NativeLibraryKind::*;
pub use rustc::middle::cstore::{CrateSource, LibSource, ForeignModule};

pub use cstore_impl::{provide, provide_extern};

// A map from external crate numbers (as decoded from some crate file) to
// local crate numbers (as generated during this session). Each external
// crate may refer to types in other external crates, and each has their
// own crate numbers.
pub type CrateNumMap = IndexVec<CrateNum, CrateNum>;

pub use rustc_data_structures::sync::MetadataRef;

pub struct MetadataBlob(pub MetadataRef);

/// Holds information about a syntax_pos::FileMap imported from another crate.
/// See `imported_filemaps()` for more information.
pub struct ImportedFileMap {
    /// This FileMap's byte-offset within the codemap of its original crate
    pub original_start_pos: syntax_pos::BytePos,
    /// The end of this FileMap within the codemap of its original crate
    pub original_end_pos: syntax_pos::BytePos,
    /// The imported FileMap's representation within the local codemap
    pub translated_filemap: Lrc<syntax_pos::FileMap>,
}

pub struct CrateMetadata {
    pub name: Symbol,

    /// Information about the extern crate that caused this crate to
    /// be loaded. If this is `None`, then the crate was injected
    /// (e.g., by the allocator)
    pub extern_crate: Lock<Option<ExternCrate>>,

    pub blob: MetadataBlob,
    pub cnum_map: Lock<CrateNumMap>,
    pub cnum: CrateNum,
    pub codemap_import_info: RwLock<Vec<ImportedFileMap>>,
    pub attribute_cache: Lock<[Vec<Option<Lrc<[ast::Attribute]>>>; 2]>,

    pub root: schema::CrateRoot,

    /// For each public item in this crate, we encode a key.  When the
    /// crate is loaded, we read all the keys and put them in this
    /// hashmap, which gives the reverse mapping.  This allows us to
    /// quickly retrace a `DefPath`, which is needed for incremental
    /// compilation support.
    pub def_path_table: Lrc<DefPathTable>,

    pub trait_impls: FxHashMap<(u32, DefIndex), schema::LazySeq<DefIndex>>,

    pub dep_kind: Lock<DepKind>,
    pub source: CrateSource,

    pub proc_macros: Option<Vec<(ast::Name, Lrc<SyntaxExtension>)>>,
}

pub struct CStore {
    metas: RwLock<IndexVec<CrateNum, Option<Lrc<CrateMetadata>>>>,
    /// Map from NodeId's of local extern crate statements to crate numbers
    extern_mod_crate_map: Lock<NodeMap<CrateNum>>,
    pub metadata_loader: Box<MetadataLoader + Sync>,
}

impl CStore {
    pub fn new(metadata_loader: Box<MetadataLoader + Sync>) -> CStore {
        CStore {
            metas: RwLock::new(IndexVec::new()),
            extern_mod_crate_map: Lock::new(FxHashMap()),
            metadata_loader,
        }
    }

    /// You cannot use this function to allocate a CrateNum in a thread-safe manner.
    /// It is currently only used in CrateLoader which is single-threaded code.
    pub fn next_crate_num(&self) -> CrateNum {
        CrateNum::new(self.metas.borrow().len() + 1)
    }

    pub fn get_crate_data(&self, cnum: CrateNum) -> Lrc<CrateMetadata> {
        self.metas.borrow()[cnum].clone().unwrap()
    }

    pub fn set_crate_data(&self, cnum: CrateNum, data: Lrc<CrateMetadata>) {
        use rustc_data_structures::indexed_vec::Idx;
        let mut met = self.metas.borrow_mut();
        while met.len() <= cnum.index() {
            met.push(None);
        }
        met[cnum] = Some(data);
    }

    pub fn iter_crate_data<I>(&self, mut i: I)
        where I: FnMut(CrateNum, &Lrc<CrateMetadata>)
    {
        for (k, v) in self.metas.borrow().iter_enumerated() {
            if let &Some(ref v) = v {
                i(k, v);
            }
        }
    }

    pub fn crate_dependencies_in_rpo(&self, krate: CrateNum) -> Vec<CrateNum> {
        let mut ordering = Vec::new();
        self.push_dependencies_in_postorder(&mut ordering, krate);
        ordering.reverse();
        ordering
    }

    pub fn push_dependencies_in_postorder(&self, ordering: &mut Vec<CrateNum>, krate: CrateNum) {
        if ordering.contains(&krate) {
            return;
        }

        let data = self.get_crate_data(krate);
        for &dep in data.cnum_map.borrow().iter() {
            if dep != krate {
                self.push_dependencies_in_postorder(ordering, dep);
            }
        }

        ordering.push(krate);
    }

    pub fn do_postorder_cnums_untracked(&self) -> Vec<CrateNum> {
        let mut ordering = Vec::new();
        for (num, v) in self.metas.borrow().iter_enumerated() {
            if let &Some(_) = v {
                self.push_dependencies_in_postorder(&mut ordering, num);
            }
        }
        return ordering
    }

    pub fn add_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId, cnum: CrateNum) {
        self.extern_mod_crate_map.borrow_mut().insert(emod_id, cnum);
    }

    pub fn do_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum> {
        self.extern_mod_crate_map.borrow().get(&emod_id).cloned()
    }
}

impl CrateMetadata {
    pub fn name(&self) -> Symbol {
        self.root.name
    }
    pub fn hash(&self) -> Svh {
        self.root.hash
    }
    pub fn disambiguator(&self) -> CrateDisambiguator {
        self.root.disambiguator
    }

    pub fn needs_allocator(&self, sess: &Session) -> bool {
        let attrs = self.get_item_attrs(CRATE_DEF_INDEX, sess);
        attr::contains_name(&attrs, "needs_allocator")
    }

    pub fn has_global_allocator(&self) -> bool {
        self.root.has_global_allocator.clone()
    }

    pub fn has_default_lib_allocator(&self) -> bool {
        self.root.has_default_lib_allocator.clone()
    }

    pub fn is_panic_runtime(&self, sess: &Session) -> bool {
        let attrs = self.get_item_attrs(CRATE_DEF_INDEX, sess);
        attr::contains_name(&attrs, "panic_runtime")
    }

    pub fn needs_panic_runtime(&self, sess: &Session) -> bool {
        let attrs = self.get_item_attrs(CRATE_DEF_INDEX, sess);
        attr::contains_name(&attrs, "needs_panic_runtime")
    }

    pub fn is_compiler_builtins(&self, sess: &Session) -> bool {
        let attrs = self.get_item_attrs(CRATE_DEF_INDEX, sess);
        attr::contains_name(&attrs, "compiler_builtins")
    }

    pub fn is_sanitizer_runtime(&self, sess: &Session) -> bool {
        let attrs = self.get_item_attrs(CRATE_DEF_INDEX, sess);
        attr::contains_name(&attrs, "sanitizer_runtime")
    }

    pub fn is_profiler_runtime(&self, sess: &Session) -> bool {
        let attrs = self.get_item_attrs(CRATE_DEF_INDEX, sess);
        attr::contains_name(&attrs, "profiler_runtime")
    }

    pub fn is_no_builtins(&self, sess: &Session) -> bool {
        let attrs = self.get_item_attrs(CRATE_DEF_INDEX, sess);
        attr::contains_name(&attrs, "no_builtins")
    }

    pub fn panic_strategy(&self) -> PanicStrategy {
        self.root.panic_strategy.clone()
    }
}
<commit_msg>Adapt some method visibilities in librustc_metadata::cstore.<commit_after>// Copyright 2012-2014 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.

// The crate store - a central repo for information collected about external
// crates and libraries

use schema;

use rustc::hir::def_id::{CRATE_DEF_INDEX, CrateNum, DefIndex};
use rustc::hir::map::definitions::DefPathTable;
use rustc::hir::svh::Svh;
use rustc::middle::cstore::{DepKind, ExternCrate, MetadataLoader};
use rustc::session::{Session, CrateDisambiguator};
use rustc_target::spec::PanicStrategy;
use rustc_data_structures::indexed_vec::IndexVec;
use rustc::util::nodemap::{FxHashMap, NodeMap};

use rustc_data_structures::sync::{Lrc, RwLock, Lock};
use syntax::{ast, attr};
use syntax::ext::base::SyntaxExtension;
use syntax::symbol::Symbol;
use syntax_pos;

pub use rustc::middle::cstore::{NativeLibrary, NativeLibraryKind, LinkagePreference};
pub use rustc::middle::cstore::NativeLibraryKind::*;
pub use rustc::middle::cstore::{CrateSource, LibSource, ForeignModule};

pub use cstore_impl::{provide, provide_extern};

// A map from external crate numbers (as decoded from some crate file) to
// local crate numbers (as generated during this session). Each external
// crate may refer to types in other external crates, and each has their
// own crate numbers.
pub type CrateNumMap = IndexVec<CrateNum, CrateNum>;

pub use rustc_data_structures::sync::MetadataRef;

pub struct MetadataBlob(pub MetadataRef);

/// Holds information about a syntax_pos::FileMap imported from another crate.
/// See `imported_filemaps()` for more information.
pub struct ImportedFileMap {
    /// This FileMap's byte-offset within the codemap of its original crate
    pub original_start_pos: syntax_pos::BytePos,
    /// The end of this FileMap within the codemap of its original crate
    pub original_end_pos: syntax_pos::BytePos,
    /// The imported FileMap's representation within the local codemap
    pub translated_filemap: Lrc<syntax_pos::FileMap>,
}

pub struct CrateMetadata {
    pub name: Symbol,

    /// Information about the extern crate that caused this crate to
    /// be loaded. If this is `None`, then the crate was injected
    /// (e.g., by the allocator)
    pub extern_crate: Lock<Option<ExternCrate>>,

    pub blob: MetadataBlob,
    pub cnum_map: Lock<CrateNumMap>,
    pub cnum: CrateNum,
    pub codemap_import_info: RwLock<Vec<ImportedFileMap>>,
    pub attribute_cache: Lock<[Vec<Option<Lrc<[ast::Attribute]>>>; 2]>,

    pub root: schema::CrateRoot,

    /// For each public item in this crate, we encode a key.  When the
    /// crate is loaded, we read all the keys and put them in this
    /// hashmap, which gives the reverse mapping.  This allows us to
    /// quickly retrace a `DefPath`, which is needed for incremental
    /// compilation support.
    pub def_path_table: Lrc<DefPathTable>,

    pub trait_impls: FxHashMap<(u32, DefIndex), schema::LazySeq<DefIndex>>,

    pub dep_kind: Lock<DepKind>,
    pub source: CrateSource,

    pub proc_macros: Option<Vec<(ast::Name, Lrc<SyntaxExtension>)>>,
}

pub struct CStore {
    metas: RwLock<IndexVec<CrateNum, Option<Lrc<CrateMetadata>>>>,
    /// Map from NodeId's of local extern crate statements to crate numbers
    extern_mod_crate_map: Lock<NodeMap<CrateNum>>,
    pub metadata_loader: Box<MetadataLoader + Sync>,
}

impl CStore {
    pub fn new(metadata_loader: Box<MetadataLoader + Sync>) -> CStore {
        CStore {
            metas: RwLock::new(IndexVec::new()),
            extern_mod_crate_map: Lock::new(FxHashMap()),
            metadata_loader,
        }
    }

    /// You cannot use this function to allocate a CrateNum in a thread-safe manner.
    /// It is currently only used in CrateLoader which is single-threaded code.
    pub(super) fn next_crate_num(&self) -> CrateNum {
        CrateNum::new(self.metas.borrow().len() + 1)
    }

    pub(super) fn get_crate_data(&self, cnum: CrateNum) -> Lrc<CrateMetadata> {
        self.metas.borrow()[cnum].clone().unwrap()
    }

    pub(super) fn set_crate_data(&self, cnum: CrateNum, data: Lrc<CrateMetadata>) {
        use rustc_data_structures::indexed_vec::Idx;
        let mut met = self.metas.borrow_mut();
        while met.len() <= cnum.index() {
            met.push(None);
        }
        met[cnum] = Some(data);
    }

    pub(super) fn iter_crate_data<I>(&self, mut i: I)
        where I: FnMut(CrateNum, &Lrc<CrateMetadata>)
    {
        for (k, v) in self.metas.borrow().iter_enumerated() {
            if let &Some(ref v) = v {
                i(k, v);
            }
        }
    }

    pub(super) fn crate_dependencies_in_rpo(&self, krate: CrateNum) -> Vec<CrateNum> {
        let mut ordering = Vec::new();
        self.push_dependencies_in_postorder(&mut ordering, krate);
        ordering.reverse();
        ordering
    }

    pub(super) fn push_dependencies_in_postorder(&self,
                                                 ordering: &mut Vec<CrateNum>,
                                                 krate: CrateNum) {
        if ordering.contains(&krate) {
            return;
        }

        let data = self.get_crate_data(krate);
        for &dep in data.cnum_map.borrow().iter() {
            if dep != krate {
                self.push_dependencies_in_postorder(ordering, dep);
            }
        }

        ordering.push(krate);
    }

    pub(super) fn do_postorder_cnums_untracked(&self) -> Vec<CrateNum> {
        let mut ordering = Vec::new();
        for (num, v) in self.metas.borrow().iter_enumerated() {
            if let &Some(_) = v {
                self.push_dependencies_in_postorder(&mut ordering, num);
            }
        }
        return ordering
    }

    pub(super) fn add_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId, cnum: CrateNum) {
        self.extern_mod_crate_map.borrow_mut().insert(emod_id, cnum);
    }

    pub(super) fn do_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum> {
        self.extern_mod_crate_map.borrow().get(&emod_id).cloned()
    }
}

impl CrateMetadata {
    pub fn name(&self) -> Symbol {
        self.root.name
    }
    pub fn hash(&self) -> Svh {
        self.root.hash
    }
    pub fn disambiguator(&self) -> CrateDisambiguator {
        self.root.disambiguator
    }

    pub fn needs_allocator(&self, sess: &Session) -> bool {
        let attrs = self.get_item_attrs(CRATE_DEF_INDEX, sess);
        attr::contains_name(&attrs, "needs_allocator")
    }

    pub fn has_global_allocator(&self) -> bool {
        self.root.has_global_allocator.clone()
    }

    pub fn has_default_lib_allocator(&self) -> bool {
        self.root.has_default_lib_allocator.clone()
    }

    pub fn is_panic_runtime(&self, sess: &Session) -> bool {
        let attrs = self.get_item_attrs(CRATE_DEF_INDEX, sess);
        attr::contains_name(&attrs, "panic_runtime")
    }

    pub fn needs_panic_runtime(&self, sess: &Session) -> bool {
        let attrs = self.get_item_attrs(CRATE_DEF_INDEX, sess);
        attr::contains_name(&attrs, "needs_panic_runtime")
    }

    pub fn is_compiler_builtins(&self, sess: &Session) -> bool {
        let attrs = self.get_item_attrs(CRATE_DEF_INDEX, sess);
        attr::contains_name(&attrs, "compiler_builtins")
    }

    pub fn is_sanitizer_runtime(&self, sess: &Session) -> bool {
        let attrs = self.get_item_attrs(CRATE_DEF_INDEX, sess);
        attr::contains_name(&attrs, "sanitizer_runtime")
    }

    pub fn is_profiler_runtime(&self, sess: &Session) -> bool {
        let attrs = self.get_item_attrs(CRATE_DEF_INDEX, sess);
        attr::contains_name(&attrs, "profiler_runtime")
    }

    pub fn is_no_builtins(&self, sess: &Session) -> bool {
        let attrs = self.get_item_attrs(CRATE_DEF_INDEX, sess);
        attr::contains_name(&attrs, "no_builtins")
    }

    pub fn panic_strategy(&self) -> PanicStrategy {
        self.root.panic_strategy.clone()
    }
}
<|endoftext|>


<commit_before>#![no_std]

use libtock_platform::Syscalls;

/// The LEDs driver
///
/// # Example
/// ```ignore
/// use libtock2::Leds;
///
/// // Turn on led 0
/// Leds::on(0);
/// ```
pub struct Leds<S: Syscalls>(S);

impl<S: Syscalls> Leds<S> {
    /// Run a check against the leds capsule to ensure it is present.
    ///
    /// Returns `Some(number_of_leds)` if the driver was present. This does not necessarily mean
    /// that the driver is working, as it may still fail to allocate grant
    /// memory.
    pub fn count() -> Option<u32> {
        S::command(DRIVER_ID, LEDS_COUNT, 0, 0)
            .get_success_u32()
            .map(|leds_count| Some(leds_count))
            .unwrap_or(None)
    }

    pub fn on(led: u32) {
        S::command(DRIVER_ID, LED_ON, led, 0);
    }

    pub fn off(led: u32) {
        S::command(DRIVER_ID, LED_OFF, led, 0);
    }

    pub fn toggle(led: u32) {
        S::command(DRIVER_ID, LED_TOGGLE, led, 0);
    }
}

const DRIVER_ID: u32 = 2;

// Command IDs
const LEDS_COUNT: u32 = 0;
const LED_ON: u32 = 1;
const LED_OFF: u32 = 2;
const LED_TOGGLE: u32 = 3;

#[cfg(test)]
mod tests;
<commit_msg>simplify count function<commit_after>#![no_std]

use libtock_platform::Syscalls;

/// The LEDs driver
///
/// # Example
/// ```ignore
/// use libtock2::Leds;
///
/// // Turn on led 0
/// Leds::on(0);
/// ```
pub struct Leds<S: Syscalls>(S);

impl<S: Syscalls> Leds<S> {
    /// Run a check against the leds capsule to ensure it is present.
    ///
    /// Returns `Some(number_of_leds)` if the driver was present. This does not necessarily mean
    /// that the driver is working, as it may still fail to allocate grant
    /// memory.
    pub fn count() -> Option<u32> {
        S::command(DRIVER_ID, LEDS_COUNT, 0, 0).get_success_u32()
    }

    pub fn on(led: u32) {
        S::command(DRIVER_ID, LED_ON, led, 0);
    }

    pub fn off(led: u32) {
        S::command(DRIVER_ID, LED_OFF, led, 0);
    }

    pub fn toggle(led: u32) {
        S::command(DRIVER_ID, LED_TOGGLE, led, 0);
    }
}

const DRIVER_ID: u32 = 2;

// Command IDs
const LEDS_COUNT: u32 = 0;
const LED_ON: u32 = 1;
const LED_OFF: u32 = 2;
const LED_TOGGLE: u32 = 3;

#[cfg(test)]
mod tests;
<|endoftext|>


<commit_before><commit_msg>Unify indexed mode instruction printing<commit_after><|endoftext|>


<commit_before>use alloc::linked_list::LinkedList;
use alloc::boxed::Box;
use kernel::kget;

use schedule::task::TID_BOTTOMHALFD;
use schedule::task::TaskStatus;

use spin::Mutex;

/// Main bottomhalfd task
///
/// Loops forever, iterating over all queued `BottomHalf` tasks and executing them in series.
pub fn execute() {
    loop {
        kprintln!("Enter loop BH::execute");
        let mut scheduler = unsafe { &mut *kget().scheduler.get() };
        let bh_manager = scheduler.bh_manager();

        // Execute all waiting bottom halves
        bh_manager.execute_all();

        kprintln!("executed all BH");

        // Set the current task status to WAITING and set the scheduler to reschedule
        // at its next opportunity.
        scheduler.set_task_status(TID_BOTTOMHALFD, TaskStatus::WAITING);
        scheduler.set_need_resched();

        kprintln!("Halting");

        // Sleep until the next interrupt
        halt!();

        kprintln!("Awakened");
    }
}

/// A task to execute as the bottom half of an interrupt handler
pub trait BottomHalf {
    /// Exectute the work for this bottom half
    fn execute(&mut self);
}

/// A first in first out queue of `BottomHalf` tasks
struct BottomHalfQueue {
    queue: LinkedList<Box<BottomHalf>>,
}

impl BottomHalfQueue {
    /// Construct a new `BottomHalfQueue`
    pub fn new() -> BottomHalfQueue {
        BottomHalfQueue { queue: LinkedList::new() }
    }

    /// Returns the length of the queue
    pub fn len(&self) -> usize {
        self.queue.len()
    }

    /// Push a `BottomHalf` onto the back of the queue
    pub fn push(&mut self, bh: Box<BottomHalf>) {
        self.queue.push_back(bh);
    }

    /// Pop a `BottomHalf` from the front of the queue
    ///
    /// If the queue is empty this will return `None`
    pub fn pop(&mut self) -> Option<Box<BottomHalf>> {
        self.queue.pop_front()
    }
}

/// Manager of `BottomHalf` queues.
///
/// Provides thread safety to the `BottomHalf` processing.
pub struct BottomHalfManager {
    queue: Mutex<BottomHalfQueue>,
}

impl BottomHalfManager {
    /// Construct a new `BottomHalfManager`
    pub fn new() -> BottomHalfManager {
        BottomHalfManager { queue: Mutex::new(BottomHalfQueue::new()) }
    }

    /// Push a `BottomHalf` onto the back of the queue
    pub fn add_bh(&self, bh: Box<BottomHalf>) {
        let len = {
            let mut q = self.queue.lock();
            q.push(bh);
            q.len()
        };

        // If this is the first task added then tell the scheduler to schedule the bottom half
        // thread next time it runs
        if len == 1 {
            let mut scheduler = unsafe { &mut *kget().scheduler.get() };
            scheduler.set_task_status(TID_BOTTOMHALFD, TaskStatus::READY);
            scheduler.set_need_resched();
        }
    }

    /// Execute all currently queued `BottomHalf` tasks
    pub fn execute_all(&self) {
        loop {
            match self.queue.lock().pop() {
                Some(mut bh) => bh.execute(),
                None => break,
            }
        }
    }
}
<commit_msg>Fix compiler warnings in bottom_half_manager<commit_after>use alloc::linked_list::LinkedList;
use alloc::boxed::Box;
use kernel::kget;

use schedule::task::TID_BOTTOMHALFD;
use schedule::task::TaskStatus;

use spin::Mutex;

/// Main bottomhalfd task
///
/// Loops forever, iterating over all queued `BottomHalf` tasks and executing them in series.
pub fn execute() {
    loop {
        kprintln!("Enter loop BH::execute");
        let scheduler = unsafe { &mut *kget().scheduler.get() };
        let bh_manager = scheduler.bh_manager();

        // Execute all waiting bottom halves
        bh_manager.execute_all();

        kprintln!("executed all BH");

        // Set the current task status to WAITING and set the scheduler to reschedule
        // at its next opportunity.
        scheduler.set_task_status(TID_BOTTOMHALFD, TaskStatus::WAITING);
        scheduler.set_need_resched();

        kprintln!("Halting");

        // Sleep until the next interrupt
        halt!();

        kprintln!("Awakened");
    }
}

/// A task to execute as the bottom half of an interrupt handler
pub trait BottomHalf {
    /// Exectute the work for this bottom half
    fn execute(&mut self);
}

/// A first in first out queue of `BottomHalf` tasks
struct BottomHalfQueue {
    queue: LinkedList<Box<BottomHalf>>,
}

impl BottomHalfQueue {
    /// Construct a new `BottomHalfQueue`
    pub fn new() -> BottomHalfQueue {
        BottomHalfQueue { queue: LinkedList::new() }
    }

    /// Returns the length of the queue
    pub fn len(&self) -> usize {
        self.queue.len()
    }

    /// Push a `BottomHalf` onto the back of the queue
    pub fn push(&mut self, bh: Box<BottomHalf>) {
        self.queue.push_back(bh);
    }

    /// Pop a `BottomHalf` from the front of the queue
    ///
    /// If the queue is empty this will return `None`
    pub fn pop(&mut self) -> Option<Box<BottomHalf>> {
        self.queue.pop_front()
    }
}

/// Manager of `BottomHalf` queues.
///
/// Provides thread safety to the `BottomHalf` processing.
pub struct BottomHalfManager {
    queue: Mutex<BottomHalfQueue>,
}

impl BottomHalfManager {
    /// Construct a new `BottomHalfManager`
    pub fn new() -> BottomHalfManager {
        BottomHalfManager { queue: Mutex::new(BottomHalfQueue::new()) }
    }

    /// Push a `BottomHalf` onto the back of the queue
    pub fn add_bh(&self, bh: Box<BottomHalf>) {
        let len = {
            let mut q = self.queue.lock();
            q.push(bh);
            q.len()
        };

        // If this is the first task added then tell the scheduler to schedule the bottom half
        // thread next time it runs
        if len == 1 {
            let scheduler = unsafe { &mut *kget().scheduler.get() };
            scheduler.set_task_status(TID_BOTTOMHALFD, TaskStatus::READY);
            scheduler.set_need_resched();
        }
    }

    /// Execute all currently queued `BottomHalf` tasks
    pub fn execute_all(&self) {
        loop {
            match self.queue.lock().pop() {
                Some(mut bh) => bh.execute(),
                None => break,
            }
        }
    }
}
<|endoftext|>