|
|
|
|
@@ -1,4 +1,4 @@
|
|
|
|
|
use crate::__internal::{disp, display, write_sep};
|
|
|
|
|
use crate::__internal::{disp, display, export, write_sep};
|
|
|
|
|
pub use luaffi_impl::*;
|
|
|
|
|
use std::{
|
|
|
|
|
collections::HashSet,
|
|
|
|
|
@@ -31,6 +31,8 @@ unsafe extern "C" fn __is_utf8(ptr: *const u8, len: usize) -> bool {
|
|
|
|
|
simdutf8::basic::from_utf8(unsafe { slice::from_raw_parts(ptr, len) }).is_ok()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export![__keep, __is_utf8];
|
|
|
|
|
|
|
|
|
|
const CACHE_LIBS: &[(&str, &str)] = &[
|
|
|
|
|
("table", "table"),
|
|
|
|
|
("string", "string"),
|
|
|
|
|
@@ -47,7 +49,7 @@ const CACHE_LIBS: &[(&str, &str)] = &[
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
// https://www.lua.org/manual/5.1/manual.html#5.1
|
|
|
|
|
const CACHE_GLOBALS: &[(&str, &str)] = &[
|
|
|
|
|
const CACHE_LOCALS: &[(&str, &str)] = &[
|
|
|
|
|
// base
|
|
|
|
|
("assert", "assert"),
|
|
|
|
|
("error", "error"),
|
|
|
|
|
@@ -86,14 +88,16 @@ const CACHE_GLOBALS: &[(&str, &str)] = &[
|
|
|
|
|
("__fmod", "math.fmod"),
|
|
|
|
|
// coroutine
|
|
|
|
|
("__yield", "coroutine.yield"),
|
|
|
|
|
// package
|
|
|
|
|
("__preload", "package.preload"),
|
|
|
|
|
// debug
|
|
|
|
|
("__traceback", "debug.traceback"),
|
|
|
|
|
// ffi
|
|
|
|
|
("__C", "ffi.C"),
|
|
|
|
|
("__ct", "{}"),
|
|
|
|
|
("__cdef", "ffi.cdef"),
|
|
|
|
|
("__cnew", "ffi.new"),
|
|
|
|
|
("__ctype", "ffi.typeof"),
|
|
|
|
|
("__ctypes", "{}"),
|
|
|
|
|
("__new", "ffi.new"),
|
|
|
|
|
("__typeof", "ffi.typeof"),
|
|
|
|
|
("__istype", "ffi.istype"),
|
|
|
|
|
("__metatype", "ffi.metatype"),
|
|
|
|
|
("__cast", "ffi.cast"),
|
|
|
|
|
@@ -117,7 +121,7 @@ const CACHE_GLOBALS: &[(&str, &str)] = &[
|
|
|
|
|
fn cache_local(f: &mut Formatter, list: &[(&str, &str)]) -> fmt::Result {
|
|
|
|
|
write!(f, "local ")?;
|
|
|
|
|
write_sep(f, ", ", list.iter().map(|(s, _)| s))?;
|
|
|
|
|
write!(f, "\n = ")?;
|
|
|
|
|
write!(f, " = ")?;
|
|
|
|
|
write_sep(f, ", ", list.iter().map(|(_, s)| s))?;
|
|
|
|
|
writeln!(f, ";")
|
|
|
|
|
}
|
|
|
|
|
@@ -141,7 +145,7 @@ impl Registry {
|
|
|
|
|
pub fn include<T: Type>(&mut self) -> &mut Self {
|
|
|
|
|
self.types
|
|
|
|
|
.insert(T::name().to_string())
|
|
|
|
|
.then(|| T::build(&mut TypeBuilder::new(self)));
|
|
|
|
|
.then(|| T::build(&mut TypeBuilder::new::<T>(self)));
|
|
|
|
|
self
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -149,7 +153,18 @@ impl Registry {
|
|
|
|
|
self.include::<T>()
|
|
|
|
|
.funcs
|
|
|
|
|
.insert(name.to_string())
|
|
|
|
|
.then(|| writeln!(self.cdef, "{};", T::cdecl(name)).unwrap());
|
|
|
|
|
.then(|| writeln!(self.cdef, "{};", T::extern_cdecl(name)).unwrap());
|
|
|
|
|
self
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn preload<T: Type>(&mut self, name: impl Display) -> &mut Self {
|
|
|
|
|
self.include::<T>();
|
|
|
|
|
writeln!(
|
|
|
|
|
self.lua,
|
|
|
|
|
r#"__preload["{name}"] = function(...) return __ct.{}(...); end;"#,
|
|
|
|
|
T::name()
|
|
|
|
|
)
|
|
|
|
|
.unwrap();
|
|
|
|
|
self
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -164,8 +179,8 @@ impl Display for Registry {
|
|
|
|
|
let version = env!("CARGO_PKG_VERSION");
|
|
|
|
|
writeln!(f, "--- automatically generated by {name} {version}")?;
|
|
|
|
|
cache_local(f, CACHE_LIBS)?;
|
|
|
|
|
cache_local(f, CACHE_GLOBALS)?;
|
|
|
|
|
writeln!(f, "__cdef [[{}]];", self.cdef)?;
|
|
|
|
|
cache_local(f, CACHE_LOCALS)?;
|
|
|
|
|
writeln!(f, "__cdef [[\n{}\n]];", self.cdef.trim())?;
|
|
|
|
|
write!(f, "{}", self.lua)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -173,6 +188,10 @@ impl Display for Registry {
|
|
|
|
|
pub unsafe trait Type {
|
|
|
|
|
fn name() -> impl Display;
|
|
|
|
|
fn cdecl(name: impl Display) -> impl Display;
|
|
|
|
|
fn extern_cdecl(name: impl Display) -> impl Display {
|
|
|
|
|
Self::cdecl(name)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn build(b: &mut TypeBuilder);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -182,7 +201,10 @@ pub struct TypeBuilder<'r> {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'r> TypeBuilder<'r> {
|
|
|
|
|
fn new(registry: &'r mut Registry) -> Self {
|
|
|
|
|
fn new<T: Type>(registry: &'r mut Registry) -> Self {
|
|
|
|
|
let ct = T::name();
|
|
|
|
|
let cdecl = T::cdecl("");
|
|
|
|
|
writeln!(registry.lua, r#"__ct.{ct} = __typeof("{cdecl}");"#).unwrap();
|
|
|
|
|
Self { registry }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -283,7 +305,6 @@ pub unsafe trait Metatype {
|
|
|
|
|
pub struct MetatypeBuilder<'r> {
|
|
|
|
|
registry: &'r mut Registry,
|
|
|
|
|
name: String,
|
|
|
|
|
cdecl: String,
|
|
|
|
|
cdef: String,
|
|
|
|
|
lua: String,
|
|
|
|
|
}
|
|
|
|
|
@@ -293,7 +314,6 @@ impl<'r> MetatypeBuilder<'r> {
|
|
|
|
|
Self {
|
|
|
|
|
registry,
|
|
|
|
|
name: T::Target::name().to_string(),
|
|
|
|
|
cdecl: T::Target::cdecl("").to_string(),
|
|
|
|
|
cdef: String::new(),
|
|
|
|
|
lua: r#"do local __mt, __idx = {}, {}; __mt.__index = __idx; "#.into(),
|
|
|
|
|
}
|
|
|
|
|
@@ -325,7 +345,7 @@ impl<'r> MetatypeBuilder<'r> {
|
|
|
|
|
name: impl Display,
|
|
|
|
|
f: impl FnOnce(&mut MetatypeMethodBuilder),
|
|
|
|
|
) -> &mut Self {
|
|
|
|
|
write!(self.lua, "__mt.{name} = ").unwrap();
|
|
|
|
|
write!(self.lua, "__mt.__{name} = ").unwrap();
|
|
|
|
|
f(&mut MetatypeMethodBuilder::new(self));
|
|
|
|
|
write!(self.lua, "; ").unwrap();
|
|
|
|
|
self
|
|
|
|
|
@@ -342,7 +362,6 @@ impl<'r> Drop for MetatypeBuilder<'r> {
|
|
|
|
|
let Self {
|
|
|
|
|
registry,
|
|
|
|
|
name,
|
|
|
|
|
cdecl,
|
|
|
|
|
cdef,
|
|
|
|
|
lua,
|
|
|
|
|
..
|
|
|
|
|
@@ -350,12 +369,7 @@ impl<'r> Drop for MetatypeBuilder<'r> {
|
|
|
|
|
|
|
|
|
|
registry.cdef.push_str(cdef);
|
|
|
|
|
registry.lua.push_str(lua);
|
|
|
|
|
|
|
|
|
|
writeln!(
|
|
|
|
|
registry.lua,
|
|
|
|
|
r#"__ctypes.{name} = __metatype("{cdecl}", __mt); end;"#
|
|
|
|
|
)
|
|
|
|
|
.unwrap();
|
|
|
|
|
writeln!(registry.lua, r#"__metatype(__ct.{name}, __mt); end;"#).unwrap();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -414,8 +428,6 @@ impl<'r, 'm> MetatypeMethodBuilder<'r, 'm> {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn param<T: FromFfi>(&mut self, name: impl Display) -> &mut Self {
|
|
|
|
|
self.metatype.registry.include::<T::From>();
|
|
|
|
|
|
|
|
|
|
(!self.params.is_empty()).then(|| self.params.push_str(", "));
|
|
|
|
|
(!self.args.is_empty()).then(|| self.args.push_str(", "));
|
|
|
|
|
write!(self.params, "{name}").unwrap();
|
|
|
|
|
@@ -450,6 +462,12 @@ impl<'r, 'm> MetatypeMethodBuilder<'r, 'm> {
|
|
|
|
|
self
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn param_ignored(&mut self) -> &mut Self {
|
|
|
|
|
(!self.params.is_empty()).then(|| self.params.push_str(", "));
|
|
|
|
|
write!(self.params, "_").unwrap();
|
|
|
|
|
self
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn call<T: ToFfi>(&mut self, func: impl Display, ret: FfiReturnConvention) {
|
|
|
|
|
let Self {
|
|
|
|
|
metatype,
|
|
|
|
|
@@ -459,8 +477,6 @@ impl<'r, 'm> MetatypeMethodBuilder<'r, 'm> {
|
|
|
|
|
postlude,
|
|
|
|
|
} = self;
|
|
|
|
|
|
|
|
|
|
metatype.registry.include::<T::To>();
|
|
|
|
|
|
|
|
|
|
let lua = &mut metatype.lua;
|
|
|
|
|
write!(lua, "function({params}) {prelude}").unwrap();
|
|
|
|
|
|
|
|
|
|
@@ -469,21 +485,21 @@ impl<'r, 'm> MetatypeMethodBuilder<'r, 'm> {
|
|
|
|
|
write!(lua, "__C.{func}({args}); {postlude}end").unwrap();
|
|
|
|
|
}
|
|
|
|
|
FfiReturnConvention::ByValue => {
|
|
|
|
|
let check = T::postlude("res", ret);
|
|
|
|
|
let check = T::postlude("__res", ret);
|
|
|
|
|
write!(
|
|
|
|
|
lua,
|
|
|
|
|
"local res = __C.{func}({args}); {check}{postlude}return res; end"
|
|
|
|
|
"local __res = __C.{func}({args}); {check}{postlude}return __res; end"
|
|
|
|
|
)
|
|
|
|
|
.unwrap();
|
|
|
|
|
}
|
|
|
|
|
FfiReturnConvention::ByOutParam => {
|
|
|
|
|
let ct = T::To::name();
|
|
|
|
|
let check = T::postlude("res", ret);
|
|
|
|
|
write!(lua, "local res = __cnew(__ctypes.{ct}); __C.{func}(res").unwrap();
|
|
|
|
|
let check = T::postlude("__res", ret);
|
|
|
|
|
write!(lua, "local __res = __new(__ct.{ct}); __C.{func}(__res").unwrap();
|
|
|
|
|
if !args.is_empty() {
|
|
|
|
|
write!(lua, ", {args}").unwrap();
|
|
|
|
|
}
|
|
|
|
|
write!(lua, "); {check}{postlude}return res; end").unwrap()
|
|
|
|
|
write!(lua, "); {check}{postlude}return __res; end").unwrap()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -560,7 +576,7 @@ macro_rules! impl_copy_primitive {
|
|
|
|
|
|
|
|
|
|
#[allow(unused)]
|
|
|
|
|
fn postlude(ret: &str, conv: FfiReturnConvention) -> impl Display {
|
|
|
|
|
disp(move |f| {
|
|
|
|
|
disp(move |f| Ok({
|
|
|
|
|
match conv {
|
|
|
|
|
FfiReturnConvention::Void => unreachable!(),
|
|
|
|
|
FfiReturnConvention::ByValue => {},
|
|
|
|
|
@@ -568,9 +584,7 @@ macro_rules! impl_copy_primitive {
|
|
|
|
|
// the cdata containing the value and convert it to the equivalent lua value
|
|
|
|
|
FfiReturnConvention::ByOutParam => { $(write!(f, "{ret} = {}; ", $unwrap(ret))?;)? },
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
})
|
|
|
|
|
}))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
@@ -592,7 +606,7 @@ impl_copy_primitive!(c_double, "double", "number", |n| display!("tonumber({n})")
|
|
|
|
|
|
|
|
|
|
unsafe impl<T: Type> Type for *const T {
|
|
|
|
|
fn name() -> impl Display {
|
|
|
|
|
display!("ptr_const_{}", T::name())
|
|
|
|
|
display!("const_{}_ptr", T::name())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn cdecl(name: impl Display) -> impl Display {
|
|
|
|
|
@@ -606,7 +620,7 @@ unsafe impl<T: Type> Type for *const T {
|
|
|
|
|
|
|
|
|
|
unsafe impl<T: Type> Type for *mut T {
|
|
|
|
|
fn name() -> impl Display {
|
|
|
|
|
display!("ptr_mut_{}", T::name())
|
|
|
|
|
display!("{}_ptr", T::name())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn cdecl(name: impl Display) -> impl Display {
|
|
|
|
|
@@ -684,7 +698,7 @@ unsafe impl<T: Type> ToFfi for *mut T {
|
|
|
|
|
//
|
|
|
|
|
unsafe impl<T: Type> Type for &T {
|
|
|
|
|
fn name() -> impl Display {
|
|
|
|
|
display!("ref_const_{}", T::name())
|
|
|
|
|
display!("const_{}_ptr", T::name())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn cdecl(name: impl Display) -> impl Display {
|
|
|
|
|
@@ -698,7 +712,7 @@ unsafe impl<T: Type> Type for &T {
|
|
|
|
|
|
|
|
|
|
unsafe impl<T: Type> Type for &mut T {
|
|
|
|
|
fn name() -> impl Display {
|
|
|
|
|
display!("ref_mut_{}", T::name())
|
|
|
|
|
display!("{}_ptr", T::name())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn cdecl(name: impl Display) -> impl Display {
|
|
|
|
|
@@ -782,7 +796,7 @@ unsafe impl<T: Type> FromFfi for &mut T {
|
|
|
|
|
//
|
|
|
|
|
unsafe impl<T: Type> Type for [T] {
|
|
|
|
|
fn name() -> impl Display {
|
|
|
|
|
display!("arr_{}", T::name())
|
|
|
|
|
display!("{}_arr", T::name())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn cdecl(name: impl Display) -> impl Display {
|
|
|
|
|
@@ -796,7 +810,7 @@ unsafe impl<T: Type> Type for [T] {
|
|
|
|
|
|
|
|
|
|
unsafe impl<T: Type, const N: usize> Type for [T; N] {
|
|
|
|
|
fn name() -> impl Display {
|
|
|
|
|
display!("arr{N}_{}", T::name())
|
|
|
|
|
display!("{}_arr{N}", T::name())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn cdecl(name: impl Display) -> impl Display {
|
|
|
|
|
@@ -824,20 +838,29 @@ macro_rules! impl_function {
|
|
|
|
|
//
|
|
|
|
|
unsafe impl<$($arg: Type,)* $ret: Type> Type for $($type)+ {
|
|
|
|
|
fn name() -> impl Display {
|
|
|
|
|
disp(|f| {
|
|
|
|
|
write!(f, "fn")?;
|
|
|
|
|
disp(|f| Ok({
|
|
|
|
|
write!(f, "fn_{}", $ret::name())?;
|
|
|
|
|
$(write!(f, "_{}", $arg::name())?;)*
|
|
|
|
|
write!(f, "_{}", $ret::name())
|
|
|
|
|
})
|
|
|
|
|
}))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn cdecl(name: impl Display) -> impl Display {
|
|
|
|
|
$ret::cdecl(disp(move |f| {
|
|
|
|
|
$ret::cdecl(disp(move |f| Ok({
|
|
|
|
|
let mut _n = 0;
|
|
|
|
|
write!(f, "(*{name})(")?;
|
|
|
|
|
$(if _n != 0 { write!(f, ", ")?; } write!(f, "{}", $arg::cdecl(""))?; _n += 1;)*
|
|
|
|
|
write!(f, ")")
|
|
|
|
|
}))
|
|
|
|
|
write!(f, ")")?;
|
|
|
|
|
})))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn extern_cdecl(name: impl Display) -> impl Display {
|
|
|
|
|
$ret::cdecl(disp(move |f| Ok({
|
|
|
|
|
// for top-level function declarations in cdef
|
|
|
|
|
let mut _n = 0;
|
|
|
|
|
write!(f, "{name}(")?;
|
|
|
|
|
$(if _n != 0 { write!(f, ", ")?; } write!(f, "{}", $arg::cdecl(""))?; _n += 1;)*
|
|
|
|
|
write!(f, ")")?;
|
|
|
|
|
})))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn build(b: &mut TypeBuilder) {
|
|
|
|
|
|