mirror of
https://github.com/lune-org/lune.git
synced 2025-04-10 21:40:54 +01:00
Use CType<T> instead of CType (#243)
This commit is contained in:
parent
26706d9355
commit
d60a1b99f6
9 changed files with 128 additions and 202 deletions
|
@ -1,3 +1,5 @@
|
||||||
|
use std::any::Any;
|
||||||
|
|
||||||
use libffi::middle::Type;
|
use libffi::middle::Type;
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
|
|
||||||
|
@ -54,13 +56,13 @@ impl CArr {
|
||||||
Ok(carr)
|
Ok(carr)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_type(&self) -> Type {
|
pub fn get_type(&self) -> &Type {
|
||||||
self.struct_type.clone()
|
&self.struct_type
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub fn get_element_type(&self) -> Type {
|
pub fn get_element_type(&self) -> &Type {
|
||||||
// self.element_type.clone()
|
&self.element_type
|
||||||
// }
|
}
|
||||||
|
|
||||||
// Stringify cstruct for pretty printing something like:
|
// Stringify cstruct for pretty printing something like:
|
||||||
// <CStruct( u8, i32, size = 8 )>
|
// <CStruct( u8, i32, size = 8 )>
|
||||||
|
@ -73,7 +75,7 @@ impl CArr {
|
||||||
.as_userdata()
|
.as_userdata()
|
||||||
.ok_or(LuaError::external("failed to get inner type userdata."))?;
|
.ok_or(LuaError::external("failed to get inner type userdata."))?;
|
||||||
|
|
||||||
if inner.is::<CType>() {
|
if inner.is::<CType<dyn Any>>() {
|
||||||
Ok(format!(
|
Ok(format!(
|
||||||
" {} ; {} ",
|
" {} ; {} ",
|
||||||
stringify_userdata(inner)?,
|
stringify_userdata(inner)?,
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use std::any::Any;
|
||||||
use std::ptr::{self, null_mut};
|
use std::ptr::{self, null_mut};
|
||||||
|
|
||||||
use libffi::{low, middle::Type, raw};
|
use libffi::{low, middle::Type, raw};
|
||||||
|
@ -37,11 +38,11 @@ pub fn type_list_from_table(table: &LuaTable) -> LuaResult<Vec<Type>> {
|
||||||
// get libffi_type from any c-type userdata
|
// get libffi_type from any c-type userdata
|
||||||
pub fn type_from_userdata(userdata: &LuaAnyUserData) -> LuaResult<Type> {
|
pub fn type_from_userdata(userdata: &LuaAnyUserData) -> LuaResult<Type> {
|
||||||
if userdata.is::<CStruct>() {
|
if userdata.is::<CStruct>() {
|
||||||
Ok(userdata.borrow::<CStruct>()?.get_type())
|
Ok(userdata.borrow::<CStruct>()?.get_type().to_owned())
|
||||||
} else if userdata.is::<CType>() {
|
} else if userdata.is::<CType<dyn Any>>() {
|
||||||
Ok(userdata.borrow::<CType>()?.get_type())
|
Ok(userdata.borrow::<CType<dyn Any>>()?.get_type().to_owned())
|
||||||
} else if userdata.is::<CArr>() {
|
} else if userdata.is::<CArr>() {
|
||||||
Ok(userdata.borrow::<CArr>()?.get_type())
|
Ok(userdata.borrow::<CArr>()?.get_type().to_owned())
|
||||||
} else if userdata.is::<CPtr>() {
|
} else if userdata.is::<CPtr>() {
|
||||||
Ok(CPtr::get_type())
|
Ok(CPtr::get_type())
|
||||||
} else {
|
} else {
|
||||||
|
@ -59,9 +60,10 @@ pub fn type_from_userdata(userdata: &LuaAnyUserData) -> LuaResult<Type> {
|
||||||
|
|
||||||
// stringify any c-type userdata (for recursive)
|
// stringify any c-type userdata (for recursive)
|
||||||
pub fn stringify_userdata(userdata: &LuaAnyUserData) -> LuaResult<String> {
|
pub fn stringify_userdata(userdata: &LuaAnyUserData) -> LuaResult<String> {
|
||||||
if userdata.is::<CType>() {
|
if userdata.is::<CType<dyn Any>>() {
|
||||||
let name = userdata.borrow::<CType>()?.stringify();
|
Ok(String::from(
|
||||||
Ok(name)
|
userdata.borrow::<CType<dyn Any>>()?.stringify(),
|
||||||
|
))
|
||||||
} else if userdata.is::<CStruct>() {
|
} else if userdata.is::<CStruct>() {
|
||||||
let name = CStruct::stringify(userdata)?;
|
let name = CStruct::stringify(userdata)?;
|
||||||
Ok(name)
|
Ok(name)
|
||||||
|
@ -80,7 +82,7 @@ pub fn stringify_userdata(userdata: &LuaAnyUserData) -> LuaResult<String> {
|
||||||
pub fn name_from_userdata(userdata: &LuaAnyUserData) -> String {
|
pub fn name_from_userdata(userdata: &LuaAnyUserData) -> String {
|
||||||
if userdata.is::<CStruct>() {
|
if userdata.is::<CStruct>() {
|
||||||
String::from("CStruct")
|
String::from("CStruct")
|
||||||
} else if userdata.is::<CType>() {
|
} else if userdata.is::<CType<dyn Any>>() {
|
||||||
String::from("CType")
|
String::from("CType")
|
||||||
} else if userdata.is::<CArr>() {
|
} else if userdata.is::<CArr>() {
|
||||||
String::from("CArr")
|
String::from("CArr")
|
||||||
|
|
|
@ -1,12 +1,9 @@
|
||||||
#![allow(clippy::cargo_common_metadata)]
|
#![allow(clippy::cargo_common_metadata)]
|
||||||
|
|
||||||
use std::{borrow::Borrow, vec::Vec};
|
use std::any::Any;
|
||||||
|
use std::vec::Vec;
|
||||||
|
|
||||||
use libffi::{
|
use libffi::{low, middle::Type, raw};
|
||||||
low,
|
|
||||||
middle::{Cif, Type},
|
|
||||||
raw,
|
|
||||||
};
|
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
|
|
||||||
use super::association_names::CSTRUCT_INNER;
|
use super::association_names::CSTRUCT_INNER;
|
||||||
|
@ -20,14 +17,14 @@ use crate::ffi::ffi_helper::FFI_STATUS_NAMES;
|
||||||
pub struct CStruct {
|
pub struct CStruct {
|
||||||
// libffi_cif: Cif,
|
// libffi_cif: Cif,
|
||||||
fields: Vec<Type>,
|
fields: Vec<Type>,
|
||||||
libffi_type: Type,
|
struct_type: Type,
|
||||||
offsets: Vec<usize>,
|
offsets: Vec<usize>,
|
||||||
size: usize,
|
size: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CStruct {
|
impl CStruct {
|
||||||
pub fn new(fields: Vec<Type>) -> LuaResult<Self> {
|
pub fn new(fields: Vec<Type>) -> LuaResult<Self> {
|
||||||
let libffi_type = Type::structure(fields.iter().cloned());
|
let struct_type = Type::structure(fields.iter().cloned());
|
||||||
// let libffi_cfi = Cif::new(vec![libffi_type.clone()], Type::void());
|
// let libffi_cfi = Cif::new(vec![libffi_type.clone()], Type::void());
|
||||||
|
|
||||||
// Get field offsets with ffi_get_struct_offsets
|
// Get field offsets with ffi_get_struct_offsets
|
||||||
|
@ -35,7 +32,7 @@ impl CStruct {
|
||||||
unsafe {
|
unsafe {
|
||||||
let offset_result: raw::ffi_status = raw::ffi_get_struct_offsets(
|
let offset_result: raw::ffi_status = raw::ffi_get_struct_offsets(
|
||||||
low::ffi_abi_FFI_DEFAULT_ABI,
|
low::ffi_abi_FFI_DEFAULT_ABI,
|
||||||
libffi_type.as_raw_ptr(),
|
struct_type.as_raw_ptr(),
|
||||||
offsets.as_mut_ptr(),
|
offsets.as_mut_ptr(),
|
||||||
);
|
);
|
||||||
if offset_result != raw::ffi_status_FFI_OK {
|
if offset_result != raw::ffi_status_FFI_OK {
|
||||||
|
@ -49,12 +46,12 @@ impl CStruct {
|
||||||
|
|
||||||
// Get tailing padded size of struct
|
// Get tailing padded size of struct
|
||||||
// See http://www.chiark.greenend.org.uk/doc/libffi-dev/html/Size-and-Alignment.html
|
// See http://www.chiark.greenend.org.uk/doc/libffi-dev/html/Size-and-Alignment.html
|
||||||
let size = unsafe { (*libffi_type.as_raw_ptr()).size };
|
let size = unsafe { (*struct_type.as_raw_ptr()).size };
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
// libffi_cif: libffi_cfi,
|
// libffi_cif: libffi_cfi,
|
||||||
fields,
|
fields,
|
||||||
libffi_type,
|
struct_type,
|
||||||
offsets,
|
offsets,
|
||||||
size,
|
size,
|
||||||
})
|
})
|
||||||
|
@ -85,7 +82,7 @@ impl CStruct {
|
||||||
let mut result = String::from(" ");
|
let mut result = String::from(" ");
|
||||||
for i in 0..table.raw_len() {
|
for i in 0..table.raw_len() {
|
||||||
let child: LuaAnyUserData = table.raw_get(i + 1)?;
|
let child: LuaAnyUserData = table.raw_get(i + 1)?;
|
||||||
if child.is::<CType>() {
|
if child.is::<CType<dyn Any>>() {
|
||||||
result.push_str(format!("{}, ", stringify_userdata(&child)?).as_str());
|
result.push_str(format!("{}, ", stringify_userdata(&child)?).as_str());
|
||||||
} else {
|
} else {
|
||||||
result.push_str(
|
result.push_str(
|
||||||
|
@ -117,8 +114,12 @@ impl CStruct {
|
||||||
Ok(offset)
|
Ok(offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_type(&self) -> Type {
|
pub fn get_fields(&self) -> &Vec<Type> {
|
||||||
self.libffi_type.clone()
|
&self.fields
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_type(&self) -> &Type {
|
||||||
|
&self.struct_type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#![allow(clippy::cargo_common_metadata)]
|
#![allow(clippy::cargo_common_metadata)]
|
||||||
|
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
use libffi::middle::Type;
|
use libffi::middle::Type;
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
|
|
||||||
|
@ -8,27 +10,20 @@ use super::c_helper::get_ensured_size;
|
||||||
use super::c_ptr::CPtr;
|
use super::c_ptr::CPtr;
|
||||||
use crate::ffi::ffi_helper::get_ptr_from_userdata;
|
use crate::ffi::ffi_helper::get_ptr_from_userdata;
|
||||||
|
|
||||||
pub struct CType {
|
pub struct CType<T: ?Sized> {
|
||||||
// for ffi_ptrarray_to_raw?
|
// for ffi_ptrarray_to_raw?
|
||||||
// libffi_cif: Cif,
|
// libffi_cif: Cif,
|
||||||
libffi_type: Type,
|
libffi_type: Type,
|
||||||
size: usize,
|
size: usize,
|
||||||
name: Option<String>,
|
name: Option<&'static str>,
|
||||||
|
_phantom: PhantomData<T>,
|
||||||
// Write converted data from luavalue into some ptr
|
|
||||||
pub luavalue_into_ptr: fn(value: LuaValue, ptr: *mut ()) -> LuaResult<()>,
|
|
||||||
|
|
||||||
// Read luavalue from some ptr
|
|
||||||
pub ptr_into_luavalue: fn(lua: &Lua, ptr: *mut ()) -> LuaResult<LuaValue>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CType {
|
impl<T> CType<T>
|
||||||
pub fn new(
|
where
|
||||||
libffi_type: Type,
|
T: ?Sized,
|
||||||
name: Option<String>,
|
{
|
||||||
luavalue_into_ptr: fn(value: LuaValue, ptr: *mut ()) -> LuaResult<()>,
|
pub fn new_with_libffi_type(libffi_type: Type, name: Option<&'static str>) -> LuaResult<Self> {
|
||||||
ptr_into_luavalue: fn(lua: &Lua, ptr: *mut ()) -> LuaResult<LuaValue>,
|
|
||||||
) -> LuaResult<Self> {
|
|
||||||
// let libffi_cfi = Cif::new(vec![libffi_type.clone()], Type::void());
|
// let libffi_cfi = Cif::new(vec![libffi_type.clone()], Type::void());
|
||||||
let size = get_ensured_size(libffi_type.as_raw_ptr())?;
|
let size = get_ensured_size(libffi_type.as_raw_ptr())?;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
|
@ -36,78 +31,83 @@ impl CType {
|
||||||
libffi_type,
|
libffi_type,
|
||||||
size,
|
size,
|
||||||
name,
|
name,
|
||||||
luavalue_into_ptr,
|
_phantom: PhantomData {},
|
||||||
ptr_into_luavalue,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_type(&self) -> Type {
|
pub fn get_type(&self) -> &Type {
|
||||||
self.libffi_type.clone()
|
&self.libffi_type
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn stringify(&self) -> String {
|
pub fn stringify(&self) -> &str {
|
||||||
match &self.name {
|
match self.name {
|
||||||
Some(t) => t.to_owned(),
|
Some(t) => t,
|
||||||
None => String::from("unnamed"),
|
None => "unnamed",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Read data from ptr and convert it into luavalue
|
pub trait PtrHandle {
|
||||||
pub unsafe fn read_ptr<'lua>(
|
// Convert luavalue into data, then write into ptr
|
||||||
|
fn luavalue_into_ptr(value: LuaValue, ptr: *mut ()) -> LuaResult<()>;
|
||||||
|
|
||||||
|
// Read data from ptr, then convert into luavalue
|
||||||
|
fn ptr_into_luavalue(lua: &Lua, ptr: *mut ()) -> LuaResult<LuaValue>;
|
||||||
|
|
||||||
|
// Read data from userdata (such as box or ref) and convert it into luavalue
|
||||||
|
unsafe fn read_userdata<'lua>(
|
||||||
&self,
|
&self,
|
||||||
lua: &'lua Lua,
|
lua: &'lua Lua,
|
||||||
userdata: LuaAnyUserData<'lua>,
|
userdata: LuaAnyUserData<'lua>,
|
||||||
offset: Option<isize>,
|
offset: Option<isize>,
|
||||||
) -> LuaResult<LuaValue<'lua>> {
|
) -> LuaResult<LuaValue<'lua>> {
|
||||||
let ptr = unsafe { get_ptr_from_userdata(&userdata, offset)? };
|
let ptr = unsafe { get_ptr_from_userdata(&userdata, offset)? };
|
||||||
let value = (self.ptr_into_luavalue)(lua, ptr)?;
|
let value = Self::ptr_into_luavalue(lua, ptr)?;
|
||||||
Ok(value)
|
Ok(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write converted data from luavalue into ptr
|
// Write data into userdata (such as box or ref) from luavalue
|
||||||
pub unsafe fn write_ptr<'lua>(
|
unsafe fn write_userdata<'lua>(
|
||||||
&self,
|
&self,
|
||||||
luavalue: LuaValue<'lua>,
|
luavalue: LuaValue<'lua>,
|
||||||
userdata: LuaAnyUserData<'lua>,
|
userdata: LuaAnyUserData<'lua>,
|
||||||
offset: Option<isize>,
|
offset: Option<isize>,
|
||||||
) -> LuaResult<()> {
|
) -> LuaResult<()> {
|
||||||
let ptr = unsafe { get_ptr_from_userdata(&userdata, offset)? };
|
let ptr = unsafe { get_ptr_from_userdata(&userdata, offset)? };
|
||||||
(self.luavalue_into_ptr)(luavalue, ptr)?;
|
Self::luavalue_into_ptr(luavalue, ptr)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LuaUserData for CType {
|
impl<T> LuaUserData for CType<T>
|
||||||
|
where
|
||||||
|
Self: Sized + PtrHandle,
|
||||||
|
{
|
||||||
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) {
|
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) {
|
||||||
fields.add_field_method_get("size", |_, this| Ok(this.size));
|
fields.add_field_method_get("size", |_, this| Ok(this.size));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) {
|
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) {
|
||||||
methods.add_function("ptr", |lua, this: LuaAnyUserData| {
|
methods.add_function("ptr", |lua, this: LuaAnyUserData| {
|
||||||
let pointer = CPtr::from_lua_userdata(lua, &this)?;
|
CPtr::from_lua_userdata(lua, &this)
|
||||||
Ok(pointer)
|
|
||||||
});
|
});
|
||||||
methods.add_method(
|
methods.add_method(
|
||||||
"from",
|
"from",
|
||||||
|lua, ctype, (userdata, offset): (LuaAnyUserData, Option<isize>)| {
|
|lua, ctype, (userdata, offset): (LuaAnyUserData, Option<isize>)| unsafe {
|
||||||
let value = unsafe { ctype.read_ptr(lua, userdata, offset)? };
|
ctype.read_userdata(lua, userdata, offset)
|
||||||
Ok(value)
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
methods.add_method(
|
methods.add_method(
|
||||||
"into",
|
"into",
|
||||||
|_, ctype, (value, userdata, offset): (LuaValue, LuaAnyUserData, Option<isize>)| {
|
|_, ctype, (value, userdata, offset): (LuaValue, LuaAnyUserData, Option<isize>)| unsafe {
|
||||||
unsafe { ctype.write_ptr(value, userdata, offset)? };
|
ctype.write_userdata(value, userdata, offset)
|
||||||
Ok(())
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
methods.add_function("arr", |lua, (this, length): (LuaAnyUserData, usize)| {
|
methods.add_function("arr", |lua, (this, length): (LuaAnyUserData, usize)| {
|
||||||
let carr = CArr::from_lua_userdata(lua, &this, length)?;
|
CArr::from_lua_userdata(lua, &this, length)
|
||||||
Ok(carr)
|
|
||||||
});
|
});
|
||||||
methods.add_meta_method(LuaMetaMethod::ToString, |_, this, ()| {
|
methods.add_meta_method(LuaMetaMethod::ToString, |lua, this, ()| {
|
||||||
let name = this.stringify();
|
lua.create_string(this.stringify())
|
||||||
Ok(name)
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,9 @@ pub(super) mod c_ptr;
|
||||||
pub(super) mod c_string;
|
pub(super) mod c_string;
|
||||||
pub(super) mod c_struct;
|
pub(super) mod c_struct;
|
||||||
pub(super) mod c_type;
|
pub(super) mod c_type;
|
||||||
|
pub(super) mod types;
|
||||||
|
|
||||||
|
pub use types::create_all_types;
|
||||||
|
|
||||||
// Named registry table names
|
// Named registry table names
|
||||||
mod association_names {
|
mod association_names {
|
||||||
|
@ -12,133 +15,3 @@ mod association_names {
|
||||||
pub const CARR_INNER: &str = "__carr_inner";
|
pub const CARR_INNER: &str = "__carr_inner";
|
||||||
pub const CSTRUCT_INNER: &str = "__cstruct_inner";
|
pub const CSTRUCT_INNER: &str = "__cstruct_inner";
|
||||||
}
|
}
|
||||||
|
|
||||||
use core::ffi::{
|
|
||||||
c_char, c_double, c_float, c_int, c_long, c_longlong, c_schar, c_short, c_uchar, c_uint,
|
|
||||||
c_ulong, c_ulonglong, c_ushort, c_void,
|
|
||||||
};
|
|
||||||
|
|
||||||
use libffi::middle::Type;
|
|
||||||
use mlua::prelude::*;
|
|
||||||
|
|
||||||
use self::c_type::CType;
|
|
||||||
use crate::ffi::ffi_platform::CHAR_IS_SIGNED;
|
|
||||||
|
|
||||||
// export all default c-types
|
|
||||||
#[allow(clippy::too_many_lines)]
|
|
||||||
pub fn create_all_types(lua: &Lua) -> LuaResult<Vec<(&'static str, LuaValue)>> {
|
|
||||||
Ok(vec![
|
|
||||||
(
|
|
||||||
"int",
|
|
||||||
CType::new(
|
|
||||||
Type::c_int(),
|
|
||||||
Some(String::from("int")),
|
|
||||||
|data, ptr| {
|
|
||||||
let value = match data {
|
|
||||||
LuaValue::Integer(t) => t,
|
|
||||||
_ => {
|
|
||||||
return Err(LuaError::external(format!(
|
|
||||||
"Integer expected, got {}",
|
|
||||||
data.type_name()
|
|
||||||
)))
|
|
||||||
}
|
|
||||||
} as c_int;
|
|
||||||
unsafe {
|
|
||||||
*(ptr.cast::<c_int>()) = value;
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
},
|
|
||||||
|lua: &Lua, ptr: *mut ()| {
|
|
||||||
let value = unsafe { (*ptr.cast::<c_int>()).into_lua(lua)? };
|
|
||||||
Ok(value)
|
|
||||||
},
|
|
||||||
)?
|
|
||||||
.into_lua(lua)?,
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"long",
|
|
||||||
CType::new(
|
|
||||||
Type::c_long(),
|
|
||||||
Some(String::from("long")),
|
|
||||||
|data, ptr| {
|
|
||||||
let value = match data {
|
|
||||||
LuaValue::Integer(t) => t,
|
|
||||||
_ => {
|
|
||||||
return Err(LuaError::external(format!(
|
|
||||||
"Integer expected, got {}",
|
|
||||||
data.type_name()
|
|
||||||
)))
|
|
||||||
}
|
|
||||||
} as c_long;
|
|
||||||
unsafe {
|
|
||||||
*(ptr.cast::<c_long>()) = value;
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
},
|
|
||||||
|lua: &Lua, ptr: *mut ()| {
|
|
||||||
let value = unsafe { (*ptr.cast::<c_long>()).into_lua(lua)? };
|
|
||||||
Ok(value)
|
|
||||||
},
|
|
||||||
)?
|
|
||||||
.into_lua(lua)?,
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"longlong",
|
|
||||||
CType::new(
|
|
||||||
Type::c_longlong(),
|
|
||||||
Some(String::from("longlong")),
|
|
||||||
|data, ptr| {
|
|
||||||
let value = match data {
|
|
||||||
LuaValue::Integer(t) => t,
|
|
||||||
_ => {
|
|
||||||
return Err(LuaError::external(format!(
|
|
||||||
"Integer expected, got {}",
|
|
||||||
data.type_name()
|
|
||||||
)))
|
|
||||||
}
|
|
||||||
} as c_longlong;
|
|
||||||
unsafe {
|
|
||||||
*(ptr.cast::<c_longlong>()) = value;
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
},
|
|
||||||
|lua: &Lua, ptr: *mut ()| {
|
|
||||||
let value = unsafe { (*ptr.cast::<c_longlong>()).into_lua(lua)? };
|
|
||||||
Ok(value)
|
|
||||||
},
|
|
||||||
)?
|
|
||||||
.into_lua(lua)?,
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"char",
|
|
||||||
CType::new(
|
|
||||||
if CHAR_IS_SIGNED {
|
|
||||||
Type::c_schar()
|
|
||||||
} else {
|
|
||||||
Type::c_uchar()
|
|
||||||
},
|
|
||||||
Some(String::from("char")),
|
|
||||||
|data, ptr| {
|
|
||||||
let value = match data {
|
|
||||||
LuaValue::Integer(t) => t,
|
|
||||||
_ => {
|
|
||||||
return Err(LuaError::external(format!(
|
|
||||||
"Integer expected, got {}",
|
|
||||||
data.type_name()
|
|
||||||
)))
|
|
||||||
}
|
|
||||||
} as c_char;
|
|
||||||
unsafe {
|
|
||||||
*(ptr.cast::<c_char>()) = value;
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
},
|
|
||||||
|lua: &Lua, ptr: *mut ()| {
|
|
||||||
let value = unsafe { (*ptr.cast::<c_char>()).into_lua(lua)? };
|
|
||||||
Ok(value)
|
|
||||||
},
|
|
||||||
)?
|
|
||||||
.into_lua(lua)?,
|
|
||||||
),
|
|
||||||
])
|
|
||||||
}
|
|
||||||
|
|
38
crates/lune-std-ffi/src/c/types/c_int.rs
Normal file
38
crates/lune-std-ffi/src/c/types/c_int.rs
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
use core::ffi::c_int;
|
||||||
|
|
||||||
|
use libffi::middle::Type;
|
||||||
|
use mlua::prelude::*;
|
||||||
|
|
||||||
|
use super::super::c_type::{CType, PtrHandle};
|
||||||
|
|
||||||
|
impl PtrHandle for CType<c_int> {
|
||||||
|
fn luavalue_into_ptr(value: LuaValue, ptr: *mut ()) -> LuaResult<()> {
|
||||||
|
let value = match value {
|
||||||
|
LuaValue::Integer(t) => t,
|
||||||
|
_ => {
|
||||||
|
return Err(LuaError::external(format!(
|
||||||
|
"Integer expected, got {}",
|
||||||
|
value.type_name()
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
} as c_int;
|
||||||
|
unsafe {
|
||||||
|
*(ptr.cast::<c_int>()) = value;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
fn ptr_into_luavalue(lua: &Lua, ptr: *mut ()) -> LuaResult<LuaValue> {
|
||||||
|
let value = unsafe { (*ptr.cast::<c_int>()).into_lua(lua)? };
|
||||||
|
Ok(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CType<c_int> {
|
||||||
|
fn new() -> LuaResult<Self> {
|
||||||
|
Self::new_with_libffi_type(Type::c_int(), Some("int"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_export(lua: &Lua) -> LuaResult<(&'static str, LuaAnyUserData)> {
|
||||||
|
Ok(("int", lua.create_userdata(CType::<c_int>::new()?)?))
|
||||||
|
}
|
8
crates/lune-std-ffi/src/c/types/mod.rs
Normal file
8
crates/lune-std-ffi/src/c/types/mod.rs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
mod c_int;
|
||||||
|
|
||||||
|
use mlua::prelude::*;
|
||||||
|
|
||||||
|
// export all default c-types
|
||||||
|
pub fn create_all_types(lua: &Lua) -> LuaResult<Vec<(&'static str, LuaAnyUserData)>> {
|
||||||
|
Ok(vec![c_int::get_export(lua)?])
|
||||||
|
}
|
|
@ -22,7 +22,7 @@ pub unsafe fn get_ptr_from_userdata(
|
||||||
} else if userdata.is::<FfiRef>() {
|
} else if userdata.is::<FfiRef>() {
|
||||||
userdata.borrow::<FfiRef>()?.get_ptr()
|
userdata.borrow::<FfiRef>()?.get_ptr()
|
||||||
} else {
|
} else {
|
||||||
return Err(LuaError::external("asdf"));
|
return Err(LuaError::external("Unexpected userdata"));
|
||||||
};
|
};
|
||||||
|
|
||||||
let ptr = if let Some(t) = offset {
|
let ptr = if let Some(t) = offset {
|
||||||
|
|
|
@ -12,6 +12,8 @@ use super::ffi_bounds::FfiRefBounds;
|
||||||
// If it references an area managed by Lua,
|
// If it references an area managed by Lua,
|
||||||
// the box will remain as long as this reference is alive.
|
// the box will remain as long as this reference is alive.
|
||||||
|
|
||||||
|
// Todo : how to impl ref == nullptr
|
||||||
|
|
||||||
pub struct FfiRef {
|
pub struct FfiRef {
|
||||||
ptr: *mut (),
|
ptr: *mut (),
|
||||||
range: Option<FfiRefBounds>,
|
range: Option<FfiRefBounds>,
|
||||||
|
|
Loading…
Add table
Reference in a new issue