diff --git a/crates/lune-std-ffi/src/c/c_fn.rs b/crates/lune-std-ffi/src/c/c_fn.rs index c1877a6b..7f413828 100644 --- a/crates/lune-std-ffi/src/c/c_fn.rs +++ b/crates/lune-std-ffi/src/c/c_fn.rs @@ -1,3 +1,4 @@ +use libffi::low::ffi_cif; use libffi::middle::{Cif, Type}; use mlua::prelude::*; @@ -23,7 +24,7 @@ use crate::ffi::NativeConvert; // moved to a Lua function or vice versa. pub struct CFn { - libffi_cif: Cif, + cif: *mut ffi_cif, args_conv: Vec<*const dyn NativeConvert>, ret_conv: *const dyn NativeConvert, } @@ -35,20 +36,19 @@ impl CFn { args_conv: Vec<*const dyn NativeConvert>, ret_conv: *const dyn NativeConvert, ) -> Self { - let libffi_cif: Cif = Cif::new(args.clone(), ret.clone()); Self { - libffi_cif, + cif: Cif::new(args.clone(), ret.clone()).as_raw_ptr(), args_conv, ret_conv, } } pub fn new_from_lua_table(lua: &Lua, args: LuaTable, ret: LuaAnyUserData) -> LuaResult { - let args_type = libffi_type_list_from_table(lua, &args)?; + let args_types = libffi_type_list_from_table(lua, &args)?; let ret_type = libffi_type_from_userdata(lua, &ret)?; Ok(Self::new( - args_type, + args_types, ret_type, unsafe { get_conv_list_from_table(&args)? }, unsafe { get_conv(&ret)? }, diff --git a/crates/lune-std-ffi/src/c/c_struct.rs b/crates/lune-std-ffi/src/c/c_struct.rs index ff51b44e..f34a98ec 100644 --- a/crates/lune-std-ffi/src/c/c_struct.rs +++ b/crates/lune-std-ffi/src/c/c_struct.rs @@ -208,7 +208,7 @@ impl LuaUserData for CStruct { if !data_handle.check_boundary(offset, this.get_size()) { return Err(LuaError::external("Out of bounds")); } - if !data_handle.check_readable(offset, this.get_size()) { + if !data_handle.is_readable() { return Err(LuaError::external("Unreadable data handle")); } @@ -224,7 +224,7 @@ impl LuaUserData for CStruct { if !data_handle.check_boundary(offset, this.get_size()) { return Err(LuaError::external("Out of bounds")); } - if !data_handle.checek_writable(offset, this.get_size()) { + if !data_handle.is_writable() { return Err(LuaError::external("Unwritable data handle")); } diff --git a/crates/lune-std-ffi/src/c/c_type.rs b/crates/lune-std-ffi/src/c/c_type.rs index bf1ff458..98ab565c 100644 --- a/crates/lune-std-ffi/src/c/c_type.rs +++ b/crates/lune-std-ffi/src/c/c_type.rs @@ -164,7 +164,7 @@ where if !data_handle.check_boundary(offset, ctype.get_size()) { return Err(LuaError::external("Out of bounds")); } - if !data_handle.check_readable(offset, ctype.get_size()) { + if !data_handle.is_readable() { return Err(LuaError::external("Unreadable data handle")); } @@ -187,7 +187,7 @@ where if !data_handle.check_boundary(offset, ctype.get_size()) { return Err(LuaError::external("Out of bounds")); } - if !data_handle.checek_writable(offset, ctype.get_size()) { + if !data_handle.is_writable() { return Err(LuaError::external("Unwritable data handle")); } diff --git a/crates/lune-std-ffi/src/ffi/ffi_box/flag.rs b/crates/lune-std-ffi/src/ffi/ffi_box/flag.rs index 34e712f5..dfb4757d 100644 --- a/crates/lune-std-ffi/src/ffi/ffi_box/flag.rs +++ b/crates/lune-std-ffi/src/ffi/ffi_box/flag.rs @@ -1,14 +1,12 @@ use super::super::bit_mask::*; pub enum FfiBoxFlag { - Dropped, Leaked, } impl FfiBoxFlag { pub const fn value(&self) -> u8 { match self { - Self::Dropped => U8_MASK1, Self::Leaked => U8_MASK2, } } diff --git a/crates/lune-std-ffi/src/ffi/ffi_box/mod.rs b/crates/lune-std-ffi/src/ffi/ffi_box/mod.rs index 6e61eeca..9832455f 100644 --- a/crates/lune-std-ffi/src/ffi/ffi_box/mod.rs +++ b/crates/lune-std-ffi/src/ffi/ffi_box/mod.rs @@ -6,7 +6,7 @@ use super::{ association_names::REF_INNER, bit_mask::*, ffi_association::set_association, - ffi_ref::{FfiRef, FfiRefBounds, FfiRefFlag, FfiRefFlagList}, + ffi_ref::{FfiRef, FfiRefBounds, FfiRefFlag}, NativeData, }; @@ -14,15 +14,9 @@ mod flag; pub use self::flag::FfiBoxFlag; -const BOX_REF_FLAGS: FfiRefFlagList = FfiRefFlagList::new( - FfiRefFlag::Offsetable.value() | FfiRefFlag::Readable.value() | FfiRefFlag::Writable.value(), -); -const BOX_MUT_REF_FLAGS: FfiRefFlagList = FfiRefFlagList::new( - FfiRefFlag::Offsetable.value() - | FfiRefFlag::Readable.value() - | FfiRefFlag::Writable.value() - | FfiRefFlag::Mutable.value(), -); +// Ref which created by lua should not be dereferenceable, +const BOX_REF_FLAGS: u8 = + FfiRefFlag::Readable.value() | FfiRefFlag::Writable.value() | FfiRefFlag::Offsetable.value(); // It is an untyped, sized memory area that Lua can manage. // This area is safe within Lua. Operations have their boundaries checked. @@ -143,6 +137,12 @@ impl NativeData for FfiBox { .cast_mut() .cast::<()>() } + fn is_readable(&self) -> bool { + true + } + fn is_writable(&self) -> bool { + true + } } impl LuaUserData for FfiBox { diff --git a/crates/lune-std-ffi/src/ffi/ffi_lib.rs b/crates/lune-std-ffi/src/ffi/ffi_lib.rs index 4d924621..8bc0524d 100644 --- a/crates/lune-std-ffi/src/ffi/ffi_lib.rs +++ b/crates/lune-std-ffi/src/ffi/ffi_lib.rs @@ -6,15 +6,13 @@ use mlua::prelude::*; use super::{ association_names::SYM_INNER, ffi_association::set_association, - ffi_ref::{FfiRef, FfiRefFlag, FfiRefFlagList, UNSIZED_BOUNDS}, + ffi_ref::{FfiRef, FfiRefFlag, UNSIZED_BOUNDS}, }; -const LIB_REF_FLAGS: FfiRefFlagList = FfiRefFlagList::new( - FfiRefFlag::Offsetable.value() - | FfiRefFlag::Readable.value() - | FfiRefFlag::Dereferenceable.value() - | FfiRefFlag::Function.value(), -); +const LIB_REF_FLAGS: u8 = FfiRefFlag::Offsetable.value() + | FfiRefFlag::Readable.value() + | FfiRefFlag::Dereferenceable.value() + | FfiRefFlag::Function.value(); pub struct FfiLib(Library); diff --git a/crates/lune-std-ffi/src/ffi/ffi_native/convert.rs b/crates/lune-std-ffi/src/ffi/ffi_native/convert.rs index 073b0802..4d493e13 100644 --- a/crates/lune-std-ffi/src/ffi/ffi_native/convert.rs +++ b/crates/lune-std-ffi/src/ffi/ffi_native/convert.rs @@ -12,7 +12,6 @@ pub trait NativeConvert { unsafe fn luavalue_into<'lua>( &self, lua: &'lua Lua, - // type_userdata: &LuaAnyUserData<'lua>, offset: isize, data_handle: &Ref, value: LuaValue<'lua>, @@ -22,7 +21,6 @@ pub trait NativeConvert { unsafe fn luavalue_from<'lua>( &self, lua: &'lua Lua, - // type_userdata: &LuaAnyUserData<'lua>, offset: isize, data_handle: &Ref, ) -> LuaResult>; diff --git a/crates/lune-std-ffi/src/ffi/ffi_native/data.rs b/crates/lune-std-ffi/src/ffi/ffi_native/data.rs index 471eb506..513ab937 100644 --- a/crates/lune-std-ffi/src/ffi/ffi_native/data.rs +++ b/crates/lune-std-ffi/src/ffi/ffi_native/data.rs @@ -8,6 +8,8 @@ use super::super::{FfiBox, FfiRef}; pub trait NativeData { fn check_boundary(&self, offset: isize, size: usize) -> bool; unsafe fn get_pointer(&self, offset: isize) -> *mut (); + fn is_writable(&self) -> bool; + fn is_readable(&self) -> bool; } pub trait GetNativeData { diff --git a/crates/lune-std-ffi/src/ffi/ffi_ref/flag.rs b/crates/lune-std-ffi/src/ffi/ffi_ref/flag.rs new file mode 100644 index 00000000..3271671b --- /dev/null +++ b/crates/lune-std-ffi/src/ffi/ffi_ref/flag.rs @@ -0,0 +1,22 @@ +use super::super::bit_mask::*; + +pub enum FfiRefFlag { + Leaked, + Dereferenceable, + Readable, + Writable, + Offsetable, + Function, +} +impl FfiRefFlag { + pub const fn value(&self) -> u8 { + match self { + Self::Leaked => U8_MASK1, + Self::Dereferenceable => U8_MASK2, + Self::Writable => U8_MASK3, + Self::Readable => U8_MASK4, + Self::Offsetable => U8_MASK5, + Self::Function => U8_MASK6, + } + } +} diff --git a/crates/lune-std-ffi/src/ffi/ffi_ref/flags.rs b/crates/lune-std-ffi/src/ffi/ffi_ref/flags.rs deleted file mode 100644 index b1dbfdee..00000000 --- a/crates/lune-std-ffi/src/ffi/ffi_ref/flags.rs +++ /dev/null @@ -1,84 +0,0 @@ -use super::super::bit_mask::*; - -pub enum FfiRefFlag { - // Dereferenceable, - // Readable, - // Writable, - // Offsetable, - // Function, - // Mutable, -} -impl FfiRefFlag { - pub const fn value(&self) -> u8 { - match self { - Self::Dereferenceable => U8_MASK1, - Self::Readable => U8_MASK2, - Self::Writable => U8_MASK3, - Self::Offsetable => U8_MASK4, - Self::Function => U8_MASK5, - Self::Mutable => U8_MASK6, - } - } -} - -pub struct FfiRefFlagList(u8); -#[allow(unused)] -impl FfiRefFlagList { - pub const fn zero() -> Self { - Self(0) - } - pub const fn new(flags: u8) -> Self { - Self(flags) - } - pub const fn all() -> Self { - Self( - FfiRefFlag::Dereferenceable.value() - | FfiRefFlag::Readable.value() - | FfiRefFlag::Writable.value() - | FfiRefFlag::Offsetable.value() - | FfiRefFlag::Function.value(), - ) - } - fn set(&mut self, value: bool, mask: u8) { - if value { - self.0 |= mask; - } else { - self.0 &= !mask; - } - } - pub fn is_dereferenceable(&self) -> bool { - U8_TEST!(self.0, FfiRefFlag::Dereferenceable.value()) - } - pub fn set_dereferenceable(&mut self, value: bool) { - self.set(value, FfiRefFlag::Dereferenceable.value()); - } - pub fn is_readable(&self) -> bool { - U8_TEST!(self.0, FfiRefFlag::Readable.value()) - } - pub fn set_readable(&mut self, value: bool) { - self.set(value, FfiRefFlag::Readable.value()); - } - pub fn is_writable(&self) -> bool { - U8_TEST!(self.0, FfiRefFlag::Writable.value()) - } - pub fn set_writable(&mut self, value: bool) { - self.set(value, FfiRefFlag::Writable.value()); - } - pub fn is_offsetable(&self) -> bool { - U8_TEST!(self.0, FfiRefFlag::Offsetable.value()) - } - pub fn set_offsetable(&mut self, value: bool) { - self.set(value, FfiRefFlag::Offsetable.value()); - } - pub fn is_mutable(&self) -> bool { - U8_TEST!(self.0, FfiRefFlag::Mutable.value()) - } - pub fn set_mutable(&mut self, value: bool) { - self.set(value, FfiRefFlag::Mutable.value()); - } -} -impl Clone for FfiRefFlagList { - fn clone(&self) -> Self { - Self(self.0) - } -} diff --git a/crates/lune-std-ffi/src/ffi/ffi_ref/mod.rs b/crates/lune-std-ffi/src/ffi/ffi_ref/mod.rs index d65178f7..d2332b5e 100644 --- a/crates/lune-std-ffi/src/ffi/ffi_ref/mod.rs +++ b/crates/lune-std-ffi/src/ffi/ffi_ref/mod.rs @@ -4,20 +4,21 @@ use mlua::prelude::*; use super::{ association_names::REF_INNER, + bit_mask::u8_test, ffi_association::{get_association, set_association}, NativeData, }; mod bounds; -mod flags; +mod flag; pub use self::{ bounds::{FfiRefBounds, UNSIZED_BOUNDS}, - flags::{FfiRefFlag, FfiRefFlagList}, + flag::FfiRefFlag, }; // Box:ref():ref() should not be able to modify, Only for external -const BOX_REF_REF_FLAGS: FfiRefFlagList = FfiRefFlagList::zero(); +const BOX_REF_REF_FLAGS: u8 = 0; // A referenced space. It is possible to read and write through types. // This operation is not safe. This may cause a memory error in Lua @@ -27,12 +28,12 @@ const BOX_REF_REF_FLAGS: FfiRefFlagList = FfiRefFlagList::zero(); pub struct FfiRef { ptr: *mut (), - pub flags: FfiRefFlagList, + pub flags: u8, pub boundary: FfiRefBounds, } impl FfiRef { - pub fn new(ptr: *mut (), flags: FfiRefFlagList, boundary: FfiRefBounds) -> Self { + pub fn new(ptr: *mut (), flags: u8, boundary: FfiRefBounds) -> Self { Self { ptr, flags, @@ -63,8 +64,7 @@ impl FfiRef { } pub unsafe fn deref(&self) -> LuaResult { - self.flags - .is_dereferenceable() + u8_test(self.flags, FfiRefFlag::Dereferenceable.value()) .then_some(()) .ok_or(LuaError::external("This pointer is not dereferenceable."))?; @@ -78,7 +78,7 @@ impl FfiRef { // FIXME flags Ok(Self::new( *self.ptr.cast::<*mut ()>(), - self.flags.clone(), + self.flags, UNSIZED_BOUNDS, )) } @@ -88,8 +88,7 @@ impl FfiRef { } pub unsafe fn offset(&self, offset: isize) -> LuaResult { - self.flags - .is_offsetable() + u8_test(self.flags, FfiRefFlag::Offsetable.value()) .then_some(()) .ok_or(LuaError::external("This pointer is not offsetable."))?; @@ -109,7 +108,7 @@ impl FfiRef { // TODO Ok(Self::new( self.ptr.byte_offset(offset), - self.flags.clone(), + self.flags, boundary, )) } @@ -122,6 +121,12 @@ impl NativeData for FfiRef { unsafe fn get_pointer(&self, offset: isize) -> *mut () { self.ptr.byte_offset(offset) } + fn is_readable(&self) -> bool { + u8_test(self.flags, FfiRefFlag::Readable.value()) + } + fn is_writable(&self) -> bool { + u8_test(self.flags, FfiRefFlag::Writable.value()) + } } impl LuaUserData for FfiRef { @@ -161,7 +166,7 @@ pub fn create_nullptr(lua: &Lua) -> LuaResult { // https://en.cppreference.com/w/cpp/types/nullptr_t lua.create_userdata(FfiRef::new( ptr::null_mut::<()>().cast(), - FfiRefFlagList::zero(), + 0, // usize::MAX means that nullptr is can be 'any' pointer type // We check size of inner data. give ffi.box(1):ref() as argument which typed as i32:ptr() will fail, // throw lua error