Commit 2371272e authored by Dan Robertson's avatar Dan Robertson

Run rustfmt on code

parent 1945668b
/*
*
*/
use std::{mem,ptr};
use std::{mem, ptr};
use super::VaPrimitive;
#[allow(non_camel_case_types)]
pub struct VaList(*const u8);
impl VaList
{
pub unsafe fn get<T: VaPrimitive>(&mut self) -> T {
T::get(self)
}
// Read a raw value from the list
unsafe fn get_raw<T: 'static>(&mut self) -> T {
assert_eq!(self.0 as usize % mem::align_of::<T>(), 0);
let rv = ptr::read(self.0 as *const T);
self.0 = self.0.offset( mem::size_of::<T>() as isize );
rv
}
impl VaList {
pub unsafe fn get<T: VaPrimitive>(&mut self) -> T {
T::get(self)
}
// Read a raw value from the list
unsafe fn get_raw<T: 'static>(&mut self) -> T {
assert_eq!(self.0 as usize % mem::align_of::<T>(), 0);
let rv = ptr::read(self.0 as *const T);
self.0 = self.0.offset(mem::size_of::<T>() as isize);
rv
}
}
impl<T: 'static> VaPrimitive for *const T
{
unsafe fn get(list: &mut VaList) -> Self {
<usize>::get(list) as *const T
}
}
impl VaPrimitive for usize { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
impl VaPrimitive for isize { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
impl VaPrimitive for u64 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
impl VaPrimitive for i64 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
impl VaPrimitive for u32 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
impl VaPrimitive for i32 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
impl<T: 'static> VaPrimitive for *const T {
unsafe fn get(list: &mut VaList) -> Self {
<usize>::get(list) as *const T
}
}
impl VaPrimitive for usize {
unsafe fn get(l: &mut VaList) -> Self {
l.get_raw()
}
}
impl VaPrimitive for isize {
unsafe fn get(l: &mut VaList) -> Self {
l.get_raw()
}
}
impl VaPrimitive for u64 {
unsafe fn get(l: &mut VaList) -> Self {
l.get_raw()
}
}
impl VaPrimitive for i64 {
unsafe fn get(l: &mut VaList) -> Self {
l.get_raw()
}
}
impl VaPrimitive for u32 {
unsafe fn get(l: &mut VaList) -> Self {
l.get_raw()
}
}
impl VaPrimitive for i32 {
unsafe fn get(l: &mut VaList) -> Self {
l.get_raw()
}
}
//impl VaPrimitive for u16 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
//impl VaPrimitive for i16 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
//impl VaPrimitive for u8 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
//impl VaPrimitive for i8 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
impl VaPrimitive for f64 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
impl VaPrimitive for f64 {
unsafe fn get(l: &mut VaList) -> Self {
l.get_raw()
}
}
//impl VaPrimitive for f32 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
/*
*
*/
use std::{mem,ptr};
use std::{mem, ptr};
use super::VaPrimitive;
#[allow(non_camel_case_types)]
pub struct VaList(*const u8);
impl VaList
{
pub unsafe fn get<T: VaPrimitive>(&mut self) -> T {
T::get(self)
}
// Read a raw value from the list
unsafe fn get_raw<T: 'static>(&mut self) -> T {
assert_eq!(self.0 as usize % mem::align_of::<T>(), 0);
let rv = ptr::read(self.0 as *const T);
self.0 = self.0.offset( mem::size_of::<T>() as isize );
rv
}
impl VaList {
pub unsafe fn get<T: VaPrimitive>(&mut self) -> T {
T::get(self)
}
// Read a raw value from the list
unsafe fn get_raw<T: 'static>(&mut self) -> T {
assert_eq!(self.0 as usize % mem::align_of::<T>(), 0);
let rv = ptr::read(self.0 as *const T);
self.0 = self.0.offset(mem::size_of::<T>() as isize);
rv
}
}
impl<T: 'static> VaPrimitive for *const T
{
unsafe fn get(list: &mut VaList) -> Self {
<usize>::get(list) as *const T
}
}
impl VaPrimitive for usize { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
impl VaPrimitive for isize { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
impl VaPrimitive for u64 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
impl VaPrimitive for i64 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
impl VaPrimitive for u32 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
impl VaPrimitive for i32 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
impl<T: 'static> VaPrimitive for *const T {
unsafe fn get(list: &mut VaList) -> Self {
<usize>::get(list) as *const T
}
}
impl VaPrimitive for usize {
unsafe fn get(l: &mut VaList) -> Self {
l.get_raw()
}
}
impl VaPrimitive for isize {
unsafe fn get(l: &mut VaList) -> Self {
l.get_raw()
}
}
impl VaPrimitive for u64 {
unsafe fn get(l: &mut VaList) -> Self {
l.get_raw()
}
}
impl VaPrimitive for i64 {
unsafe fn get(l: &mut VaList) -> Self {
l.get_raw()
}
}
impl VaPrimitive for u32 {
unsafe fn get(l: &mut VaList) -> Self {
l.get_raw()
}
}
impl VaPrimitive for i32 {
unsafe fn get(l: &mut VaList) -> Self {
l.get_raw()
}
}
//impl VaPrimitive for u16 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
//impl VaPrimitive for i16 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
//impl VaPrimitive for u8 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
//impl VaPrimitive for i8 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
impl VaPrimitive for f64 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
impl VaPrimitive for f64 {
unsafe fn get(l: &mut VaList) -> Self {
l.get_raw()
}
}
//impl VaPrimitive for f32 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
// x86_64 ELF - Aka the Itanium ABI
//
use std::{mem,ptr};
use std::{mem, ptr};
use super::VaPrimitive;
pub struct VaList(*mut VaListInner);
......@@ -10,28 +10,26 @@ pub struct VaList(*mut VaListInner);
#[repr(C)]
#[derive(Debug)]
#[doc(hidden)]
pub struct VaListInner
{
gp_offset: u32,
fp_offset: u32,
overflow_arg_area: *const (),
reg_save_area: *const (),
pub struct VaListInner {
gp_offset: u32,
fp_offset: u32,
overflow_arg_area: *const (),
reg_save_area: *const (),
}
impl VaList
{
fn inner(&mut self) -> &mut VaListInner {
// This pointer should be valid
unsafe { &mut *self.0 }
}
impl VaList {
fn inner(&mut self) -> &mut VaListInner {
// This pointer should be valid
unsafe { &mut *self.0 }
}
}
#[doc(hidden)]
impl VaListInner
{
impl VaListInner {
fn check_space(&self, num_gp: u32, num_fp: u32) -> bool {
!(self.gp_offset > 48 - num_gp * 8 || self.fp_offset > 304 - num_fp * 16)
}
unsafe fn get_gp<T>(&mut self) -> T {
let n_gp = (mem::size_of::<T>()+7)/8;
assert!( self.check_space(n_gp as u32, 0) );
......@@ -39,6 +37,7 @@ impl VaListInner
self.gp_offset += (8*n_gp) as u32;
rv
}
unsafe fn get_fp<T>(&mut self) -> T {
let n_fp = (mem::size_of::<T>()+15)/16;
assert!( self.check_space(0, n_fp as u32) );
......@@ -46,6 +45,7 @@ impl VaListInner
self.fp_offset += (16*n_fp) as u32;
rv
}
unsafe fn get_overflow<T>(&mut self) -> T {
let align = mem::align_of::<T>();
// 7. Align overflow_reg_area upwards to a 16-byte boundary if alignment
......@@ -68,33 +68,31 @@ impl VaListInner
}
}
impl<T: 'static> VaPrimitive for *const T
{
unsafe fn get(list: &mut VaList) -> Self {
<usize>::get(list) as *const T
}
impl<T: 'static> VaPrimitive for *const T {
unsafe fn get(list: &mut VaList) -> Self {
<usize>::get(list) as *const T
}
}
macro_rules! impl_va_prim {
($u:ty, $s:ty) => {
impl VaPrimitive for $u {
unsafe fn get(list: &mut VaList) -> Self {
let inner = list.inner();
// See the ELF AMD64 ABI document for a description of how this should act
if ! inner.check_space(1, 0) {
inner.get_overflow()
}
else {
inner.get_gp()
}
}
}
impl VaPrimitive for $s {
unsafe fn get(list: &mut VaList) -> Self {
mem::transmute( <$u>::get(list) )
}
}
};
($u: ty, $s: ty) => {
impl VaPrimitive for $u {
unsafe fn get(list: &mut VaList) -> Self {
let inner = list.inner();
// See the ELF AMD64 ABI document for a description of how this should act
if !inner.check_space(1, 0) {
inner.get_overflow()
} else {
inner.get_gp()
}
}
}
impl VaPrimitive for $s {
unsafe fn get(list: &mut VaList) -> Self {
mem::transmute(<$u>::get(list))
}
}
};
}
impl_va_prim!{ usize, isize }
......
/*
*
*/
use std::{mem,ptr};
use std::{mem, ptr};
use super::VaPrimitive;
#[allow(non_camel_case_types)]
pub struct VaList(*const u8);
impl VaList
{
// Read a raw value from the list
unsafe fn get_raw<T: 'static>(&mut self) -> T {
assert_eq!(self.0 as usize % mem::align_of::<T>(), 0);
let rv = ptr::read(self.0 as *const T);
self.0 = self.0.offset( mem::size_of::<T>() as isize );
rv
}
impl VaList {
// Read a raw value from the list
unsafe fn get_raw<T: 'static>(&mut self) -> T {
assert_eq!(self.0 as usize % mem::align_of::<T>(), 0);
let rv = ptr::read(self.0 as *const T);
self.0 = self.0.offset(mem::size_of::<T>() as isize);
rv
}
}
impl<T: 'static> VaPrimitive for *const T
{
unsafe fn get(list: &mut VaList) -> Self {
<usize>::get(list) as *const T
}
}
impl VaPrimitive for usize { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
impl VaPrimitive for isize { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
impl VaPrimitive for u64 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
impl VaPrimitive for i64 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
impl VaPrimitive for u32 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw::<u64>() as u32 } }
impl VaPrimitive for i32 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw::<i64>() as i32 } }
impl<T: 'static> VaPrimitive for *const T {
unsafe fn get(list: &mut VaList) -> Self {
<usize>::get(list) as *const T
}
}
impl VaPrimitive for usize {
unsafe fn get(l: &mut VaList) -> Self {
l.get_raw()
}
}
impl VaPrimitive for isize {
unsafe fn get(l: &mut VaList) -> Self {
l.get_raw()
}
}
impl VaPrimitive for u64 {
unsafe fn get(l: &mut VaList) -> Self {
l.get_raw()
}
}
impl VaPrimitive for i64 {
unsafe fn get(l: &mut VaList) -> Self {
l.get_raw()
}
}
impl VaPrimitive for u32 {
unsafe fn get(l: &mut VaList) -> Self {
l.get_raw::<u64>() as u32
}
}
impl VaPrimitive for i32 {
unsafe fn get(l: &mut VaList) -> Self {
l.get_raw::<i64>() as i32
}
}
//impl VaPrimitive for u16 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
//impl VaPrimitive for i16 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
//impl VaPrimitive for u8 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
//impl VaPrimitive for i8 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
impl VaPrimitive for f64 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
impl VaPrimitive for f64 {
unsafe fn get(l: &mut VaList) -> Self {
l.get_raw()
}
}
......@@ -33,52 +33,54 @@
* }
* ```
*/
#![cfg_attr(feature="no_std",no_std)]
#![crate_type="lib"]
#![crate_name="va_list"]
#![cfg_attr(feature = "no_std", no_std)]
#![crate_type = "lib"]
#![crate_name = "va_list"]
#[cfg(feature="no_std")]
#[cfg(feature = "no_std")]
#[doc(hidden)]
mod std {
pub use core::{mem,ptr};
pub use core::{mem, ptr};
}
// x86_64 on unix platforms is _usually_ ELF.
#[cfg(all( target_arch="x86_64", any(target_family="unix", target_os="redox", target_os="tifflin") ))]
#[path="impl-x86_64-elf.rs"] mod imp;
#[cfg(all(target_arch="x86_64", any(target_family="unix", target_os="redox", target_os="tifflin")))]
#[path = "impl-x86_64-elf.rs"]
mod imp;
//// x86_64 on windows is special
#[cfg(all( target_arch="x86_64", target_family="windows" ))]
#[path="impl-x86_64-win64.rs"] mod imp;
#[cfg(all(target_arch = "x86_64", target_family = "windows"))]
#[path = "impl-x86_64-win64.rs"]
mod imp;
// x86+unix = cdecl
#[cfg(all( target_arch="x86", target_family="unix" ))]
#[path="impl-x86-sysv.rs"] mod imp;
#[cfg(all(target_arch = "x86", target_family = "unix"))]
#[path = "impl-x86-sysv.rs"]
mod imp;
// arm+unix = cdecl
#[cfg(all( target_arch="arm", target_family="unix" ))]
#[path="impl-arm-sysv.rs"] mod imp;
#[cfg(all(target_arch = "arm", target_family = "unix"))]
#[path = "impl-arm-sysv.rs"]
mod imp;
/// Rust version of C's `va_list` type from the `stdarg.h` header
#[repr(C)]
pub struct VaList {
internal: imp::VaList
internal: imp::VaList,
}
/// Core type as passed though the FFI
impl VaList
{
/// Read a value from the VaList.
///
/// Users should take care that they are reading the correct type
pub unsafe fn get<T: VaPrimitive>(&mut self) -> T {
T::get(&mut self.internal)
}
impl VaList {
/// Read a value from the VaList.
///
/// Users should take care that they are reading the correct type
pub unsafe fn get<T: VaPrimitive>(&mut self) -> T {
T::get(&mut self.internal)
}
}
/// Trait implemented on types that can be read from a va_list
pub trait VaPrimitive: 'static
{
#[doc(hidden)]
unsafe fn get(&mut imp::VaList) -> Self;
pub trait VaPrimitive: 'static {
#[doc(hidden)]
unsafe fn get(&mut imp::VaList) -> Self;
}
extern crate va_list;
#[link(name="va_list_test")]
#[link(name = "va_list_test")]
extern "C" {
fn dispatch(context: *mut u8, count: u32, ...);
fn dispatch(context: *mut u8, count: u32, ...);
}
type CbType<'a> = &'a mut FnMut(u32, va_list::VaList);
......@@ -10,16 +10,16 @@ type CbType<'a> = &'a mut FnMut(u32, va_list::VaList);
#[no_mangle]
/// Method called by 'dispatch'
pub extern "C" fn inbound(context: *mut u8, count: u32, args: va_list::VaList) {
let cb_ptr = unsafe { ::std::ptr::read(context as *mut CbType ) };
// call passed closure
(cb_ptr)(count, args);
let cb_ptr = unsafe { ::std::ptr::read(context as *mut CbType) };
// call passed closure
(cb_ptr)(count, args);
}
macro_rules! test_va_list {
($int:expr, ($($args:expr),*), $code:expr) => ({
let mut cb = $code;
let mut cb_ref: CbType = &mut cb;
unsafe {
dispatch(&mut cb_ref as *mut _ as *mut u8, $int, $($args),*);
}
......@@ -28,22 +28,28 @@ macro_rules! test_va_list {
#[test]
fn trivial_values() {
// Trivial test: Pass four random-ish sized integers
test_va_list!(4, (123456u32, 2u64, 1i32, -23i64),
|_count, mut list: va_list::VaList| { unsafe {
assert_eq!( list.get::<u32>(), 123456u32 );
assert_eq!( list.get::<u64>(), 2u64 );
assert_eq!( list.get::<i32>(), 1i32 );
assert_eq!( list.get::<i64>(), -23i64 );
} });
// Trivial test: Pass four random-ish sized integers
test_va_list!(
4,
(123456u32, 2u64, 1i32, -23i64),
|_count, mut list: va_list::VaList| unsafe {
assert_eq!(list.get::<u32>(), 123456u32);
assert_eq!(list.get::<u64>(), 2u64);
assert_eq!(list.get::<i32>(), 1i32);
assert_eq!(list.get::<i64>(), -23i64);
}
);
}
#[test]
#[cfg(not(all( target_arch="x86_64", target_family="unix" )))] // TODO: Float on AMD64
#[cfg(not(all(target_arch = "x86_64", target_family = "unix")))] // TODO: Float on AMD64
fn floating_point() {
test_va_list!(4, (123456f64, 0.1f64),
|_count, mut list: va_list::VaList| { unsafe {
assert_eq!( list.get::<f64>(), 123456f64 );
assert_eq!( list.get::<f64>(), 0.1f64 );
} });
test_va_list!(
4,
(123456f64, 0.1f64),
|_count, mut list: va_list::VaList| unsafe {
assert_eq!(list.get::<f64>(), 123456f64);
assert_eq!(list.get::<f64>(), 0.1f64);
}
);
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment