diff --git a/crates/lune-std-ffi/src/c/c_helper.rs b/crates/lune-std-ffi/src/c/c_helper.rs index a843ae5..2db7361 100644 --- a/crates/lune-std-ffi/src/c/c_helper.rs +++ b/crates/lune-std-ffi/src/c/c_helper.rs @@ -5,9 +5,8 @@ use lune_utils::fmt::{pretty_format_value, ValueFormatConfig}; use mlua::prelude::*; use super::{ - association_names::CTYPE_STATIC, types::{get_ctype_conv, get_ctype_size}, - CArr, CPtr, CStruct, CTypeStatic, + CArr, CPtr, CStruct, }; use crate::ffi::{ffi_association::get_association, NativeConvert, NativeSize}; diff --git a/crates/lune-std-ffi/src/c/c_type.rs b/crates/lune-std-ffi/src/c/c_type.rs index 1b6dcf1..67cfdda 100644 --- a/crates/lune-std-ffi/src/c/c_type.rs +++ b/crates/lune-std-ffi/src/c/c_type.rs @@ -6,36 +6,10 @@ use libffi::middle::Type; use lune_utils::fmt::{pretty_format_value, ValueFormatConfig}; use mlua::prelude::*; -use super::{association_names::CTYPE_STATIC, CArr, CPtr}; -use crate::ffi::{ - ffi_association::set_association, FfiBox, GetNativeData, NativeConvert, NativeData, - NativeSignedness, NativeSize, -}; +use super::{CArr, CPtr}; +use crate::ffi::{FfiBox, GetNativeData, NativeConvert, NativeData, NativeSignedness, NativeSize}; use crate::libffi_helper::get_ensured_size; -// We can't get a CType through mlua, something like -// .is::> will fail. -// So we need data that has a static type. -// each CType userdata instance stores an instance of CTypeStatic. -#[allow(unused)] -pub struct CTypeStatic { - pub libffi_type: Type, - pub size: usize, - pub name: Option<&'static str>, - pub signedness: bool, -} -impl CTypeStatic { - fn new(ctype: &CType, signedness: bool) -> Self { - Self { - libffi_type: ctype.libffi_type.clone(), - size: ctype.size, - name: ctype.name, - signedness, - } - } -} -impl LuaUserData for CTypeStatic {} - // Cast native data pub trait CTypeCast { #[inline(always)] @@ -96,12 +70,8 @@ where name, _phantom: PhantomData, }; - let userdata_static = - lua.create_any_userdata(CTypeStatic::new::(&ctype, ctype.get_signedness()))?; let userdata = lua.create_userdata(ctype)?; - set_association(lua, CTYPE_STATIC, &userdata, &userdata_static)?; - Ok(userdata) } diff --git a/crates/lune-std-ffi/src/c/mod.rs b/crates/lune-std-ffi/src/c/mod.rs index e1a577a..e99b9c9 100644 --- a/crates/lune-std-ffi/src/c/mod.rs +++ b/crates/lune-std-ffi/src/c/mod.rs @@ -12,7 +12,7 @@ pub use self::{ c_fn::CFn, c_ptr::CPtr, c_struct::CStruct, - c_type::{CType, CTypeCast, CTypeStatic}, + c_type::{CType, CTypeCast}, }; pub use types::export_ctypes; @@ -22,7 +22,6 @@ mod association_names { pub const CPTR_INNER: &str = "__cptr_inner"; pub const CARR_INNER: &str = "__carr_inner"; pub const CSTRUCT_INNER: &str = "__cstruct_inner"; - pub const CTYPE_STATIC: &str = "__ctype_static"; pub const CFN_RESULT: &str = "__cfn_result"; pub const CFN_ARGS: &str = "__cfn_args"; pub const CALLABLE_REF: &str = "__callable_ref"; diff --git a/crates/lune-std-ffi/src/c/types/mod.rs b/crates/lune-std-ffi/src/c/types/mod.rs index f054142..87df517 100644 --- a/crates/lune-std-ffi/src/c/types/mod.rs +++ b/crates/lune-std-ffi/src/c/types/mod.rs @@ -25,6 +25,7 @@ pub mod u64; pub mod u8; pub mod usize; +// create CType userdata and export macro_rules! create_ctypes { ($lua:ident, $(( $name:expr, $rust_type:ty, $libffi_type:expr ),)* ) => { Ok(vec![$(( @@ -33,8 +34,6 @@ macro_rules! create_ctypes { ),)*]) }; } - -// create CType userdata and export pub fn export_ctypes(lua: &Lua) -> LuaResult> { create_ctypes!( lua, @@ -56,10 +55,6 @@ pub fn export_ctypes(lua: &Lua) -> LuaResult ("ulong", c_ulong, Type::c_ulong()), ("longlong", c_longlong, Type::c_longlong()), ("ulonglong", c_ulonglong, Type::c_ulonglong()), - // TODO: c_float and c_double sometime can be half and single, - // TODO: but libffi-rs doesn't support it. need work-around or drop support - ("float", f32, Type::f32()), - ("double", f64, Type::f64()), // Export Source-time known c-types (fixed) ("u8", u8, Type::u8()), ("u16", u16, Type::u16()), @@ -75,25 +70,16 @@ pub fn export_ctypes(lua: &Lua) -> LuaResult ("f32", f32, Type::f32()), ("usize", usize, Type::usize()), ("isize", isize, Type::isize()), + // TODO: c_float and c_double sometime can be half and single, + // TODO: but libffi-rs doesn't support it. need work-around or drop support + ("float", f32, Type::f32()), + ("double", f64, Type::f64()), ) } -macro_rules! define { - (@get_conv $userdata:ident, $( $rust_type:ty )*) => { - $( if $userdata.is::>() { - Ok($userdata.to_pointer().cast::>() as *const dyn NativeConvert) - } else )* { - Err(LuaError::external("Unexpected type")) - } - }; - (@get_size $userdata:ident, $( $rust_type:ty )*) => { - $( if $userdata.is::>() { - Ok($userdata.borrow::>()?.get_size()) - } else )* { - Err(LuaError::external("Unexpected type")) - } - }; - (@cast_num $from_rust_type:ident, $self:ident, $from_ctype:ident, $into_ctype:ident, $from:ident, $into:ident, $($into_rust_type:ty)*) => { +// Implement type-casting for numeric ctypes +macro_rules! define_cast_num { + ($from_rust_type:ident, $self:ident, $from_ctype:ident, $into_ctype:ident, $from:ident, $into:ident, $($into_rust_type:ty)*) => { $( if $into_ctype.is::>() { native_num_cast::<$from_rust_type, $into_rust_type>($from, $into) } else )* { @@ -101,10 +87,9 @@ macro_rules! define { } }; } - -impl CTypeCast for CType +impl CTypeCast for CType where - T: AsPrimitive + From: AsPrimitive + AsPrimitive + AsPrimitive + AsPrimitive @@ -126,17 +111,65 @@ where from: &Ref, into: &Ref, ) -> LuaResult<()> { - define!( - @cast_num T, self, into_ctype, from_ctype, from, into, + define_cast_num!( + From, self, into_ctype, from_ctype, from, into, u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 f32 f64 usize isize ) } } // To prevent drop NativeConvert, we must use ffi_association to ensure children keep alive +macro_rules! define_get_conv { + ($userdata:ident, $( $rust_type:ty )*) => { + $( if $userdata.is::>() { + Ok($userdata.to_pointer().cast::>() as *const dyn NativeConvert) + } else )* { + Err(LuaError::external("Unexpected type")) + } + }; +} pub fn get_ctype_conv(userdata: &LuaAnyUserData) -> LuaResult<*const dyn NativeConvert> { - define!(@get_conv userdata, u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 f32 f64 usize isize) + define_get_conv!(userdata, u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 f32 f64 usize isize) +} + +// Get size of ctype (not includes struct, arr, ... only CType<*>) +macro_rules! define_get_size { + ($userdata:ident, $( $rust_type:ty )*) => { + $( if $userdata.is::>() { + Ok($userdata.borrow::>()?.get_size()) + } else )* { + Err(LuaError::external("Unexpected type")) + } + }; } pub fn get_ctype_size(userdata: &LuaAnyUserData) -> LuaResult { - define!(@get_size userdata, u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 f32 f64 usize isize) + define_get_size!(userdata, u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 f32 f64 usize isize) +} + +// Get name of ctype +macro_rules! define_get_name { + ($userdata:ident, $( $rust_type:ty )*) => { + $( if $userdata.is::>() { + Ok($userdata.borrow::>()?.stringify()) + } else )* { + Err(LuaError::external("Unexpected type")) + } + }; +} +pub fn get_ctype_name(userdata: &LuaAnyUserData) -> LuaResult<&str> { + define_get_name!(userdata, u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 f32 f64 usize isize) +} + +// Get libffi_type of ctype +macro_rules! define_get_libffi_type { + ($userdata:ident, $( $rust_type:ty )*) => { + $( if $userdata.is::>() { + Ok($userdata.borrow::>()?.get_size()) + } else )* { + Err(LuaError::external("Unexpected type")) + } + }; +} +pub fn get_ctype_libffi_type(userdata: &LuaAnyUserData) -> LuaResult { + define_get_libffi_type!(userdata, u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 f32 f64 usize isize) }