Commit dd3bd537 authored by John Hodge (bugs)'s avatar John Hodge (bugs)

Implement win64 ABI, fix a few other quirks.

parent 228770f3
......@@ -39,5 +39,5 @@ impl VaPrimitive for i32 { 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 f32 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
//impl VaPrimitive for f32 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
......@@ -39,5 +39,5 @@ impl VaPrimitive for i32 { 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 f32 { 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 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<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 _ } }
impl VaPrimitive for i32 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw::<i64>() as _ } }
//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() } }
......@@ -48,8 +48,8 @@ mod std {
#[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-elf.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" ))]
......
......@@ -2,14 +2,14 @@ extern crate va_list;
#[link(name="va_list_test")]
extern "C" {
fn dispatch(context: *mut (), count: u32, ...);
fn dispatch(context: *mut u8, count: u32, ...);
}
type CbType<'a> = &'a mut FnMut(u32, va_list::VaList);
#[no_mangle]
/// Method called by 'dispatch'
pub extern "C" fn inbound(context: *mut (), count: u32, args: va_list::VaList) {
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);
......@@ -21,7 +21,7 @@ macro_rules! test_va_list {
let mut cb_ref: CbType = &mut cb;
unsafe {
dispatch(&mut cb_ref as *mut _ as *mut (), $int, $($args),*);
dispatch(&mut cb_ref as *mut _ as *mut u8, $int, $($args),*);
}
});
}
......@@ -37,3 +37,12 @@ fn trivial_values() {
assert_eq!( list.get::<i64>(), -23i64 );
} });
}
#[test]
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 );
} });
}
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