mirror of
https://github.com/lune-org/lune.git
synced 2025-04-04 10:30:54 +01:00
Implement luavalue conversion (#243)
This commit is contained in:
parent
6d0db930f6
commit
48d2db4950
14 changed files with 293 additions and 99 deletions
|
@ -39,7 +39,7 @@ impl CArr {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn from_lua_userdata<'lua>(
|
||||
pub fn new_from_lua_userdata<'lua>(
|
||||
lua: &'lua Lua,
|
||||
luatype: &LuaAnyUserData<'lua>,
|
||||
length: usize,
|
||||
|
|
|
@ -35,7 +35,7 @@ impl CFn {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn from_lua_table(lua: &Lua, args: LuaTable, ret: LuaAnyUserData) -> LuaResult<Self> {
|
||||
pub fn new_from_lua_table(lua: &Lua, args: LuaTable, ret: LuaAnyUserData) -> LuaResult<Self> {
|
||||
let args = type_list_from_table(lua, &args)?;
|
||||
let ret = type_from_userdata(lua, &ret)?;
|
||||
Ok(Self::new(args, ret))
|
||||
|
|
|
@ -60,7 +60,7 @@ impl LuaUserData for CPtr {
|
|||
Ok(pointer)
|
||||
});
|
||||
methods.add_function("arr", |lua, (this, length): (LuaAnyUserData, usize)| {
|
||||
let carr = CArr::from_lua_userdata(lua, &this, length)?;
|
||||
let carr = CArr::new_from_lua_userdata(lua, &this, length)?;
|
||||
Ok(carr)
|
||||
});
|
||||
methods.add_meta_function(LuaMetaMethod::ToString, |lua, this: LuaAnyUserData| {
|
||||
|
|
|
@ -57,7 +57,7 @@ impl CStruct {
|
|||
|
||||
// Create new CStruct UserData with LuaTable.
|
||||
// Lock and hold table for .inner ref
|
||||
pub fn from_lua_table<'lua>(
|
||||
pub fn new_from_lua_table<'lua>(
|
||||
lua: &'lua Lua,
|
||||
table: LuaTable<'lua>,
|
||||
) -> LuaResult<LuaAnyUserData<'lua>> {
|
||||
|
@ -135,7 +135,7 @@ impl LuaUserData for CStruct {
|
|||
Ok(pointer)
|
||||
});
|
||||
methods.add_function("arr", |lua, (this, length): (LuaAnyUserData, usize)| {
|
||||
let carr = CArr::from_lua_userdata(lua, &this, length)?;
|
||||
let carr = CArr::new_from_lua_userdata(lua, &this, length)?;
|
||||
Ok(carr)
|
||||
});
|
||||
methods.add_meta_function(LuaMetaMethod::ToString, |lua, this: LuaAnyUserData| {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#![allow(clippy::cargo_common_metadata)]
|
||||
|
||||
use lune_utils::fmt::{pretty_format_value, ValueFormatConfig};
|
||||
use num::cast::{AsPrimitive, NumCast};
|
||||
use num::cast::AsPrimitive;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use libffi::middle::Type;
|
||||
|
@ -24,13 +24,18 @@ pub struct CType<T: ?Sized> {
|
|||
_phantom: PhantomData<T>,
|
||||
}
|
||||
|
||||
// Static CType, for borrow, is operation
|
||||
// We can't get a CType<T> through mlua, something like
|
||||
// .is::<CType<dyn Any>> will fail.
|
||||
// So we need data that has a static type.
|
||||
// each CType<T> 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<T>(ctype: &CType<T>) -> Self {
|
||||
Self {
|
||||
|
@ -45,8 +50,8 @@ impl LuaUserData for CTypeStatic {}
|
|||
|
||||
impl<T> CType<T>
|
||||
where
|
||||
Self: CTypeConvert,
|
||||
T: 'static,
|
||||
Self: CTypeConvert + CTypeCast,
|
||||
{
|
||||
pub fn new_with_libffi_type<'lua>(
|
||||
lua: &'lua Lua,
|
||||
|
@ -73,25 +78,12 @@ where
|
|||
Ok(userdata)
|
||||
}
|
||||
|
||||
pub fn get_type(&self) -> &Type {
|
||||
&self.libffi_type
|
||||
}
|
||||
|
||||
pub fn stringify(&self) -> &str {
|
||||
match self.name {
|
||||
Some(t) => t,
|
||||
None => "unnamed",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cast_failed_with(&self, into_ctype: &LuaAnyUserData) -> LuaError {
|
||||
let config = ValueFormatConfig::new();
|
||||
LuaError::external(format!(
|
||||
"Cannot cast <CType({})> to {}",
|
||||
self.stringify(),
|
||||
pretty_format_value(&LuaValue::UserData(into_ctype.to_owned()), &config)
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
// Handle C data, provide type conversion between luavalue and c-type
|
||||
|
@ -127,12 +119,9 @@ pub trait CTypeConvert {
|
|||
}
|
||||
}
|
||||
|
||||
pub trait CTypeNumCast<T>
|
||||
where
|
||||
T: NumCast,
|
||||
{
|
||||
pub trait CTypeCast {
|
||||
// Cast T as U
|
||||
fn cast_userdata<U>(from: &LuaAnyUserData, into: &LuaAnyUserData) -> LuaResult<()>
|
||||
fn cast_num<T, U>(&self, from: &LuaAnyUserData, into: &LuaAnyUserData) -> LuaResult<()>
|
||||
where
|
||||
T: AsPrimitive<U>,
|
||||
U: 'static + Copy,
|
||||
|
@ -147,7 +136,8 @@ where
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn cast_userdata_if_type_match<U>(
|
||||
fn try_cast_num<T, U>(
|
||||
&self,
|
||||
ctype: &LuaAnyUserData,
|
||||
from: &LuaAnyUserData,
|
||||
into: &LuaAnyUserData,
|
||||
|
@ -157,18 +147,42 @@ where
|
|||
U: 'static + Copy,
|
||||
{
|
||||
if ctype.is::<CType<U>>() {
|
||||
Self::cast_userdata(from, into)?;
|
||||
Self::cast_num::<T, U>(self, from, into)?;
|
||||
Ok(Some(()))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
fn cast(
|
||||
&self,
|
||||
from_ctype: &LuaAnyUserData,
|
||||
into_ctype: &LuaAnyUserData,
|
||||
from: &LuaAnyUserData,
|
||||
into: &LuaAnyUserData,
|
||||
) -> LuaResult<()> {
|
||||
Err(Self::cast_failed_with(self, from_ctype, into_ctype))
|
||||
}
|
||||
|
||||
fn cast_failed_with(
|
||||
&self,
|
||||
from_ctype: &LuaAnyUserData,
|
||||
into_ctype: &LuaAnyUserData,
|
||||
) -> LuaError {
|
||||
let config = ValueFormatConfig::new();
|
||||
LuaError::external(format!(
|
||||
"Cannot cast {} to {}",
|
||||
pretty_format_value(&LuaValue::UserData(from_ctype.to_owned()), &config),
|
||||
pretty_format_value(&LuaValue::UserData(into_ctype.to_owned()), &config),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> LuaUserData for CType<T>
|
||||
where
|
||||
Self: CTypeConvert,
|
||||
T: 'static,
|
||||
Self: CTypeConvert + CTypeCast,
|
||||
{
|
||||
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) {
|
||||
fields.add_field_method_get("size", |_, this| Ok(this.size));
|
||||
|
@ -193,8 +207,22 @@ where
|
|||
},
|
||||
);
|
||||
methods.add_function("arr", |lua, (this, length): (LuaAnyUserData, usize)| {
|
||||
CArr::from_lua_userdata(lua, &this, length)
|
||||
CArr::new_from_lua_userdata(lua, &this, length)
|
||||
});
|
||||
methods.add_function(
|
||||
"cast",
|
||||
|_,
|
||||
(from_type, into_type, from, into): (
|
||||
LuaAnyUserData,
|
||||
LuaAnyUserData,
|
||||
LuaAnyUserData,
|
||||
LuaAnyUserData,
|
||||
)| {
|
||||
from_type
|
||||
.borrow::<Self>()?
|
||||
.cast(&from_type, &into_type, &from, &into)
|
||||
},
|
||||
);
|
||||
methods.add_meta_method(LuaMetaMethod::ToString, |lua, this, ()| {
|
||||
lua.create_string(this.stringify())
|
||||
});
|
||||
|
|
|
@ -2,21 +2,23 @@ use core::ffi::*;
|
|||
|
||||
use libffi::middle::Type;
|
||||
use mlua::prelude::*;
|
||||
use num::cast::AsPrimitive;
|
||||
|
||||
use super::super::c_type::{CType, CTypeConvert, CTypeNumCast};
|
||||
use super::super::c_type::{CType, CTypeCast, CTypeConvert};
|
||||
use crate::ffi::ffi_platform::CHAR_IS_SIGNED;
|
||||
|
||||
impl CTypeConvert for CType<c_char> {
|
||||
fn luavalue_into_ptr(value: LuaValue, ptr: *mut ()) -> LuaResult<()> {
|
||||
let value = match value {
|
||||
LuaValue::Integer(t) => t,
|
||||
let value: c_char = match value {
|
||||
LuaValue::Integer(t) => t.as_(),
|
||||
LuaValue::String(t) => t.as_bytes().first().map_or(0, u8::to_owned).as_(),
|
||||
_ => {
|
||||
return Err(LuaError::external(format!(
|
||||
"Integer expected, got {}",
|
||||
"Argument LuaValue expected a Integer or String, got {}",
|
||||
value.type_name()
|
||||
)))
|
||||
}
|
||||
} as c_char;
|
||||
};
|
||||
unsafe {
|
||||
*(ptr.cast::<c_char>()) = value;
|
||||
}
|
||||
|
@ -28,29 +30,24 @@ impl CTypeConvert for CType<c_char> {
|
|||
}
|
||||
}
|
||||
|
||||
impl CType<c_char> {
|
||||
impl CTypeCast for CType<c_char> {
|
||||
fn cast(
|
||||
&self,
|
||||
from_ctype: &LuaAnyUserData,
|
||||
into_ctype: &LuaAnyUserData,
|
||||
from: &LuaAnyUserData,
|
||||
into: &LuaAnyUserData,
|
||||
) -> LuaResult<()> {
|
||||
Self::cast_userdata_if_type_match::<c_float>(into_ctype, from, into)?
|
||||
.or(Self::cast_userdata_if_type_match::<c_double>(
|
||||
into_ctype, from, into,
|
||||
)?)
|
||||
.or(Self::cast_userdata_if_type_match::<c_char>(
|
||||
into_ctype, from, into,
|
||||
)?)
|
||||
.or(Self::cast_userdata_if_type_match::<c_long>(
|
||||
into_ctype, from, into,
|
||||
)?)
|
||||
.ok_or_else(|| self.cast_failed_with(into_ctype))
|
||||
self.try_cast_num::<c_char, c_float>(into_ctype, from, into)?
|
||||
.or(self.try_cast_num::<c_char, c_double>(into_ctype, from, into)?)
|
||||
.or(self.try_cast_num::<c_char, c_char>(into_ctype, from, into)?)
|
||||
.or(self.try_cast_num::<c_char, c_long>(into_ctype, from, into)?)
|
||||
.or(self.try_cast_num::<c_char, c_int>(into_ctype, from, into)?)
|
||||
.or(self.try_cast_num::<c_char, c_longlong>(into_ctype, from, into)?)
|
||||
.ok_or_else(|| self.cast_failed_with(from_ctype, into_ctype))
|
||||
}
|
||||
}
|
||||
|
||||
impl CTypeNumCast<c_char> for CType<c_char> {}
|
||||
|
||||
pub fn get_export(lua: &Lua) -> LuaResult<(&'static str, LuaAnyUserData)> {
|
||||
Ok((
|
||||
"char",
|
||||
|
|
59
crates/lune-std-ffi/src/c/types/c_double.rs
Normal file
59
crates/lune-std-ffi/src/c/types/c_double.rs
Normal file
|
@ -0,0 +1,59 @@
|
|||
use core::ffi::*;
|
||||
|
||||
use libffi::middle::Type;
|
||||
use mlua::prelude::*;
|
||||
|
||||
use super::super::c_type::{CType, CTypeCast, CTypeConvert};
|
||||
use num::cast::AsPrimitive;
|
||||
|
||||
impl CTypeConvert for CType<c_double> {
|
||||
fn luavalue_into_ptr(value: LuaValue, ptr: *mut ()) -> LuaResult<()> {
|
||||
let value: c_double = match value {
|
||||
LuaValue::Integer(t) => t.as_(),
|
||||
LuaValue::Number(t) => t.as_(),
|
||||
LuaValue::String(t) => t
|
||||
.to_string_lossy()
|
||||
.parse::<c_double>()
|
||||
.map_err(LuaError::external)?,
|
||||
_ => {
|
||||
return Err(LuaError::external(format!(
|
||||
"Argument LuaValue expected a Integer, Number or String, got {}",
|
||||
value.type_name()
|
||||
)))
|
||||
}
|
||||
};
|
||||
unsafe {
|
||||
*(ptr.cast::<c_double>()) = value;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
fn ptr_into_luavalue(lua: &Lua, ptr: *mut ()) -> LuaResult<LuaValue> {
|
||||
let value = unsafe { (*ptr.cast::<c_double>()).into_lua(lua)? };
|
||||
Ok(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl CTypeCast for CType<c_double> {
|
||||
fn cast(
|
||||
&self,
|
||||
from_ctype: &LuaAnyUserData,
|
||||
into_ctype: &LuaAnyUserData,
|
||||
from: &LuaAnyUserData,
|
||||
into: &LuaAnyUserData,
|
||||
) -> LuaResult<()> {
|
||||
self.try_cast_num::<c_double, c_float>(into_ctype, from, into)?
|
||||
.or(self.try_cast_num::<c_double, c_double>(into_ctype, from, into)?)
|
||||
.or(self.try_cast_num::<c_double, c_char>(into_ctype, from, into)?)
|
||||
.or(self.try_cast_num::<c_double, c_long>(into_ctype, from, into)?)
|
||||
.or(self.try_cast_num::<c_double, c_int>(into_ctype, from, into)?)
|
||||
.or(self.try_cast_num::<c_double, c_longlong>(into_ctype, from, into)?)
|
||||
.ok_or_else(|| self.cast_failed_with(from_ctype, into_ctype))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_export(lua: &Lua) -> LuaResult<(&'static str, LuaAnyUserData)> {
|
||||
Ok((
|
||||
"double",
|
||||
CType::<c_double>::new_with_libffi_type(lua, Type::f64(), true, Some("double"))?,
|
||||
))
|
||||
}
|
59
crates/lune-std-ffi/src/c/types/c_float.rs
Normal file
59
crates/lune-std-ffi/src/c/types/c_float.rs
Normal file
|
@ -0,0 +1,59 @@
|
|||
use core::ffi::*;
|
||||
|
||||
use libffi::middle::Type;
|
||||
use mlua::prelude::*;
|
||||
|
||||
use super::super::c_type::{CType, CTypeCast, CTypeConvert};
|
||||
use num::cast::AsPrimitive;
|
||||
|
||||
impl CTypeConvert for CType<c_float> {
|
||||
fn luavalue_into_ptr(value: LuaValue, ptr: *mut ()) -> LuaResult<()> {
|
||||
let value: c_float = match value {
|
||||
LuaValue::Integer(t) => t.as_(),
|
||||
LuaValue::Number(t) => t.as_(),
|
||||
LuaValue::String(t) => t
|
||||
.to_string_lossy()
|
||||
.parse::<c_float>()
|
||||
.map_err(LuaError::external)?,
|
||||
_ => {
|
||||
return Err(LuaError::external(format!(
|
||||
"Argument LuaValue expected a Integer, Number or String, got {}",
|
||||
value.type_name()
|
||||
)))
|
||||
}
|
||||
};
|
||||
unsafe {
|
||||
*(ptr.cast::<c_float>()) = value;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
fn ptr_into_luavalue(lua: &Lua, ptr: *mut ()) -> LuaResult<LuaValue> {
|
||||
let value = unsafe { (*ptr.cast::<c_float>()).into_lua(lua)? };
|
||||
Ok(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl CTypeCast for CType<c_float> {
|
||||
fn cast(
|
||||
&self,
|
||||
from_ctype: &LuaAnyUserData,
|
||||
into_ctype: &LuaAnyUserData,
|
||||
from: &LuaAnyUserData,
|
||||
into: &LuaAnyUserData,
|
||||
) -> LuaResult<()> {
|
||||
self.try_cast_num::<c_float, c_float>(into_ctype, from, into)?
|
||||
.or(self.try_cast_num::<c_float, c_double>(into_ctype, from, into)?)
|
||||
.or(self.try_cast_num::<c_float, c_char>(into_ctype, from, into)?)
|
||||
.or(self.try_cast_num::<c_float, c_long>(into_ctype, from, into)?)
|
||||
.or(self.try_cast_num::<c_float, c_int>(into_ctype, from, into)?)
|
||||
.or(self.try_cast_num::<c_float, c_longlong>(into_ctype, from, into)?)
|
||||
.ok_or_else(|| self.cast_failed_with(from_ctype, into_ctype))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_export(lua: &Lua) -> LuaResult<(&'static str, LuaAnyUserData)> {
|
||||
Ok((
|
||||
"float",
|
||||
CType::<c_float>::new_with_libffi_type(lua, Type::f32(), true, Some("float"))?,
|
||||
))
|
||||
}
|
|
@ -2,20 +2,26 @@ use core::ffi::*;
|
|||
|
||||
use libffi::middle::Type;
|
||||
use mlua::prelude::*;
|
||||
use num::cast::AsPrimitive;
|
||||
|
||||
use super::super::c_type::{CType, CTypeConvert, CTypeNumCast};
|
||||
use super::super::c_type::{CType, CTypeCast, CTypeConvert};
|
||||
|
||||
impl CTypeConvert for CType<c_int> {
|
||||
fn luavalue_into_ptr(value: LuaValue, ptr: *mut ()) -> LuaResult<()> {
|
||||
let value = match value {
|
||||
LuaValue::Integer(t) => t,
|
||||
let value: c_int = match value {
|
||||
LuaValue::Integer(t) => t.as_(),
|
||||
LuaValue::Number(t) => t.as_(),
|
||||
LuaValue::String(t) => t
|
||||
.to_string_lossy()
|
||||
.parse::<i32>()
|
||||
.map_err(LuaError::external)?,
|
||||
_ => {
|
||||
return Err(LuaError::external(format!(
|
||||
"Integer expected, got {}",
|
||||
"Argument LuaValue expected a Integer, Number or String, got {}",
|
||||
value.type_name()
|
||||
)))
|
||||
}
|
||||
} as c_int;
|
||||
};
|
||||
unsafe {
|
||||
*(ptr.cast::<c_int>()) = value;
|
||||
}
|
||||
|
@ -27,29 +33,26 @@ impl CTypeConvert for CType<c_int> {
|
|||
}
|
||||
}
|
||||
|
||||
impl CType<c_int> {
|
||||
impl CType<c_int> {}
|
||||
|
||||
impl CTypeCast for CType<c_int> {
|
||||
fn cast(
|
||||
&self,
|
||||
from_ctype: &LuaAnyUserData,
|
||||
into_ctype: &LuaAnyUserData,
|
||||
from: &LuaAnyUserData,
|
||||
into: &LuaAnyUserData,
|
||||
) -> LuaResult<()> {
|
||||
Self::cast_userdata_if_type_match::<c_float>(into_ctype, from, into)?
|
||||
.or(Self::cast_userdata_if_type_match::<c_double>(
|
||||
into_ctype, from, into,
|
||||
)?)
|
||||
.or(Self::cast_userdata_if_type_match::<c_char>(
|
||||
into_ctype, from, into,
|
||||
)?)
|
||||
.or(Self::cast_userdata_if_type_match::<c_long>(
|
||||
into_ctype, from, into,
|
||||
)?)
|
||||
.ok_or_else(|| self.cast_failed_with(into_ctype))
|
||||
self.try_cast_num::<c_int, c_float>(into_ctype, from, into)?
|
||||
.or(self.try_cast_num::<c_int, c_double>(into_ctype, from, into)?)
|
||||
.or(self.try_cast_num::<c_int, c_char>(into_ctype, from, into)?)
|
||||
.or(self.try_cast_num::<c_int, c_long>(into_ctype, from, into)?)
|
||||
.or(self.try_cast_num::<c_int, c_int>(into_ctype, from, into)?)
|
||||
.or(self.try_cast_num::<c_int, c_longlong>(into_ctype, from, into)?)
|
||||
.ok_or_else(|| self.cast_failed_with(from_ctype, into_ctype))
|
||||
}
|
||||
}
|
||||
|
||||
impl CTypeNumCast<c_int> for CType<c_int> {}
|
||||
|
||||
pub fn get_export(lua: &Lua) -> LuaResult<(&'static str, LuaAnyUserData)> {
|
||||
Ok((
|
||||
"int",
|
||||
|
|
59
crates/lune-std-ffi/src/c/types/c_long.rs
Normal file
59
crates/lune-std-ffi/src/c/types/c_long.rs
Normal file
|
@ -0,0 +1,59 @@
|
|||
use core::ffi::*;
|
||||
|
||||
use libffi::middle::Type;
|
||||
use mlua::prelude::*;
|
||||
|
||||
use super::super::c_type::{CType, CTypeCast, CTypeConvert};
|
||||
use num::cast::AsPrimitive;
|
||||
|
||||
impl CTypeConvert for CType<c_long> {
|
||||
fn luavalue_into_ptr(value: LuaValue, ptr: *mut ()) -> LuaResult<()> {
|
||||
let value: c_long = match value {
|
||||
LuaValue::Integer(t) => t.as_(),
|
||||
LuaValue::Number(t) => t.as_(),
|
||||
LuaValue::String(t) => t
|
||||
.to_string_lossy()
|
||||
.parse::<c_long>()
|
||||
.map_err(LuaError::external)?,
|
||||
_ => {
|
||||
return Err(LuaError::external(format!(
|
||||
"Argument LuaValue expected a Integer, Number or String, got {}",
|
||||
value.type_name()
|
||||
)))
|
||||
}
|
||||
};
|
||||
unsafe {
|
||||
*(ptr.cast::<c_long>()) = value;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
fn ptr_into_luavalue(lua: &Lua, ptr: *mut ()) -> LuaResult<LuaValue> {
|
||||
let value = unsafe { (*ptr.cast::<c_long>()).into_lua(lua)? };
|
||||
Ok(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl CTypeCast for CType<c_long> {
|
||||
fn cast(
|
||||
&self,
|
||||
from_ctype: &LuaAnyUserData,
|
||||
into_ctype: &LuaAnyUserData,
|
||||
from: &LuaAnyUserData,
|
||||
into: &LuaAnyUserData,
|
||||
) -> LuaResult<()> {
|
||||
self.try_cast_num::<c_long, c_float>(into_ctype, from, into)?
|
||||
.or(self.try_cast_num::<c_long, c_double>(into_ctype, from, into)?)
|
||||
.or(self.try_cast_num::<c_long, c_char>(into_ctype, from, into)?)
|
||||
.or(self.try_cast_num::<c_long, c_long>(into_ctype, from, into)?)
|
||||
.or(self.try_cast_num::<c_long, c_int>(into_ctype, from, into)?)
|
||||
.or(self.try_cast_num::<c_long, c_longlong>(into_ctype, from, into)?)
|
||||
.ok_or_else(|| self.cast_failed_with(from_ctype, into_ctype))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_export(lua: &Lua) -> LuaResult<(&'static str, LuaAnyUserData)> {
|
||||
Ok((
|
||||
"long",
|
||||
CType::<c_long>::new_with_libffi_type(lua, Type::c_long(), true, Some("long"))?,
|
||||
))
|
||||
}
|
|
@ -1,9 +1,18 @@
|
|||
mod c_char;
|
||||
mod c_double;
|
||||
mod c_float;
|
||||
mod c_int;
|
||||
mod c_long;
|
||||
|
||||
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)?, c_char::get_export(lua)?])
|
||||
Ok(vec![
|
||||
c_char::get_export(lua)?,
|
||||
c_double::get_export(lua)?,
|
||||
c_float::get_export(lua)?,
|
||||
c_int::get_export(lua)?,
|
||||
c_long::get_export(lua)?,
|
||||
])
|
||||
}
|
||||
|
|
|
@ -39,18 +39,9 @@ impl FfiBox {
|
|||
|
||||
// Todo: if too big, print as another format
|
||||
pub fn stringify(&self) -> String {
|
||||
let mut buff: String = String::with_capacity(self.size() * 10 - 2);
|
||||
for (pos, value) in self.0.iter().enumerate() {
|
||||
for i in 0..8 {
|
||||
if (value & (1 << i)) == 0 {
|
||||
buff.push('0');
|
||||
} else {
|
||||
buff.push('1');
|
||||
}
|
||||
}
|
||||
if pos < self.size() - 1 {
|
||||
buff.push_str(", ");
|
||||
}
|
||||
let mut buff: String = String::with_capacity(self.size() * 2);
|
||||
for value in &self.0 {
|
||||
buff.push_str(format!("{:x}", value.to_be()).as_str());
|
||||
}
|
||||
buff
|
||||
}
|
||||
|
@ -78,7 +69,7 @@ impl FfiBox {
|
|||
bounds = bounds.offset(t);
|
||||
}
|
||||
|
||||
// Lua should not be able to deref a box that refers to a box managed by Lua.
|
||||
// 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.
|
||||
|
|
|
@ -1,22 +1,11 @@
|
|||
use core::ffi::c_char;
|
||||
use std::env::consts;
|
||||
use std::vec::Vec;
|
||||
|
||||
pub const CHAR_IS_SIGNED: bool = c_char::MIN as u8 != u8::MIN;
|
||||
pub const IS_LITTLE_ENDIAN: bool = cfg!(target_endian = "little");
|
||||
|
||||
pub fn get_platform_value() -> Vec<(&'static str, &'static str)> {
|
||||
vec![
|
||||
// https://doc.rust-lang.org/std/env/consts/constant.ARCH.html
|
||||
("arch", consts::ARCH),
|
||||
// https://doc.rust-lang.org/std/env/consts/constant.OS.html
|
||||
("os", consts::OS),
|
||||
// https://doc.rust-lang.org/std/env/consts/constant.FAMILY.html
|
||||
("family", consts::FAMILY),
|
||||
("endian", if IS_LITTLE_ENDIAN { "little" } else { "big" }),
|
||||
(
|
||||
"char_variant",
|
||||
if CHAR_IS_SIGNED { "schar" } else { "uchar" },
|
||||
),
|
||||
]
|
||||
vec![(
|
||||
"char_variant",
|
||||
if CHAR_IS_SIGNED { "schar" } else { "uchar" },
|
||||
)]
|
||||
}
|
||||
|
|
|
@ -30,11 +30,11 @@ pub fn module(lua: &Lua) -> LuaResult<LuaTable> {
|
|||
Ok(lib)
|
||||
})?
|
||||
.with_function("struct", |lua, types: LuaTable| {
|
||||
let cstruct = CStruct::from_lua_table(lua, types)?;
|
||||
let cstruct = CStruct::new_from_lua_table(lua, types)?;
|
||||
Ok(cstruct)
|
||||
})?
|
||||
.with_function("fn", |lua, (args, ret): (LuaTable, LuaAnyUserData)| {
|
||||
let cfn = CFn::from_lua_table(lua, args, ret)?;
|
||||
let cfn = CFn::new_from_lua_table(lua, args, ret)?;
|
||||
Ok(cfn)
|
||||
})?;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue