Update luaffi

This commit is contained in:
2025-06-24 10:37:28 +10:00
parent 7548c68c7c
commit cadf0a8551
3 changed files with 201 additions and 130 deletions

View File

@@ -1,78 +0,0 @@
use crate::{Cdef, CdefBuilder, FfiReturnConvention, FromFfi, ToFfi, Type, TypeBuilder, display};
use std::{ffi::c_int, fmt::Display, ptr};
#[repr(C)]
#[allow(non_camel_case_types)]
pub enum lua_option<T> {
None, // __tag = 0
Some(T), // __tag = 1
}
unsafe impl<T: Type> Type for lua_option<T> {
fn name() -> impl Display {
display!("option__{}", T::name())
}
fn cdecl(name: impl Display) -> impl Display {
display!("struct option__{} {name}", T::name())
}
fn build(b: &mut TypeBuilder) {
b.include::<T>().cdef::<Self>();
}
}
unsafe impl<T: Type> Cdef for lua_option<T> {
fn build(b: &mut CdefBuilder) {
b.field::<c_int>("__tag").field::<T>("__value");
}
}
unsafe impl<T: FromFfi> FromFfi for Option<T> {
type From = lua_option<T::From>;
type FromArg = *mut Self::From; // pass by-ref
fn require_keepalive() -> bool {
T::require_keepalive()
}
fn prelude(arg: &str) -> impl Display {
let ct = Self::From::name();
display!(
"if {arg} == nil then {arg} = __new(__ct.{ct}); else {}{arg} = __new(__ct.{ct}, 1, {arg}); end; ",
T::prelude(arg)
)
}
fn convert(from: Self::From) -> Self {
match from {
lua_option::Some(value) => Some(T::convert(value)),
lua_option::None => None,
}
}
fn convert_arg(from: Self::FromArg) -> Self {
debug_assert!(!from.is_null());
Self::convert(unsafe { ptr::replace(from, lua_option::None) })
}
}
unsafe impl<T: ToFfi> ToFfi for Option<T> {
type To = lua_option<T::To>;
fn convert(self) -> Self::To {
match self {
Some(value) => lua_option::Some(value.convert()),
None => lua_option::None,
}
}
fn postlude(ret: &str, _conv: FfiReturnConvention) -> impl Display {
// if we don't have a value, return nil. otherwise copy out the inner value immediately,
// forget the option cdata, then call postlude on the inner value.
display!(
"if {ret}.__tag == 0 then {ret} = nil; else {ret} = {ret}.__value; {}end; ",
T::postlude(ret, FfiReturnConvention::ByValue)
)
}
}