Improve cdef loading time by trimming unnecessary ctype caching
This commit is contained in:
parent
e027623d40
commit
ccae0046fb
@ -129,7 +129,7 @@ fn cache_local(f: &mut Formatter, list: &[(&str, &str)]) -> fmt::Result {
|
|||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
pub struct Registry {
|
pub struct Registry {
|
||||||
types: HashSet<String>,
|
types: HashSet<String>,
|
||||||
funcs: HashSet<String>,
|
decls: HashSet<String>,
|
||||||
cdef: String,
|
cdef: String,
|
||||||
lua: String,
|
lua: String,
|
||||||
}
|
}
|
||||||
@ -146,16 +146,16 @@ impl Registry {
|
|||||||
pub fn include<T: Type>(&mut self) -> &mut Self {
|
pub fn include<T: Type>(&mut self) -> &mut Self {
|
||||||
self.types
|
self.types
|
||||||
.insert(T::name().to_string())
|
.insert(T::name().to_string())
|
||||||
.then(|| T::build(&mut TypeBuilder::new::<T>(self)));
|
.then(|| T::build(&mut TypeBuilder::new(self)));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn declare<T: Type>(&mut self, name: impl Display) -> &mut Self {
|
pub fn declare<T: Type>(&mut self, name: impl Display) -> &mut Self {
|
||||||
assert!(T::ty() != TypeType::Void, "cannot declare void type");
|
assert!(T::ty() != TypeType::Void, "cannot declare void type");
|
||||||
self.include::<T>()
|
self.include::<T>()
|
||||||
.funcs
|
.decls
|
||||||
.insert(name.to_string())
|
.insert(T::extern_cdecl(&name).to_string())
|
||||||
.then(|| writeln!(self.cdef, "{};", T::extern_cdecl(name)).unwrap());
|
.then(|| writeln!(self.cdef, "{};", T::extern_cdecl(&name)).unwrap());
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,7 +184,7 @@ impl Display for Registry {
|
|||||||
cache_local(f, CACHE_LIBS)?;
|
cache_local(f, CACHE_LIBS)?;
|
||||||
cache_local(f, CACHE_LOCALS)?;
|
cache_local(f, CACHE_LOCALS)?;
|
||||||
writeln!(f, "{}", include_str!("./lib.lua"))?;
|
writeln!(f, "{}", include_str!("./lib.lua"))?;
|
||||||
writeln!(f, "__cdef [[\n{}\n]];", self.cdef.trim())?;
|
writeln!(f, "__cdef [[\n{}\n]];", self.cdef.trim_end())?;
|
||||||
write!(f, "{}", self.lua)
|
write!(f, "{}", self.lua)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -210,31 +210,23 @@ pub enum TypeType {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct TypeBuilder<'r> {
|
pub struct TypeBuilder<'r> {
|
||||||
registry: &'r mut Registry,
|
reg: &'r mut Registry,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'r> TypeBuilder<'r> {
|
impl<'r> TypeBuilder<'r> {
|
||||||
fn new<T: Type>(registry: &'r mut Registry) -> Self {
|
fn new(reg: &'r mut Registry) -> Self {
|
||||||
let ct = T::name();
|
Self { reg }
|
||||||
let cdecl = T::cdecl("");
|
|
||||||
writeln!(registry.lua, r#"__ct.{ct} = __typeof("{cdecl}");"#).unwrap();
|
|
||||||
Self { registry }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn include<T: Type>(&mut self) -> &mut Self {
|
|
||||||
self.registry.include::<T>();
|
|
||||||
self
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cdef<T: Cdef>(&mut self) -> &mut Self {
|
pub fn cdef<T: Cdef>(&mut self) -> &mut Self {
|
||||||
let mut b = CdefBuilder::new::<T>(self.registry);
|
let mut b = CdefBuilder::new::<T>(self.reg);
|
||||||
<T as Cdef>::build(&mut b);
|
<T as Cdef>::build(&mut b);
|
||||||
drop(b);
|
drop(b);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn metatype<T: Metatype>(&mut self) -> &mut Self {
|
pub fn metatype<T: Metatype>(&mut self) -> &mut Self {
|
||||||
let mut b = MetatypeBuilder::new::<T>(self.registry);
|
let mut b = MetatypeBuilder::new::<T>(self.reg);
|
||||||
<T as Metatype>::build(&mut b);
|
<T as Metatype>::build(&mut b);
|
||||||
drop(b);
|
drop(b);
|
||||||
self
|
self
|
||||||
@ -251,16 +243,16 @@ pub unsafe trait Cdef: Type {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct CdefBuilder<'r> {
|
pub struct CdefBuilder<'r> {
|
||||||
registry: &'r mut Registry,
|
reg: &'r mut Registry,
|
||||||
cdef: String,
|
cdef: String,
|
||||||
align: usize,
|
align: usize,
|
||||||
opaque: usize,
|
opaque: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'r> CdefBuilder<'r> {
|
impl<'r> CdefBuilder<'r> {
|
||||||
fn new<T: Cdef>(registry: &'r mut Registry) -> Self {
|
fn new<T: Cdef>(reg: &'r mut Registry) -> Self {
|
||||||
Self {
|
Self {
|
||||||
registry,
|
reg,
|
||||||
cdef: format!("{} {{ ", T::cdecl("")),
|
cdef: format!("{} {{ ", T::cdecl("")),
|
||||||
align: mem::align_of::<T>(),
|
align: mem::align_of::<T>(),
|
||||||
opaque: 0,
|
opaque: 0,
|
||||||
@ -269,7 +261,7 @@ impl<'r> CdefBuilder<'r> {
|
|||||||
|
|
||||||
pub fn field<T: Type>(&mut self, name: impl Display) -> &mut Self {
|
pub fn field<T: Type>(&mut self, name: impl Display) -> &mut Self {
|
||||||
assert!(T::ty() != TypeType::Void, "cannot declare void field");
|
assert!(T::ty() != TypeType::Void, "cannot declare void field");
|
||||||
self.registry.include::<T>();
|
self.reg.include::<T>();
|
||||||
self.field_raw(T::cdecl(name))
|
self.field_raw(T::cdecl(name))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -303,14 +295,11 @@ impl<'r> CdefBuilder<'r> {
|
|||||||
impl<'r> Drop for CdefBuilder<'r> {
|
impl<'r> Drop for CdefBuilder<'r> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
let Self {
|
let Self {
|
||||||
registry,
|
reg, cdef, align, ..
|
||||||
cdef,
|
|
||||||
align,
|
|
||||||
..
|
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
registry.cdef.push_str(cdef);
|
reg.cdef.push_str(cdef);
|
||||||
writeln!(registry.cdef, "}} __attribute__((aligned({align})));").unwrap();
|
writeln!(reg.cdef, "}} __attribute__((aligned({align})));").unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -321,26 +310,34 @@ pub unsafe trait Metatype {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct MetatypeBuilder<'r> {
|
pub struct MetatypeBuilder<'r> {
|
||||||
registry: &'r mut Registry,
|
reg: &'r mut Registry,
|
||||||
ct: String,
|
ct: String,
|
||||||
cdef: String,
|
cdef: String,
|
||||||
lua: String,
|
lua: String,
|
||||||
lua_includes: Vec<&'static str>,
|
lua_includes: Vec<&'static str>,
|
||||||
|
has_index: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'r> MetatypeBuilder<'r> {
|
impl<'r> MetatypeBuilder<'r> {
|
||||||
fn new<T: Metatype>(registry: &'r mut Registry) -> Self {
|
fn new<T: Metatype>(reg: &'r mut Registry) -> Self {
|
||||||
|
// NOTE: this needs to be written first, because recursively included dependency types might
|
||||||
|
// need it
|
||||||
|
let ct = T::Target::name();
|
||||||
|
let cdecl = T::Target::cdecl("");
|
||||||
|
writeln!(reg.lua, r#"__ct.{ct} = __typeof("{cdecl}");"#).unwrap();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
registry,
|
reg,
|
||||||
ct: T::Target::name().to_string(),
|
ct: T::Target::name().to_string(),
|
||||||
cdef: String::new(),
|
cdef: String::new(),
|
||||||
lua: r#"do local __mt, __idx = {}, {}; __mt.__index = __idx; "#.into(),
|
lua: String::new(),
|
||||||
lua_includes: vec![],
|
lua_includes: vec![],
|
||||||
|
has_index: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn declare<T: Type>(&mut self, name: impl Display) -> &mut Self {
|
pub fn declare<T: Type>(&mut self, name: impl Display) -> &mut Self {
|
||||||
self.registry.declare::<T>(name);
|
self.reg.declare::<T>(name);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -357,11 +354,13 @@ impl<'r> MetatypeBuilder<'r> {
|
|||||||
write!(self.lua, "__idx.{name} = ").unwrap();
|
write!(self.lua, "__idx.{name} = ").unwrap();
|
||||||
f(&mut MetatypeFunctionBuilder::new(self));
|
f(&mut MetatypeFunctionBuilder::new(self));
|
||||||
writeln!(self.lua, ";").unwrap();
|
writeln!(self.lua, ";").unwrap();
|
||||||
|
self.has_index = true;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn index_raw(&mut self, name: impl Display, value: impl Display) -> &mut Self {
|
pub fn index_raw(&mut self, name: impl Display, value: impl Display) -> &mut Self {
|
||||||
writeln!(self.lua, "__idx.{name} = {value};").unwrap();
|
writeln!(self.lua, "__idx.{name} = {value};").unwrap();
|
||||||
|
self.has_index = true;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -385,18 +384,27 @@ impl<'r> MetatypeBuilder<'r> {
|
|||||||
impl<'r> Drop for MetatypeBuilder<'r> {
|
impl<'r> Drop for MetatypeBuilder<'r> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
let Self {
|
let Self {
|
||||||
registry,
|
reg,
|
||||||
ct,
|
ct,
|
||||||
cdef,
|
cdef,
|
||||||
lua,
|
lua,
|
||||||
lua_includes: lua_postlude,
|
lua_includes,
|
||||||
|
has_index,
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
registry.cdef.push_str(cdef);
|
write!(reg.lua, r#"do local __mt = {{}}; "#).unwrap();
|
||||||
registry.lua.push_str(lua);
|
|
||||||
writeln!(registry.lua, r#"__metatype(__ct.{ct}, __mt); end;"#).unwrap();
|
if *has_index {
|
||||||
for lua in lua_postlude {
|
write!(reg.lua, r#"local __idx = {{}}; __mt.__index = __idx; "#).unwrap();
|
||||||
writeln!(registry.lua, r#"do {lua} end;"#).unwrap();
|
}
|
||||||
|
|
||||||
|
reg.cdef.push_str(cdef);
|
||||||
|
reg.lua.push_str(lua.trim_end());
|
||||||
|
|
||||||
|
writeln!(reg.lua, r#"__metatype(__ct.{ct}, __mt); end;"#).unwrap();
|
||||||
|
|
||||||
|
for lua in lua_includes {
|
||||||
|
writeln!(reg.lua, "do {}\nend;", lua.trim_end()).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -471,7 +479,7 @@ impl<'r, 'm> MetatypeFunctionBuilder<'r, 'm> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let Self {
|
let Self {
|
||||||
metatype: MetatypeBuilder { registry, .. },
|
metatype: MetatypeBuilder { reg, .. },
|
||||||
lparams,
|
lparams,
|
||||||
cparams,
|
cparams,
|
||||||
cargs,
|
cargs,
|
||||||
@ -480,7 +488,7 @@ impl<'r, 'm> MetatypeFunctionBuilder<'r, 'm> {
|
|||||||
..
|
..
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
registry.include::<T::From>();
|
reg.include::<T::From>();
|
||||||
|
|
||||||
(!lparams.is_empty()).then(|| lparams.push_str(", "));
|
(!lparams.is_empty()).then(|| lparams.push_str(", "));
|
||||||
(!cparams.is_empty()).then(|| cparams.push_str(", "));
|
(!cparams.is_empty()).then(|| cparams.push_str(", "));
|
||||||
@ -552,13 +560,7 @@ impl<'r, 'm> MetatypeFunctionBuilder<'r, 'm> {
|
|||||||
|
|
||||||
pub fn call<T: IntoFfi>(&mut self, func: impl Display) {
|
pub fn call<T: IntoFfi>(&mut self, func: impl Display) {
|
||||||
let Self {
|
let Self {
|
||||||
metatype:
|
metatype: MetatypeBuilder { reg, cdef, lua, .. },
|
||||||
MetatypeBuilder {
|
|
||||||
registry,
|
|
||||||
cdef,
|
|
||||||
lua,
|
|
||||||
..
|
|
||||||
},
|
|
||||||
lparams,
|
lparams,
|
||||||
cparams,
|
cparams,
|
||||||
cargs,
|
cargs,
|
||||||
@ -567,7 +569,7 @@ impl<'r, 'm> MetatypeFunctionBuilder<'r, 'm> {
|
|||||||
..
|
..
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
registry.include::<T::Into>();
|
reg.include::<T::Into>();
|
||||||
write!(lua, "function({lparams}) {prelude}").unwrap();
|
write!(lua, "function({lparams}) {prelude}").unwrap();
|
||||||
|
|
||||||
match T::convention() {
|
match T::convention() {
|
||||||
@ -812,7 +814,7 @@ macro_rules! impl_ptr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn build(b: &mut TypeBuilder) {
|
fn build(b: &mut TypeBuilder) {
|
||||||
b.include::<T>();
|
b.reg.include::<T>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -1009,7 +1011,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn build(b: &mut TypeBuilder) {
|
fn build(b: &mut TypeBuilder) {
|
||||||
b.include::<T>();
|
b.reg.include::<T>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1039,7 +1041,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn build(b: &mut TypeBuilder) {
|
fn build(b: &mut TypeBuilder) {
|
||||||
b.include::<T>();
|
b.reg.include::<T>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1103,8 +1105,8 @@ macro_rules! impl_externcfn {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn build(b: &mut TypeBuilder) {
|
fn build(b: &mut TypeBuilder) {
|
||||||
$(b.include::<$arg>();)*
|
$(b.reg.include::<$arg>();)*
|
||||||
b.include::<$ret>();
|
b.reg.include::<$ret>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
__internal::{disp, display, type_id},
|
__internal::{disp, display, type_id},
|
||||||
Cdef, CdefBuilder, IntoFfi, KEEP_FN, Type, TypeBuilder, TypeType,
|
Cdef, CdefBuilder, IntoFfi, KEEP_FN, Metatype, MetatypeBuilder, Type, TypeBuilder, TypeType,
|
||||||
};
|
};
|
||||||
use std::{ffi::c_int, fmt::Display};
|
use std::{ffi::c_int, fmt::Display};
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ unsafe impl<T: Type + 'static> Type for lua_option<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn build(b: &mut TypeBuilder) {
|
fn build(b: &mut TypeBuilder) {
|
||||||
b.cdef::<Self>();
|
b.cdef::<Self>().metatype::<Self>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,6 +36,11 @@ unsafe impl<T: Type + 'static> Cdef for lua_option<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe impl<T: Type + 'static> Metatype for lua_option<T> {
|
||||||
|
type Target = Self;
|
||||||
|
fn build(_b: &mut MetatypeBuilder) {}
|
||||||
|
}
|
||||||
|
|
||||||
unsafe impl<T: IntoFfi<Into: 'static>> IntoFfi for Option<T> {
|
unsafe impl<T: IntoFfi<Into: 'static>> IntoFfi for Option<T> {
|
||||||
type Into = lua_option<T::Into>;
|
type Into = lua_option<T::Into>;
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
__internal::{disp, display, type_id},
|
__internal::{disp, display, type_id},
|
||||||
Cdef, CdefBuilder, IntoFfi, KEEP_FN, Type, TypeBuilder, TypeType,
|
Cdef, CdefBuilder, IntoFfi, KEEP_FN, Metatype, MetatypeBuilder, Type, TypeBuilder, TypeType,
|
||||||
string::{DROP_BUFFER_FN, lua_buffer},
|
string::{DROP_BUFFER_FN, lua_buffer},
|
||||||
};
|
};
|
||||||
use std::{ffi::c_int, fmt::Display};
|
use std::{ffi::c_int, fmt::Display};
|
||||||
@ -26,7 +26,7 @@ unsafe impl<T: Type + 'static> Type for lua_result<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn build(b: &mut TypeBuilder) {
|
fn build(b: &mut TypeBuilder) {
|
||||||
b.cdef::<Self>();
|
b.cdef::<Self>().metatype::<Self>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,6 +39,11 @@ unsafe impl<T: Type + 'static> Cdef for lua_result<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe impl<T: Type + 'static> Metatype for lua_result<T> {
|
||||||
|
type Target = Self;
|
||||||
|
fn build(_b: &mut MetatypeBuilder) {}
|
||||||
|
}
|
||||||
|
|
||||||
unsafe impl<T: IntoFfi<Into: 'static>, E: Display> IntoFfi for Result<T, E> {
|
unsafe impl<T: IntoFfi<Into: 'static>, E: Display> IntoFfi for Result<T, E> {
|
||||||
type Into = lua_result<T::Into>;
|
type Into = lua_result<T::Into>;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user