Remove unused codes and strange safety features (#243)

This commit is contained in:
qwreey 2024-09-06 11:06:21 +00:00
parent c656a486c4
commit 11bf0b6896
No known key found for this signature in database
GPG key ID: D28DB79297A214BD
28 changed files with 193 additions and 314 deletions

View file

@ -10,7 +10,7 @@ use super::{
};
use crate::ffi::{
ffi_association::{get_association, set_association},
FfiBox, GetNativeDataHandle, NativeConvert, NativeDataHandle, NativeSize,
FfiBox, GetNativeData, NativeConvert, NativeData, NativeSize,
};
// This is a series of some type.
@ -110,7 +110,7 @@ impl NativeConvert for CArr {
&self,
lua: &'lua Lua,
offset: isize,
data_handle: &Ref<dyn NativeDataHandle>,
data_handle: &Ref<dyn NativeData>,
value: LuaValue<'lua>,
) -> LuaResult<()> {
let LuaValue::Table(ref table) = value else {
@ -134,7 +134,7 @@ impl NativeConvert for CArr {
&self,
lua: &'lua Lua,
offset: isize,
data_handle: &Ref<dyn NativeDataHandle>,
data_handle: &Ref<dyn NativeData>,
) -> LuaResult<LuaValue<'lua>> {
let table = lua.create_table_with_capacity(self.length, 0)?;
for i in 0..self.length {
@ -187,9 +187,6 @@ impl LuaUserData for CArr {
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()) {
return Err(LuaError::external("Unreadable data handle"));
}
unsafe { this.luavalue_from(lua, offset, data_handle) }
},
@ -203,7 +200,7 @@ impl LuaUserData for CArr {
if !data_handle.check_boundary(offset, this.size) {
return Err(LuaError::external("Out of bounds"));
}
if !data_handle.checek_writable(offset, this.size) {
if !data_handle.is_writable() {
return Err(LuaError::external("Unwritable data handle"));
}

View file

@ -10,7 +10,7 @@ use super::{
};
use crate::ffi::{
ffi_association::{get_association, set_association},
FfiBox, GetNativeDataHandle, NativeConvert, NativeDataHandle, NativeSignedness, NativeSize,
FfiBox, GetNativeData, NativeConvert, NativeData, NativeSignedness, NativeSize,
FFI_STATUS_NAMES,
};
@ -135,7 +135,7 @@ impl NativeConvert for CStruct {
&self,
lua: &'lua Lua,
offset: isize,
data_handle: &Ref<dyn NativeDataHandle>,
data_handle: &Ref<dyn NativeData>,
value: LuaValue<'lua>,
) -> LuaResult<()> {
let LuaValue::Table(ref table) = value else {
@ -156,7 +156,7 @@ impl NativeConvert for CStruct {
&self,
lua: &'lua Lua,
offset: isize,
data_handle: &Ref<dyn NativeDataHandle>,
data_handle: &Ref<dyn NativeData>,
) -> LuaResult<LuaValue<'lua>> {
let table = lua.create_table_with_capacity(self.conv.len(), 0)?;
for (i, conv) in self.conv.iter().enumerate() {

View file

@ -9,8 +9,8 @@ use num::cast::AsPrimitive;
use super::{association_names::CTYPE_STATIC, c_helper::get_ensured_size, CArr, CPtr};
use crate::ffi::{
ffi_association::set_association, native_num_cast, FfiBox, GetNativeDataHandle, NativeConvert,
NativeDataHandle, NativeSignedness, NativeSize,
ffi_association::set_association, native_num_cast, FfiBox, GetNativeData, NativeConvert,
NativeData, NativeSignedness, NativeSize,
};
// We can't get a CType<T> through mlua, something like
@ -42,8 +42,8 @@ pub trait CTypeCast {
fn try_cast_num<T, U>(
&self,
ctype: &LuaAnyUserData,
from: &Ref<dyn NativeDataHandle>,
into: &Ref<dyn NativeDataHandle>,
from: &Ref<dyn NativeData>,
into: &Ref<dyn NativeData>,
) -> LuaResult<Option<()>>
where
T: AsPrimitive<U>,
@ -62,8 +62,8 @@ pub trait CTypeCast {
&self,
from_ctype: &LuaAnyUserData,
into_ctype: &LuaAnyUserData,
_from: &Ref<dyn NativeDataHandle>,
_into: &Ref<dyn NativeDataHandle>,
_from: &Ref<dyn NativeData>,
_into: &Ref<dyn NativeData>,
) -> LuaResult<()> {
Err(Self::cast_failed_with(self, from_ctype, into_ctype))
}

View file

@ -5,7 +5,7 @@ use mlua::prelude::*;
use num::cast::AsPrimitive;
use super::super::c_type::CType;
use crate::ffi::{NativeConvert, NativeDataHandle, NativeSignedness};
use crate::ffi::{NativeConvert, NativeData, NativeSignedness};
impl NativeSignedness for CType<f32> {
fn get_signedness(&self) -> bool {
@ -19,7 +19,7 @@ impl NativeConvert for CType<f32> {
_lua: &'lua Lua,
// _type_userdata: &LuaAnyUserData<'lua>,
offset: isize,
data_handle: &Ref<dyn NativeDataHandle>,
data_handle: &Ref<dyn NativeData>,
value: LuaValue<'lua>,
) -> LuaResult<()> {
let value: f32 = match value {
@ -46,7 +46,7 @@ impl NativeConvert for CType<f32> {
lua: &'lua Lua,
// _type_userdata: &LuaAnyUserData<'lua>,
offset: isize,
data_handle: &Ref<dyn NativeDataHandle>,
data_handle: &Ref<dyn NativeData>,
) -> LuaResult<LuaValue<'lua>> {
let value = unsafe { (*data_handle.get_pointer(offset).cast::<f32>()).into_lua(lua)? };
Ok(value)

View file

@ -5,7 +5,7 @@ use mlua::prelude::*;
use num::cast::AsPrimitive;
use super::super::c_type::CType;
use crate::ffi::{NativeConvert, NativeDataHandle, NativeSignedness};
use crate::ffi::{NativeConvert, NativeData, NativeSignedness};
impl NativeSignedness for CType<f64> {
fn get_signedness(&self) -> bool {
@ -19,7 +19,7 @@ impl NativeConvert for CType<f64> {
_lua: &'lua Lua,
// _type_userdata: &LuaAnyUserData<'lua>,
offset: isize,
data_handle: &Ref<dyn NativeDataHandle>,
data_handle: &Ref<dyn NativeData>,
value: LuaValue<'lua>,
) -> LuaResult<()> {
let value: f64 = match value {
@ -46,7 +46,7 @@ impl NativeConvert for CType<f64> {
lua: &'lua Lua,
// _type_userdata: &LuaAnyUserData<'lua>,
offset: isize,
data_handle: &Ref<dyn NativeDataHandle>,
data_handle: &Ref<dyn NativeData>,
) -> LuaResult<LuaValue<'lua>> {
let value = unsafe { (*data_handle.get_pointer(offset).cast::<f64>()).into_lua(lua)? };
Ok(value)

View file

@ -5,7 +5,7 @@ use mlua::prelude::*;
use num::cast::AsPrimitive;
use super::super::c_type::CType;
use crate::ffi::{NativeConvert, NativeDataHandle, NativeSignedness};
use crate::ffi::{NativeConvert, NativeData, NativeSignedness};
impl NativeSignedness for CType<i128> {
fn get_signedness(&self) -> bool {
@ -19,7 +19,7 @@ impl NativeConvert for CType<i128> {
_lua: &'lua Lua,
// _type_userdata: &LuaAnyUserData<'lua>,
offset: isize,
data_handle: &Ref<dyn NativeDataHandle>,
data_handle: &Ref<dyn NativeData>,
value: LuaValue<'lua>,
) -> LuaResult<()> {
let value: i128 = match value {
@ -46,7 +46,7 @@ impl NativeConvert for CType<i128> {
lua: &'lua Lua,
// _type_userdata: &LuaAnyUserData<'lua>,
offset: isize,
data_handle: &Ref<dyn NativeDataHandle>,
data_handle: &Ref<dyn NativeData>,
) -> LuaResult<LuaValue<'lua>> {
let value = unsafe { (*data_handle.get_pointer(offset).cast::<i128>()).into_lua(lua)? };
Ok(value)

View file

@ -5,7 +5,7 @@ use mlua::prelude::*;
use num::cast::AsPrimitive;
use super::super::c_type::CType;
use crate::ffi::{NativeConvert, NativeDataHandle, NativeSignedness};
use crate::ffi::{NativeConvert, NativeData, NativeSignedness};
impl NativeSignedness for CType<i16> {
fn get_signedness(&self) -> bool {
@ -19,7 +19,7 @@ impl NativeConvert for CType<i16> {
_lua: &'lua Lua,
// _type_userdata: &LuaAnyUserData<'lua>,
offset: isize,
data_handle: &Ref<dyn NativeDataHandle>,
data_handle: &Ref<dyn NativeData>,
value: LuaValue<'lua>,
) -> LuaResult<()> {
let value: i16 = match value {
@ -46,7 +46,7 @@ impl NativeConvert for CType<i16> {
lua: &'lua Lua,
// _type_userdata: &LuaAnyUserData<'lua>,
offset: isize,
data_handle: &Ref<dyn NativeDataHandle>,
data_handle: &Ref<dyn NativeData>,
) -> LuaResult<LuaValue<'lua>> {
let value = unsafe { (*data_handle.get_pointer(offset).cast::<i16>()).into_lua(lua)? };
Ok(value)

View file

@ -5,7 +5,7 @@ use mlua::prelude::*;
use num::cast::AsPrimitive;
use super::super::c_type::CType;
use crate::ffi::{NativeConvert, NativeDataHandle, NativeSignedness};
use crate::ffi::{NativeConvert, NativeData, NativeSignedness};
impl NativeSignedness for CType<i32> {
fn get_signedness(&self) -> bool {
@ -19,7 +19,7 @@ impl NativeConvert for CType<i32> {
_lua: &'lua Lua,
// _type_userdata: &LuaAnyUserData<'lua>,
offset: isize,
data_handle: &Ref<dyn NativeDataHandle>,
data_handle: &Ref<dyn NativeData>,
value: LuaValue<'lua>,
) -> LuaResult<()> {
let value: i32 = match value {
@ -46,7 +46,7 @@ impl NativeConvert for CType<i32> {
lua: &'lua Lua,
// _type_userdata: &LuaAnyUserData<'lua>,
offset: isize,
data_handle: &Ref<dyn NativeDataHandle>,
data_handle: &Ref<dyn NativeData>,
) -> LuaResult<LuaValue<'lua>> {
let value = unsafe { (*data_handle.get_pointer(offset).cast::<i32>()).into_lua(lua)? };
Ok(value)

View file

@ -5,7 +5,7 @@ use mlua::prelude::*;
use num::cast::AsPrimitive;
use super::super::c_type::CType;
use crate::ffi::{NativeConvert, NativeDataHandle, NativeSignedness};
use crate::ffi::{NativeConvert, NativeData, NativeSignedness};
impl NativeSignedness for CType<i64> {
fn get_signedness(&self) -> bool {
@ -19,7 +19,7 @@ impl NativeConvert for CType<i64> {
_lua: &'lua Lua,
// _type_userdata: &LuaAnyUserData<'lua>,
offset: isize,
data_handle: &Ref<dyn NativeDataHandle>,
data_handle: &Ref<dyn NativeData>,
value: LuaValue<'lua>,
) -> LuaResult<()> {
let value: i64 = match value {
@ -46,7 +46,7 @@ impl NativeConvert for CType<i64> {
lua: &'lua Lua,
// _type_userdata: &LuaAnyUserData<'lua>,
offset: isize,
data_handle: &Ref<dyn NativeDataHandle>,
data_handle: &Ref<dyn NativeData>,
) -> LuaResult<LuaValue<'lua>> {
let value = unsafe { (*data_handle.get_pointer(offset).cast::<i64>()).into_lua(lua)? };
Ok(value)

View file

@ -5,7 +5,7 @@ use mlua::prelude::*;
use num::cast::AsPrimitive;
use super::super::c_type::CType;
use crate::ffi::{NativeConvert, NativeDataHandle, NativeSignedness};
use crate::ffi::{NativeConvert, NativeData, NativeSignedness};
impl NativeSignedness for CType<i8> {
fn get_signedness(&self) -> bool {
@ -19,7 +19,7 @@ impl NativeConvert for CType<i8> {
_lua: &'lua Lua,
// _type_userdata: &LuaAnyUserData<'lua>,
offset: isize,
data_handle: &Ref<dyn NativeDataHandle>,
data_handle: &Ref<dyn NativeData>,
value: LuaValue<'lua>,
) -> LuaResult<()> {
let value: i8 = match value {
@ -42,7 +42,7 @@ impl NativeConvert for CType<i8> {
lua: &'lua Lua,
// _type_userdata: &LuaAnyUserData<'lua>,
offset: isize,
data_handle: &Ref<dyn NativeDataHandle>,
data_handle: &Ref<dyn NativeData>,
) -> LuaResult<LuaValue<'lua>> {
let value = unsafe { (*data_handle.get_pointer(offset).cast::<i8>()).into_lua(lua)? };
Ok(value)

View file

@ -5,7 +5,7 @@ use mlua::prelude::*;
use num::cast::AsPrimitive;
use super::super::c_type::CType;
use crate::ffi::{NativeConvert, NativeDataHandle, NativeSignedness};
use crate::ffi::{NativeConvert, NativeData, NativeSignedness};
impl NativeSignedness for CType<isize> {
fn get_signedness(&self) -> bool {
@ -19,7 +19,7 @@ impl NativeConvert for CType<isize> {
_lua: &'lua Lua,
// _type_userdata: &LuaAnyUserData<'lua>,
offset: isize,
data_handle: &Ref<dyn NativeDataHandle>,
data_handle: &Ref<dyn NativeData>,
value: LuaValue<'lua>,
) -> LuaResult<()> {
let value: isize = match value {
@ -46,7 +46,7 @@ impl NativeConvert for CType<isize> {
lua: &'lua Lua,
// _type_userdata: &LuaAnyUserData<'lua>,
offset: isize,
data_handle: &Ref<dyn NativeDataHandle>,
data_handle: &Ref<dyn NativeData>,
) -> LuaResult<LuaValue<'lua>> {
let value = unsafe { (*data_handle.get_pointer(offset).cast::<isize>()).into_lua(lua)? };
Ok(value)

View file

@ -8,7 +8,7 @@ use mlua::prelude::*;
use num::cast::AsPrimitive;
use super::{CType, CTypeCast};
use crate::ffi::{NativeConvert, NativeDataHandle};
use crate::ffi::{NativeConvert, NativeData};
pub mod f32;
pub mod f64;
@ -54,8 +54,8 @@ where
&self,
from_ctype: &LuaAnyUserData,
into_ctype: &LuaAnyUserData,
from: &Ref<dyn NativeDataHandle>,
into: &Ref<dyn NativeDataHandle>,
from: &Ref<dyn NativeData>,
into: &Ref<dyn NativeData>,
) -> LuaResult<()> {
cast_nums!(
T, self, into_ctype, from_ctype, from, into, u8, u16, u32, u64, u128, i8, i16, i128,
@ -128,106 +128,8 @@ pub fn create_all_types(lua: &Lua) -> LuaResult<Vec<(&'static str, LuaAnyUserDat
])
}
// macro_rules! define_ctype_size_from_userdata {
// ($t:ident, $f:ty, $( $c:ty ),*) => {
// if $t.is::<CType<$f>>() {
// Ok(size_of::<$f>())
// }$( else if $t.is::<CType<$c>>() {
// Ok(size_of::<$c>())
// })* else {
// Err(LuaError::external("Unexpected type"))
// }
// };
// }
// #[inline(always)]
// pub fn ctype_size_from_userdata(this: &LuaAnyUserData) -> LuaResult<usize> {
// define_ctype_size_from_userdata!(
// this, u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, f32, f64
// )
// }
// macro_rules! define_ctype_luavalue_into_ptr {
// ($lua:ident, $this:ident, $offset:ident, $data_handle:ident, $value:ident, $f:ty, $( $c:ty ),*) => {
// if $this.is::<CType<$f>>() {
// let ctype = $this.borrow::<CType<$f>>()?;
// ctype.luavalue_into($lua, $offset, $data_handle, $value)
// }$( else if $this.is::<CType<$c>>() {
// let ctype = $this.borrow::<CType<$c>>()?;
// ctype.luavalue_into($lua, $offset, $data_handle, $value)
// })* else {
// Err(LuaError::external("Unexpected type"))
// }
// };
// }
// #[inline(always)]
// pub unsafe fn ctype_luavalue_into_ptr<'lua>(
// lua: &'lua Lua,
// this: &LuaAnyUserData<'lua>,
// offset: isize,
// data_handle: &Ref<dyn NativeDataHandle>,
// value: LuaValue<'lua>,
// ) -> LuaResult<()> {
// define_ctype_luavalue_into_ptr!(
// lua,
// this,
// offset,
// data_handle,
// value,
// u8,
// u16,
// u32,
// u64,
// u128,
// i8,
// i16,
// i32,
// i64,
// i128,
// f32,
// f64
// )
// }
// macro_rules! define_ctype_luavalue_from_ptr {
// ($lua:ident, $this:ident, $offset:ident, $data_handle:ident, $f:ty, $( $c:ty ),*) => {
// if $this.is::<CType<$f>>() {
// $this.borrow::<CType<$f>>()?.luavalue_from($lua, $offset, $data_handle)
// }$( else if $this.is::<CType<$c>>() {
// $this.borrow::<CType<$c>>()?.luavalue_from($lua, $offset, $data_handle)
// })* else {
// Err(LuaError::external("Unexpected type"))
// }
// };
// }
// #[inline(always)]
// pub unsafe fn ctype_luavalue_from_ptr<'lua>(
// lua: &'lua Lua,
// this: &LuaAnyUserData<'lua>,
// offset: isize,
// data_handle: &Ref<dyn NativeDataHandle>,
// ) -> LuaResult<LuaValue<'lua>> {
// define_ctype_luavalue_from_ptr!(
// lua,
// this,
// offset,
// data_handle,
// u8,
// u16,
// u32,
// u64,
// u128,
// i8,
// i16,
// i32,
// i64,
// i128,
// f32,
// f64
// )
// }
// Use UB method, but safe. because we use ffi_association to ensure children alive
// Much faster then get NativeConvert handle everytime from lua table
// Use UB method, but safe. because we use ffi_association to ensure children keep alive
// Much faster then get NativeConvert handle every time from lua table
// it's spam of table.get(), if ud.is::<T>() { ud.borrow::<T>()? ... }
macro_rules! define_get_ctype_conv {
($userdata:ident, $f:ty, $( $c:ty ),*) => {

View file

@ -5,7 +5,7 @@ use mlua::prelude::*;
use num::cast::AsPrimitive;
use super::super::c_type::CType;
use crate::ffi::{NativeConvert, NativeDataHandle, NativeSignedness};
use crate::ffi::{NativeConvert, NativeData, NativeSignedness};
impl NativeSignedness for CType<u128> {
fn get_signedness(&self) -> bool {
@ -19,7 +19,7 @@ impl NativeConvert for CType<u128> {
_lua: &'lua Lua,
// _type_userdata: &LuaAnyUserData<'lua>,
offset: isize,
data_handle: &Ref<dyn NativeDataHandle>,
data_handle: &Ref<dyn NativeData>,
value: LuaValue<'lua>,
) -> LuaResult<()> {
let value: u128 = match value {
@ -46,7 +46,7 @@ impl NativeConvert for CType<u128> {
lua: &'lua Lua,
// _type_userdata: &LuaAnyUserData<'lua>,
offset: isize,
data_handle: &Ref<dyn NativeDataHandle>,
data_handle: &Ref<dyn NativeData>,
) -> LuaResult<LuaValue<'lua>> {
let value = unsafe { (*data_handle.get_pointer(offset).cast::<u128>()).into_lua(lua)? };
Ok(value)

View file

@ -5,7 +5,7 @@ use mlua::prelude::*;
use num::cast::AsPrimitive;
use super::super::c_type::CType;
use crate::ffi::{NativeConvert, NativeDataHandle, NativeSignedness};
use crate::ffi::{NativeConvert, NativeData, NativeSignedness};
impl NativeSignedness for CType<u16> {
fn get_signedness(&self) -> bool {
@ -20,7 +20,7 @@ impl NativeConvert for CType<u16> {
_lua: &'lua Lua,
// _type_userdata: &LuaAnyUserData<'lua>,
offset: isize,
data_handle: &Ref<dyn NativeDataHandle>,
data_handle: &Ref<dyn NativeData>,
value: LuaValue<'lua>,
) -> LuaResult<()> {
let value: u16 = match value {
@ -47,7 +47,7 @@ impl NativeConvert for CType<u16> {
lua: &'lua Lua,
// _type_userdata: &LuaAnyUserData<'lua>,
offset: isize,
data_handle: &Ref<dyn NativeDataHandle>,
data_handle: &Ref<dyn NativeData>,
) -> LuaResult<LuaValue<'lua>> {
let value = unsafe { (*data_handle.get_pointer(offset).cast::<u16>()).into_lua(lua)? };
Ok(value)

View file

@ -5,7 +5,7 @@ use mlua::prelude::*;
use num::cast::AsPrimitive;
use super::super::c_type::CType;
use crate::ffi::{NativeConvert, NativeDataHandle, NativeSignedness};
use crate::ffi::{NativeConvert, NativeData, NativeSignedness};
impl NativeSignedness for CType<u32> {
fn get_signedness(&self) -> bool {
@ -19,7 +19,7 @@ impl NativeConvert for CType<u32> {
_lua: &'lua Lua,
// _type_userdata: &LuaAnyUserData<'lua>,
offset: isize,
data_handle: &Ref<dyn NativeDataHandle>,
data_handle: &Ref<dyn NativeData>,
value: LuaValue<'lua>,
) -> LuaResult<()> {
let value: u32 = match value {
@ -46,7 +46,7 @@ impl NativeConvert for CType<u32> {
lua: &'lua Lua,
// _type_userdata: &LuaAnyUserData<'lua>,
offset: isize,
data_handle: &Ref<dyn NativeDataHandle>,
data_handle: &Ref<dyn NativeData>,
) -> LuaResult<LuaValue<'lua>> {
let value = unsafe { (*data_handle.get_pointer(offset).cast::<u32>()).into_lua(lua)? };
Ok(value)

View file

@ -5,7 +5,7 @@ use mlua::prelude::*;
use num::cast::AsPrimitive;
use super::super::c_type::CType;
use crate::ffi::{NativeConvert, NativeDataHandle, NativeSignedness};
use crate::ffi::{NativeConvert, NativeData, NativeSignedness};
impl NativeSignedness for CType<u64> {
fn get_signedness(&self) -> bool {
@ -19,7 +19,7 @@ impl NativeConvert for CType<u64> {
_lua: &'lua Lua,
// _type_userdata: &LuaAnyUserData<'lua>,
offset: isize,
data_handle: &Ref<dyn NativeDataHandle>,
data_handle: &Ref<dyn NativeData>,
value: LuaValue<'lua>,
) -> LuaResult<()> {
let value: u64 = match value {
@ -46,7 +46,7 @@ impl NativeConvert for CType<u64> {
lua: &'lua Lua,
// _type_userdata: &LuaAnyUserData<'lua>,
offset: isize,
data_handle: &Ref<dyn NativeDataHandle>,
data_handle: &Ref<dyn NativeData>,
) -> LuaResult<LuaValue<'lua>> {
let value = unsafe { (*data_handle.get_pointer(offset).cast::<u64>()).into_lua(lua)? };
Ok(value)

View file

@ -5,7 +5,7 @@ use mlua::prelude::*;
use num::cast::AsPrimitive;
use super::super::c_type::CType;
use crate::ffi::{NativeConvert, NativeDataHandle, NativeSignedness};
use crate::ffi::{NativeConvert, NativeData, NativeSignedness};
impl NativeSignedness for CType<u8> {
fn get_signedness(&self) -> bool {
@ -20,7 +20,7 @@ impl NativeConvert for CType<u8> {
_lua: &'lua Lua,
// _type_userdata: &LuaAnyUserData<'lua>,
offset: isize,
data_handle: &Ref<dyn NativeDataHandle>,
data_handle: &Ref<dyn NativeData>,
value: LuaValue<'lua>,
) -> LuaResult<()> {
let value: u8 = match value {
@ -45,7 +45,7 @@ impl NativeConvert for CType<u8> {
lua: &'lua Lua,
// _type_userdata: &LuaAnyUserData<'lua>,
offset: isize,
data_handle: &Ref<dyn NativeDataHandle>,
data_handle: &Ref<dyn NativeData>,
) -> LuaResult<LuaValue<'lua>> {
let value = unsafe { (*data_handle.get_pointer(offset).cast::<u8>()).into_lua(lua)? };
Ok(value)

View file

@ -5,7 +5,7 @@ use mlua::prelude::*;
use num::cast::AsPrimitive;
use super::super::c_type::CType;
use crate::ffi::{NativeConvert, NativeDataHandle, NativeSignedness};
use crate::ffi::{NativeConvert, NativeData, NativeSignedness};
impl NativeSignedness for CType<usize> {
fn get_signedness(&self) -> bool {
@ -19,7 +19,7 @@ impl NativeConvert for CType<usize> {
_lua: &'lua Lua,
// _type_userdata: &LuaAnyUserData<'lua>,
offset: isize,
data_handle: &Ref<dyn NativeDataHandle>,
data_handle: &Ref<dyn NativeData>,
value: LuaValue<'lua>,
) -> LuaResult<()> {
let value: usize = match value {
@ -46,7 +46,7 @@ impl NativeConvert for CType<usize> {
lua: &'lua Lua,
// _type_userdata: &LuaAnyUserData<'lua>,
offset: isize,
data_handle: &Ref<dyn NativeDataHandle>,
data_handle: &Ref<dyn NativeData>,
) -> LuaResult<LuaValue<'lua>> {
let value = unsafe { (*data_handle.get_pointer(offset).cast::<usize>()).into_lua(lua)? };
Ok(value)

View file

@ -0,0 +1,15 @@
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,
}
}
}

View file

@ -1,17 +1,28 @@
use std::boxed::Box;
use std::{alloc, alloc::Layout, boxed::Box, mem::ManuallyDrop, ptr};
use mlua::prelude::*;
use super::{
association_names::REF_INNER,
bit_mask::*,
ffi_association::set_association,
ffi_ref::{FfiRef, FfiRefBounds, FfiRefFlag, FfiRefFlagList, UNSIZED_BOUNDS},
NativeDataHandle,
ffi_ref::{FfiRef, FfiRefBounds, FfiRefFlag, FfiRefFlagList},
NativeData,
};
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(),
);
// It is an untyped, sized memory area that Lua can manage.
// This area is safe within Lua. Operations have their boundaries checked.
@ -22,46 +33,48 @@ const BOX_REF_FLAGS: FfiRefFlagList = FfiRefFlagList::new(
// rather, it creates more heap space, so it should be used appropriately
// where necessary.
struct RefData {
address: usize,
offset: usize,
lua_inner_id: i32,
pub struct FfiBox {
flags: u8,
data: ManuallyDrop<Box<[u8]>>,
}
pub struct FfiBox {
data: Box<[u8]>,
refs: Vec<RefData>,
}
const FFI_BOX_PRINT_MAX_LENGTH: usize = 1024;
impl FfiBox {
// For efficiency, it is initialized non-zeroed.
pub fn new(size: usize) -> Self {
// Create new vector to allocate heap memory. sized with 'size'
let mut vec_heap = Vec::<u8>::with_capacity(size);
// It is safe to have a length equal to the capacity
#[allow(clippy::uninit_vec)]
unsafe {
vec_heap.set_len(size);
}
let slice = unsafe {
Box::from_raw(ptr::slice_from_raw_parts_mut(
alloc::alloc(Layout::array::<u8>(size).unwrap()),
size,
))
};
Self {
data: vec_heap.into_boxed_slice(),
refs: vec![],
flags: 0,
data: ManuallyDrop::new(slice),
}
}
// pub fn copy(&self, target: &mut FfiBox) {}
// Todo: if too big, print as another format
pub fn stringify(&self) -> String {
if self.size() > FFI_BOX_PRINT_MAX_LENGTH * 2 {
// FIXME
// Todo: if too big, print as another format
return String::from("exceed");
}
let mut buff: String = String::with_capacity(self.size() * 2);
for value in &self.data {
for value in self.data.iter() {
buff.push_str(format!("{:x}", value.to_be()).as_str());
}
buff
}
pub fn leak(&mut self) {
self.flags = u8_set(self.flags, FfiBoxFlag::Leaked.value(), true);
}
// Make FfiRef from box, with boundary checking
pub fn luaref<'lua>(
lua: &'lua Lua,
@ -70,7 +83,7 @@ impl FfiBox {
) -> LuaResult<LuaAnyUserData<'lua>> {
let target = this.borrow::<FfiBox>()?;
let mut bounds = FfiRefBounds::new(0, target.size());
let mut ptr = target.get_ptr();
let mut ptr = unsafe { target.get_pointer(0) };
// Calculate offset
if let Some(t) = offset {
@ -81,14 +94,10 @@ impl FfiBox {
t
)));
}
ptr = unsafe { target.get_ptr().byte_offset(t) };
ptr = unsafe { target.get_pointer(t) };
bounds = bounds.offset(t);
}
// Lua should not be able to deref a box.
// To deref a box space is to allow lua to read any space,
// which has security issues and is ultimately dangerous.
// Therefore, box:ref():deref() is not allowed.
let luaref = lua.create_userdata(FfiRef::new(ptr.cast(), BOX_REF_FLAGS, bounds))?;
// Makes box alive longer then ref
@ -97,63 +106,42 @@ impl FfiBox {
Ok(luaref)
}
// Make FfiRef from box, without any safe features
pub fn luaref_unsafe<'lua>(
lua: &'lua Lua,
this: LuaAnyUserData<'lua>,
offset: Option<isize>,
) -> LuaResult<LuaAnyUserData<'lua>> {
let target = this.borrow::<FfiBox>()?;
let mut ptr = target.get_ptr();
// Calculate offset
if let Some(t) = offset {
ptr = unsafe { target.get_ptr().byte_offset(t) };
}
lua.create_userdata(FfiRef::new(
ptr.cast(),
FfiRefFlagList::all(),
UNSIZED_BOUNDS,
))
pub unsafe fn drop(&mut self) {
ManuallyDrop::drop(&mut self.data);
}
// Fill every field with 0
pub fn zero(&mut self) {
self.data.fill(0u8);
self.data.fill(0);
}
// Get size of box
pub fn size(&self) -> usize {
self.data.len()
}
}
// Get raw ptr
pub fn get_ptr(&self) -> *mut u8 {
self.data.as_ptr().cast_mut()
impl Drop for FfiBox {
fn drop(&mut self) {
if u8_test_not(self.flags, FfiBoxFlag::Leaked.value()) {
unsafe { self.drop() };
}
}
}
impl NativeDataHandle for FfiBox {
impl NativeData for FfiBox {
fn check_boundary(&self, offset: isize, size: usize) -> bool {
if offset < 0 {
return false;
}
self.size() > ((offset as usize) + size)
}
// FIXME
fn checek_writable(&self, offset: isize, size: usize) -> bool {
true
}
// FIXME
fn check_readable(&self, offset: isize, size: usize) -> bool {
true
}
fn mark_ref(&self, userdata: &LuaAnyUserData, offset: isize, ptr: usize) -> LuaResult<()> {
Ok(())
}
unsafe fn get_pointer(&self, offset: isize) -> *mut () {
self.get_ptr().byte_offset(offset).cast::<()>()
self.data
.as_ptr()
.byte_offset(offset)
.cast_mut()
.cast::<()>()
}
}
@ -167,18 +155,19 @@ impl LuaUserData for FfiBox {
this.borrow_mut::<FfiBox>()?.zero();
Ok(this)
});
methods.add_function_mut(
"leak",
|lua, (this, offset): (LuaAnyUserData, Option<isize>)| {
this.borrow_mut::<FfiBox>()?.leak();
FfiBox::luaref(lua, this, offset)
},
);
methods.add_function(
"ref",
|lua, (this, offset): (LuaAnyUserData, Option<isize>)| {
FfiBox::luaref(lua, this, offset)
},
);
methods.add_function(
"unsafeRef",
|lua, (this, offset): (LuaAnyUserData, Option<isize>)| {
FfiBox::luaref_unsafe(lua, this, offset)
},
);
methods.add_meta_method(LuaMetaMethod::ToString, |_, this, ()| Ok(this.stringify()));
}
}

View file

@ -2,7 +2,7 @@ use std::cell::Ref;
use mlua::prelude::*;
use super::NativeDataHandle;
use super::NativeData;
// Handle native data, provide type conversion between luavalue and native types
pub trait NativeCall {
@ -11,7 +11,7 @@ pub trait NativeCall {
&self,
lua: &Lua,
arg: LuaMultiValue,
ret: &Ref<dyn NativeDataHandle>,
ret: &Ref<dyn NativeData>,
) -> LuaResult<()>;
// Call lua closure

View file

@ -5,14 +5,14 @@ use std::cell::Ref;
use mlua::prelude::*;
use num::cast::AsPrimitive;
use super::NativeDataHandle;
use super::NativeData;
// Cast T as U
#[inline(always)]
pub fn native_num_cast<T, U>(
from: &Ref<dyn NativeDataHandle>,
into: &Ref<dyn NativeDataHandle>,
from: &Ref<dyn NativeData>,
into: &Ref<dyn NativeData>,
) -> LuaResult<()>
where
T: AsPrimitive<U>,

View file

@ -4,7 +4,7 @@ use std::cell::Ref;
use mlua::prelude::*;
use super::NativeDataHandle;
use super::NativeData;
// Handle native data, provide type conversion between luavalue and native types
pub trait NativeConvert {
@ -14,7 +14,7 @@ pub trait NativeConvert {
lua: &'lua Lua,
// type_userdata: &LuaAnyUserData<'lua>,
offset: isize,
data_handle: &Ref<dyn NativeDataHandle>,
data_handle: &Ref<dyn NativeData>,
value: LuaValue<'lua>,
) -> LuaResult<()>;
@ -24,6 +24,6 @@ pub trait NativeConvert {
lua: &'lua Lua,
// type_userdata: &LuaAnyUserData<'lua>,
offset: isize,
data_handle: &Ref<dyn NativeDataHandle>,
data_handle: &Ref<dyn NativeData>,
) -> LuaResult<LuaValue<'lua>>;
}

View file

@ -5,28 +5,25 @@ use mlua::prelude::*;
use super::super::{FfiBox, FfiRef};
pub trait NativeDataHandle {
pub trait NativeData {
fn check_boundary(&self, offset: isize, size: usize) -> bool;
fn check_readable(&self, offset: isize, size: usize) -> bool;
fn checek_writable(&self, offset: isize, size: usize) -> bool;
fn mark_ref(&self, userdata: &LuaAnyUserData, offset: isize, ptr: usize) -> LuaResult<()>;
unsafe fn get_pointer(&self, offset: isize) -> *mut ();
}
pub trait GetNativeDataHandle {
fn get_data_handle(&self) -> LuaResult<Ref<dyn NativeDataHandle>>;
pub trait GetNativeData {
fn get_data_handle(&self) -> LuaResult<Ref<dyn NativeData>>;
}
// I tried to remove dyn (which have little bit costs)
// But, maybe this is best option for now.
// If remove dyn, we must spam self.is::<>() / self.borrow::<>()?
// more costly....
impl GetNativeDataHandle for LuaAnyUserData<'_> {
fn get_data_handle(&self) -> LuaResult<Ref<dyn NativeDataHandle>> {
impl GetNativeData for LuaAnyUserData<'_> {
fn get_data_handle(&self) -> LuaResult<Ref<dyn NativeData>> {
if self.is::<FfiBox>() {
Ok(self.borrow::<FfiBox>()? as Ref<dyn NativeDataHandle>)
Ok(self.borrow::<FfiBox>()? as Ref<dyn NativeData>)
} else if self.is::<FfiRef>() {
Ok(self.borrow::<FfiRef>()? as Ref<dyn NativeDataHandle>)
Ok(self.borrow::<FfiRef>()? as Ref<dyn NativeData>)
// } else if self.is::<FfiRaw>() {
// Ok(self.borrow::<FfiRaw>()? as Ref<dyn ReadWriteHandle>)
} else {

View file

@ -1,7 +1,7 @@
mod call;
mod cast;
mod convert;
mod readwrite;
mod data;
pub trait NativeSize {
fn get_size(&self) -> usize;
@ -14,6 +14,6 @@ pub trait NativeSignedness {
}
pub use self::{
call::NativeCall, cast::native_num_cast, convert::NativeConvert,
readwrite::GetNativeDataHandle, readwrite::NativeDataHandle,
call::NativeCall, cast::native_num_cast, convert::NativeConvert, data::GetNativeData,
data::NativeData,
};

View file

@ -1,11 +1,12 @@
use super::super::bit_mask::*;
pub enum FfiRefFlag {
Dereferenceable,
Readable,
Writable,
Offsetable,
Function,
// Dereferenceable,
// Readable,
// Writable,
// Offsetable,
// Function,
// Mutable,
}
impl FfiRefFlag {
pub const fn value(&self) -> u8 {
@ -15,6 +16,7 @@ impl FfiRefFlag {
Self::Writable => U8_MASK3,
Self::Offsetable => U8_MASK4,
Self::Function => U8_MASK5,
Self::Mutable => U8_MASK6,
}
}
}
@ -45,28 +47,34 @@ impl FfiRefFlagList {
}
}
pub fn is_dereferenceable(&self) -> bool {
U8_TEST!(self.0, U8_MASK1)
U8_TEST!(self.0, FfiRefFlag::Dereferenceable.value())
}
pub fn set_dereferenceable(&mut self, value: bool) {
self.set(value, U8_MASK1);
self.set(value, FfiRefFlag::Dereferenceable.value());
}
pub fn is_readable(&self) -> bool {
U8_TEST!(self.0, U8_MASK2)
U8_TEST!(self.0, FfiRefFlag::Readable.value())
}
pub fn set_readable(&mut self, value: bool) {
self.set(value, U8_MASK2);
self.set(value, FfiRefFlag::Readable.value());
}
pub fn is_writable(&self) -> bool {
U8_TEST!(self.0, U8_MASK3)
U8_TEST!(self.0, FfiRefFlag::Writable.value())
}
pub fn set_writable(&mut self, value: bool) {
self.set(value, U8_MASK2);
self.set(value, FfiRefFlag::Writable.value());
}
pub fn is_offsetable(&self) -> bool {
U8_TEST!(self.0, U8_MASK4)
U8_TEST!(self.0, FfiRefFlag::Offsetable.value())
}
pub fn set_offsetable(&mut self, value: bool) {
self.set(value, U8_MASK2);
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 {

View file

@ -5,7 +5,7 @@ use mlua::prelude::*;
use super::{
association_names::REF_INNER,
ffi_association::{get_association, set_association},
NativeDataHandle,
NativeData,
};
mod bounds;
@ -29,17 +29,14 @@ pub struct FfiRef {
ptr: *mut (),
pub flags: FfiRefFlagList,
pub boundary: FfiRefBounds,
// Save lua ffibox pointer
pub inner: Option<*const dyn NativeDataHandle>,
}
impl FfiRef {
pub fn new(ptr: *mut (), flags: FfiRefFlagList, range: FfiRefBounds) -> Self {
pub fn new(ptr: *mut (), flags: FfiRefFlagList, boundary: FfiRefBounds) -> Self {
Self {
ptr,
flags,
boundary: range,
inner: None,
boundary,
}
}
@ -65,10 +62,6 @@ impl FfiRef {
Ok(luaref)
}
pub fn get_ptr(&self) -> *mut () {
self.ptr
}
pub unsafe fn deref(&self) -> LuaResult<Self> {
self.flags
.is_dereferenceable()
@ -122,41 +115,12 @@ impl FfiRef {
}
}
impl NativeDataHandle for FfiRef {
impl NativeData for FfiRef {
fn check_boundary(&self, offset: isize, size: usize) -> bool {
self.boundary.check_sized(offset, size)
}
fn checek_writable(&self, offset: isize, size: usize) -> bool {
// If unreadable ref
if !self.flags.is_writable() {
return false;
}
// If ref have inner luabox
if let Some(inner) = self.inner {
return unsafe { inner.as_ref().unwrap().checek_writable(offset, size) };
}
true
}
fn check_readable(&self, offset: isize, size: usize) -> bool {
// If unreadable ref
if !self.flags.is_readable() {
return false;
}
// If ref have inner luabox
if let Some(inner) = self.inner {
return unsafe { inner.as_ref().unwrap().check_readable(offset, size) };
}
true
}
fn mark_ref(&self, userdata: &LuaAnyUserData, offset: isize, ptr: usize) -> LuaResult<()> {
Ok(())
}
unsafe fn get_pointer(&self, offset: isize) -> *mut () {
self.get_ptr().byte_offset(offset)
self.ptr.byte_offset(offset)
}
}

View file

@ -11,8 +11,7 @@ pub use self::{
ffi_box::FfiBox,
ffi_lib::FfiLib,
ffi_native::{
native_num_cast, GetNativeDataHandle, NativeConvert, NativeDataHandle, NativeSignedness,
NativeSize,
native_num_cast, GetNativeData, NativeConvert, NativeData, NativeSignedness, NativeSize,
},
ffi_ref::{create_nullptr, FfiRef},
};
@ -42,13 +41,21 @@ pub mod bit_mask {
pub const U8_MASK7: u8 = 64;
pub const U8_MASK8: u8 = 128;
macro_rules! U8_TEST {
($val:expr, $mask:ident) => {
($val & $mask != 0)
};
pub fn u8_test(bits: u8, mask: u8) -> bool {
bits & mask != 0
}
pub(crate) use U8_TEST;
pub fn u8_test_not(bits: u8, mask: u8) -> bool {
bits & mask == 0
}
pub fn u8_set(bits: u8, mask: u8, val: bool) -> u8 {
if val {
bits | mask
} else {
bits & !mask
}
}
}
pub fn is_integer(num: LuaValue) -> bool {