Implement luavalue conversion (#243)

This commit is contained in:
qwreey 2024-08-27 10:44:51 +00:00
parent 6d0db930f6
commit 48d2db4950
No known key found for this signature in database
GPG key ID: D28DB79297A214BD
14 changed files with 293 additions and 99 deletions

View file

@ -39,7 +39,7 @@ impl CArr {
}) })
} }
pub fn from_lua_userdata<'lua>( pub fn new_from_lua_userdata<'lua>(
lua: &'lua Lua, lua: &'lua Lua,
luatype: &LuaAnyUserData<'lua>, luatype: &LuaAnyUserData<'lua>,
length: usize, length: usize,

View file

@ -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 args = type_list_from_table(lua, &args)?;
let ret = type_from_userdata(lua, &ret)?; let ret = type_from_userdata(lua, &ret)?;
Ok(Self::new(args, ret)) Ok(Self::new(args, ret))

View file

@ -60,7 +60,7 @@ impl LuaUserData for CPtr {
Ok(pointer) Ok(pointer)
}); });
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)?; let carr = CArr::new_from_lua_userdata(lua, &this, length)?;
Ok(carr) Ok(carr)
}); });
methods.add_meta_function(LuaMetaMethod::ToString, |lua, this: LuaAnyUserData| { methods.add_meta_function(LuaMetaMethod::ToString, |lua, this: LuaAnyUserData| {

View file

@ -57,7 +57,7 @@ impl CStruct {
// Create new CStruct UserData with LuaTable. // Create new CStruct UserData with LuaTable.
// Lock and hold table for .inner ref // Lock and hold table for .inner ref
pub fn from_lua_table<'lua>( pub fn new_from_lua_table<'lua>(
lua: &'lua Lua, lua: &'lua Lua,
table: LuaTable<'lua>, table: LuaTable<'lua>,
) -> LuaResult<LuaAnyUserData<'lua>> { ) -> LuaResult<LuaAnyUserData<'lua>> {
@ -135,7 +135,7 @@ impl LuaUserData for CStruct {
Ok(pointer) Ok(pointer)
}); });
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)?; let carr = CArr::new_from_lua_userdata(lua, &this, length)?;
Ok(carr) Ok(carr)
}); });
methods.add_meta_function(LuaMetaMethod::ToString, |lua, this: LuaAnyUserData| { methods.add_meta_function(LuaMetaMethod::ToString, |lua, this: LuaAnyUserData| {

View file

@ -1,7 +1,7 @@
#![allow(clippy::cargo_common_metadata)] #![allow(clippy::cargo_common_metadata)]
use lune_utils::fmt::{pretty_format_value, ValueFormatConfig}; use lune_utils::fmt::{pretty_format_value, ValueFormatConfig};
use num::cast::{AsPrimitive, NumCast}; use num::cast::AsPrimitive;
use std::marker::PhantomData; use std::marker::PhantomData;
use libffi::middle::Type; use libffi::middle::Type;
@ -24,13 +24,18 @@ pub struct CType<T: ?Sized> {
_phantom: PhantomData<T>, _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 struct CTypeStatic {
pub libffi_type: Type, pub libffi_type: Type,
pub size: usize, pub size: usize,
pub name: Option<&'static str>, pub name: Option<&'static str>,
pub signedness: bool, pub signedness: bool,
} }
impl CTypeStatic { impl CTypeStatic {
fn new<T>(ctype: &CType<T>) -> Self { fn new<T>(ctype: &CType<T>) -> Self {
Self { Self {
@ -45,8 +50,8 @@ impl LuaUserData for CTypeStatic {}
impl<T> CType<T> impl<T> CType<T>
where where
Self: CTypeConvert,
T: 'static, T: 'static,
Self: CTypeConvert + CTypeCast,
{ {
pub fn new_with_libffi_type<'lua>( pub fn new_with_libffi_type<'lua>(
lua: &'lua Lua, lua: &'lua Lua,
@ -73,25 +78,12 @@ where
Ok(userdata) Ok(userdata)
} }
pub fn get_type(&self) -> &Type {
&self.libffi_type
}
pub fn stringify(&self) -> &str { pub fn stringify(&self) -> &str {
match self.name { match self.name {
Some(t) => t, Some(t) => t,
None => "unnamed", 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 // Handle C data, provide type conversion between luavalue and c-type
@ -127,12 +119,9 @@ pub trait CTypeConvert {
} }
} }
pub trait CTypeNumCast<T> pub trait CTypeCast {
where
T: NumCast,
{
// Cast T as U // 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 where
T: AsPrimitive<U>, T: AsPrimitive<U>,
U: 'static + Copy, U: 'static + Copy,
@ -147,7 +136,8 @@ where
Ok(()) Ok(())
} }
fn cast_userdata_if_type_match<U>( fn try_cast_num<T, U>(
&self,
ctype: &LuaAnyUserData, ctype: &LuaAnyUserData,
from: &LuaAnyUserData, from: &LuaAnyUserData,
into: &LuaAnyUserData, into: &LuaAnyUserData,
@ -157,18 +147,42 @@ where
U: 'static + Copy, U: 'static + Copy,
{ {
if ctype.is::<CType<U>>() { if ctype.is::<CType<U>>() {
Self::cast_userdata(from, into)?; Self::cast_num::<T, U>(self, from, into)?;
Ok(Some(())) Ok(Some(()))
} else { } else {
Ok(None) 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> impl<T> LuaUserData for CType<T>
where where
Self: CTypeConvert,
T: 'static, T: 'static,
Self: CTypeConvert + CTypeCast,
{ {
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));
@ -193,8 +207,22 @@ where
}, },
); );
methods.add_function("arr", |lua, (this, length): (LuaAnyUserData, usize)| { 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, ()| { methods.add_meta_method(LuaMetaMethod::ToString, |lua, this, ()| {
lua.create_string(this.stringify()) lua.create_string(this.stringify())
}); });

View file

@ -2,21 +2,23 @@ use core::ffi::*;
use libffi::middle::Type; use libffi::middle::Type;
use mlua::prelude::*; 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; use crate::ffi::ffi_platform::CHAR_IS_SIGNED;
impl CTypeConvert for CType<c_char> { impl CTypeConvert for CType<c_char> {
fn luavalue_into_ptr(value: LuaValue, ptr: *mut ()) -> LuaResult<()> { fn luavalue_into_ptr(value: LuaValue, ptr: *mut ()) -> LuaResult<()> {
let value = match value { let value: c_char = match value {
LuaValue::Integer(t) => t, LuaValue::Integer(t) => t.as_(),
LuaValue::String(t) => t.as_bytes().first().map_or(0, u8::to_owned).as_(),
_ => { _ => {
return Err(LuaError::external(format!( return Err(LuaError::external(format!(
"Integer expected, got {}", "Argument LuaValue expected a Integer or String, got {}",
value.type_name() value.type_name()
))) )))
} }
} as c_char; };
unsafe { unsafe {
*(ptr.cast::<c_char>()) = value; *(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( fn cast(
&self, &self,
from_ctype: &LuaAnyUserData,
into_ctype: &LuaAnyUserData, into_ctype: &LuaAnyUserData,
from: &LuaAnyUserData, from: &LuaAnyUserData,
into: &LuaAnyUserData, into: &LuaAnyUserData,
) -> LuaResult<()> { ) -> LuaResult<()> {
Self::cast_userdata_if_type_match::<c_float>(into_ctype, from, into)? self.try_cast_num::<c_char, c_float>(into_ctype, from, into)?
.or(Self::cast_userdata_if_type_match::<c_double>( .or(self.try_cast_num::<c_char, c_double>(into_ctype, from, into)?)
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::cast_userdata_if_type_match::<c_char>( .or(self.try_cast_num::<c_char, c_int>(into_ctype, from, into)?)
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))
.or(Self::cast_userdata_if_type_match::<c_long>(
into_ctype, from, into,
)?)
.ok_or_else(|| self.cast_failed_with(into_ctype))
} }
} }
impl CTypeNumCast<c_char> for CType<c_char> {}
pub fn get_export(lua: &Lua) -> LuaResult<(&'static str, LuaAnyUserData)> { pub fn get_export(lua: &Lua) -> LuaResult<(&'static str, LuaAnyUserData)> {
Ok(( Ok((
"char", "char",

View 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"))?,
))
}

View 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"))?,
))
}

View file

@ -2,20 +2,26 @@ use core::ffi::*;
use libffi::middle::Type; use libffi::middle::Type;
use mlua::prelude::*; 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> { impl CTypeConvert for CType<c_int> {
fn luavalue_into_ptr(value: LuaValue, ptr: *mut ()) -> LuaResult<()> { fn luavalue_into_ptr(value: LuaValue, ptr: *mut ()) -> LuaResult<()> {
let value = match value { let value: c_int = match value {
LuaValue::Integer(t) => t, 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!( return Err(LuaError::external(format!(
"Integer expected, got {}", "Argument LuaValue expected a Integer, Number or String, got {}",
value.type_name() value.type_name()
))) )))
} }
} as c_int; };
unsafe { unsafe {
*(ptr.cast::<c_int>()) = value; *(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( fn cast(
&self, &self,
from_ctype: &LuaAnyUserData,
into_ctype: &LuaAnyUserData, into_ctype: &LuaAnyUserData,
from: &LuaAnyUserData, from: &LuaAnyUserData,
into: &LuaAnyUserData, into: &LuaAnyUserData,
) -> LuaResult<()> { ) -> LuaResult<()> {
Self::cast_userdata_if_type_match::<c_float>(into_ctype, from, into)? self.try_cast_num::<c_int, c_float>(into_ctype, from, into)?
.or(Self::cast_userdata_if_type_match::<c_double>( .or(self.try_cast_num::<c_int, c_double>(into_ctype, from, into)?)
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::cast_userdata_if_type_match::<c_char>( .or(self.try_cast_num::<c_int, c_int>(into_ctype, from, into)?)
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))
.or(Self::cast_userdata_if_type_match::<c_long>(
into_ctype, from, into,
)?)
.ok_or_else(|| self.cast_failed_with(into_ctype))
} }
} }
impl CTypeNumCast<c_int> for CType<c_int> {}
pub fn get_export(lua: &Lua) -> LuaResult<(&'static str, LuaAnyUserData)> { pub fn get_export(lua: &Lua) -> LuaResult<(&'static str, LuaAnyUserData)> {
Ok(( Ok((
"int", "int",

View 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"))?,
))
}

View file

@ -1,9 +1,18 @@
mod c_char; mod c_char;
mod c_double;
mod c_float;
mod c_int; mod c_int;
mod c_long;
use mlua::prelude::*; use mlua::prelude::*;
// export all default c-types // export all default c-types
pub fn create_all_types(lua: &Lua) -> LuaResult<Vec<(&'static str, LuaAnyUserData)>> { 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)?,
])
} }

View file

@ -39,18 +39,9 @@ impl FfiBox {
// Todo: if too big, print as another format // Todo: if too big, print as another format
pub fn stringify(&self) -> String { pub fn stringify(&self) -> String {
let mut buff: String = String::with_capacity(self.size() * 10 - 2); let mut buff: String = String::with_capacity(self.size() * 2);
for (pos, value) in self.0.iter().enumerate() { for value in &self.0 {
for i in 0..8 { buff.push_str(format!("{:x}", value.to_be()).as_str());
if (value & (1 << i)) == 0 {
buff.push('0');
} else {
buff.push('1');
}
}
if pos < self.size() - 1 {
buff.push_str(", ");
}
} }
buff buff
} }
@ -78,7 +69,7 @@ impl FfiBox {
bounds = bounds.offset(t); 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, // To deref a box space is to allow lua to read any space,
// which has security issues and is ultimately dangerous. // which has security issues and is ultimately dangerous.
// Therefore, box:ref():deref() is not allowed. // Therefore, box:ref():deref() is not allowed.

View file

@ -1,22 +1,11 @@
use core::ffi::c_char; use core::ffi::c_char;
use std::env::consts;
use std::vec::Vec; use std::vec::Vec;
pub const CHAR_IS_SIGNED: bool = c_char::MIN as u8 != u8::MIN; 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)> { pub fn get_platform_value() -> Vec<(&'static str, &'static str)> {
vec![ vec![(
// https://doc.rust-lang.org/std/env/consts/constant.ARCH.html "char_variant",
("arch", consts::ARCH), if CHAR_IS_SIGNED { "schar" } else { "uchar" },
// 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" },
),
]
} }

View file

@ -30,11 +30,11 @@ pub fn module(lua: &Lua) -> LuaResult<LuaTable> {
Ok(lib) Ok(lib)
})? })?
.with_function("struct", |lua, types: LuaTable| { .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) Ok(cstruct)
})? })?
.with_function("fn", |lua, (args, ret): (LuaTable, LuaAnyUserData)| { .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) Ok(cfn)
})?; })?;