From 94d8d079c412311751748503bf37e61ac290948b Mon Sep 17 00:00:00 2001 From: qwreey Date: Mon, 2 Sep 2024 10:14:34 +0000 Subject: [PATCH] Add is_integer (#243) --- crates/lune-std-ffi/src/c/c_helper.rs | 2 +- crates/lune-std-ffi/src/ffi/ffi_box.rs | 28 +++++++++++-------- crates/lune-std-ffi/src/ffi/ffi_func.rs | 3 ++ crates/lune-std-ffi/src/ffi/ffi_lib.rs | 2 +- .../lune-std-ffi/src/ffi/ffi_native/call.rs | 19 +++++++++++++ crates/lune-std-ffi/src/ffi/ffi_native/mod.rs | 5 ++-- crates/lune-std-ffi/src/ffi/mod.rs | 6 ++++ crates/lune-std-ffi/src/lib.rs | 5 ++-- 8 files changed, 52 insertions(+), 18 deletions(-) create mode 100644 crates/lune-std-ffi/src/ffi/ffi_native/call.rs diff --git a/crates/lune-std-ffi/src/c/c_helper.rs b/crates/lune-std-ffi/src/c/c_helper.rs index d072bd4..3338c72 100644 --- a/crates/lune-std-ffi/src/c/c_helper.rs +++ b/crates/lune-std-ffi/src/c/c_helper.rs @@ -12,7 +12,7 @@ use super::{ use crate::ffi::{ffi_association::get_association, NativeConvert, FFI_STATUS_NAMES}; // Get the NativeConvert handle from the type UserData -// this is intended to avoid constant table lookups. (eg: struct) +// this is intended to avoid lookup userdata and lua table every time. (eg: struct) // userdata must live longer than the NativeConvert handle. // However, c_struct is a strong reference to each field, so this is not a problem. pub unsafe fn get_conv(userdata: &LuaAnyUserData) -> LuaResult<*const dyn NativeConvert> { diff --git a/crates/lune-std-ffi/src/ffi/ffi_box.rs b/crates/lune-std-ffi/src/ffi/ffi_box.rs index 63c1f1e..f769666 100644 --- a/crates/lune-std-ffi/src/ffi/ffi_box.rs +++ b/crates/lune-std-ffi/src/ffi/ffi_box.rs @@ -1,5 +1,5 @@ use std::boxed::Box; -use std::sync::LazyLock; +use std::sync::OnceLock; use mlua::prelude::*; @@ -10,13 +10,18 @@ use super::{ NativeDataHandle, }; -static BOX_REF_FLAGS: LazyLock = LazyLock::new(|| { - FfiRefFlagList::new(&[ - FfiRefFlag::Offsetable, - FfiRefFlag::Readable, - FfiRefFlag::Writable, - ]) -}); +static BOX_REF_FLAGS: OnceLock = OnceLock::new(); +fn get_box_ref_flags() -> FfiRefFlagList { + BOX_REF_FLAGS + .get_or_init(|| { + FfiRefFlagList::new(&[ + FfiRefFlag::Offsetable, + FfiRefFlag::Readable, + FfiRefFlag::Writable, + ]) + }) + .to_owned() +} // It is an untyped, sized memory area that Lua can manage. // This area is safe within Lua. Operations have their boundaries checked. @@ -93,8 +98,7 @@ impl FfiBox { // 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).clone(), bounds))?; + let luaref = lua.create_userdata(FfiRef::new(ptr.cast(), get_box_ref_flags(), bounds))?; // Makes box alive longer then ref set_association(lua, REF_INNER, &luaref, &this)?; @@ -114,7 +118,7 @@ impl FfiBox { // Get raw ptr pub fn get_ptr(&self) -> *mut u8 { - self.data.as_ptr() as *mut u8 + self.data.as_ptr().cast_mut() } } @@ -134,7 +138,7 @@ impl NativeDataHandle for FfiBox { true } unsafe fn get_pointer(&self, offset: isize) -> *mut () { - self.get_ptr().byte_offset(offset) as *mut () + self.get_ptr().byte_offset(offset).cast::<()>() } } diff --git a/crates/lune-std-ffi/src/ffi/ffi_func.rs b/crates/lune-std-ffi/src/ffi/ffi_func.rs index e69de29..2126bc5 100644 --- a/crates/lune-std-ffi/src/ffi/ffi_func.rs +++ b/crates/lune-std-ffi/src/ffi/ffi_func.rs @@ -0,0 +1,3 @@ +struct FfiFunc { + args: Vec, +} diff --git a/crates/lune-std-ffi/src/ffi/ffi_lib.rs b/crates/lune-std-ffi/src/ffi/ffi_lib.rs index 14d2cec..6b5180a 100644 --- a/crates/lune-std-ffi/src/ffi/ffi_lib.rs +++ b/crates/lune-std-ffi/src/ffi/ffi_lib.rs @@ -64,7 +64,7 @@ impl FfiLib { impl LuaUserData for FfiLib { fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { - methods.add_function("dlsym", |lua, (this, name): (LuaAnyUserData, String)| { + methods.add_function("find", |lua, (this, name): (LuaAnyUserData, String)| { let luasym = FfiLib::get_sym(lua, this, name)?; Ok(luasym) }); diff --git a/crates/lune-std-ffi/src/ffi/ffi_native/call.rs b/crates/lune-std-ffi/src/ffi/ffi_native/call.rs new file mode 100644 index 0000000..b551484 --- /dev/null +++ b/crates/lune-std-ffi/src/ffi/ffi_native/call.rs @@ -0,0 +1,19 @@ +use std::cell::Ref; + +use mlua::prelude::*; + +use super::NativeDataHandle; + +// Handle native data, provide type conversion between luavalue and native types +pub trait NativeCall { + // Call native function + unsafe fn call_native( + &self, + lua: &Lua, + arg: LuaMultiValue, + ret: &Ref, + ) -> LuaResult<()>; + + // Call lua closure + unsafe fn call_lua(&self, lua: &Lua, arg: LuaMultiValue, ret: *mut ()) -> LuaResult<()>; +} diff --git a/crates/lune-std-ffi/src/ffi/ffi_native/mod.rs b/crates/lune-std-ffi/src/ffi/ffi_native/mod.rs index e083fe5..9ecfe3e 100644 --- a/crates/lune-std-ffi/src/ffi/ffi_native/mod.rs +++ b/crates/lune-std-ffi/src/ffi/ffi_native/mod.rs @@ -1,3 +1,4 @@ +mod call; mod cast; mod convert; mod readwrite; @@ -13,6 +14,6 @@ pub trait NativeSignedness { } pub use self::{ - cast::native_num_cast, convert::NativeConvert, readwrite::GetNativeDataHandle, - readwrite::NativeDataHandle, + call::NativeCall, cast::native_num_cast, convert::NativeConvert, + readwrite::GetNativeDataHandle, readwrite::NativeDataHandle, }; diff --git a/crates/lune-std-ffi/src/ffi/mod.rs b/crates/lune-std-ffi/src/ffi/mod.rs index 3eb02f9..1526316 100644 --- a/crates/lune-std-ffi/src/ffi/mod.rs +++ b/crates/lune-std-ffi/src/ffi/mod.rs @@ -5,6 +5,8 @@ mod ffi_native; mod ffi_raw; mod ffi_ref; +use mlua::prelude::*; + pub use self::{ ffi_box::FfiBox, ffi_lib::FfiLib, @@ -48,3 +50,7 @@ pub mod bit_mask { pub(crate) use U8_TEST; } + +pub fn is_integer(num: LuaValue) -> bool { + num.is_integer() +} diff --git a/crates/lune-std-ffi/src/lib.rs b/crates/lune-std-ffi/src/lib.rs index 18b6c24..ad1aad0 100644 --- a/crates/lune-std-ffi/src/lib.rs +++ b/crates/lune-std-ffi/src/lib.rs @@ -8,7 +8,7 @@ mod ffi; use crate::{ c::{create_all_c_types, create_all_types, CFn, CStruct}, - ffi::{create_nullptr, FfiBox, FfiLib}, + ffi::{create_nullptr, is_integer, FfiBox, FfiLib}, }; /** @@ -25,7 +25,7 @@ pub fn module(lua: &Lua) -> LuaResult { .with_value("nullptr", create_nullptr(lua)?)? .with_function("box", |_, size: usize| Ok(FfiBox::new(size)))? // TODO: discuss about function name. matching with io.open is better? - .with_function("dlopen", |_, name: String| { + .with_function("open", |_, name: String| { let lib = FfiLib::new(name)?; Ok(lib) })? @@ -33,6 +33,7 @@ pub fn module(lua: &Lua) -> LuaResult { let cstruct = CStruct::new_from_lua_table(lua, types)?; Ok(cstruct) })? + .with_function("isInteger", |_lua, num: LuaValue| Ok(is_integer(num)))? .with_function("fn", |lua, (args, ret): (LuaTable, LuaAnyUserData)| { let cfn = CFn::new_from_lua_table(lua, args, ret)?; Ok(cfn)