Refactor and overhaul luajit crate

This commit is contained in:
2025-06-30 05:59:54 +10:00
parent 7768c5ec56
commit 1808bee82a
10 changed files with 1190 additions and 569 deletions

View File

@@ -18,6 +18,7 @@ net = ["tokio/net", "tokio/io-util"]
derive_more = { version = "2.0.1", features = ["full"] }
globset = { version = "0.4.16", optional = true }
luaffi = { path = "../luaffi" }
luaify = { path = "../luaify" }
luajit = { path = "../luajit" }
sysexits = "0.9.0"
tempfile = { version = "3.20.0", optional = true }

View File

@@ -1,7 +1,8 @@
#![doc(hidden)]
use derive_more::{Deref, DerefMut};
use luaffi::{Module, Registry};
use luajit::{Chunk, State};
use luaify::luaify_chunk;
use luajit::{Chunk, Index, NewTable, State};
use std::rc::Rc;
use tokio::{
task::{JoinHandle, LocalSet, futures::TaskLocalFuture, spawn_local},
@@ -13,6 +14,7 @@ pub type ErrorFn = dyn Fn(&luajit::Error);
pub struct Builder {
registry: Registry,
report_err: Rc<ErrorFn>,
prohibit_globals: bool,
}
impl Builder {
@@ -23,6 +25,7 @@ impl Builder {
Some(trace) => eprintln!("unhandled lua error: {err}\n{trace}"),
None => eprintln!("unhandled lua error: {err}"),
}),
prohibit_globals: false,
}
}
@@ -35,19 +38,42 @@ impl Builder {
self
}
pub fn prohibit_globals(&mut self, enabled: bool) -> &mut Self {
self.prohibit_globals = enabled;
self
}
pub fn module<T: Module>(&mut self) -> &mut Self {
self.registry.preload::<T>();
self
}
pub fn build(&self) -> luajit::Result<Runtime> {
let mut state = State::new()?;
let chunk = Chunk::new(self.registry.build()).with_path("[luby]");
state.eval(&chunk, 0, Some(0))?;
if self.prohibit_globals {
let mut s = state.guard();
s.eval(
&Chunk::new(luaify_chunk!({
return |self, key, value| {
error(("undeclared local variable '%s'").format(key), 2);
};
})),
0,
Some(1),
)
.unwrap();
s.push(NewTable::new());
(s.push("__index"), s.push_idx(-3), s.set(-3));
(s.push("__newindex"), s.push_idx(-3), s.set(-3));
s.set_metatable(Index::globals());
}
Ok(Runtime {
cx: Context {
state: {
let mut s = State::new()?;
s.eval(Chunk::new(self.registry.build()).path("[luby]"), 0, 0)?;
s
},
state,
report_err: self.report_err.clone(),
},
tasks: LocalSet::new(),
@@ -97,7 +123,7 @@ pub struct Context {
impl Context {
pub fn new_thread(&self) -> Self {
Self {
state: self.state.new_thread(),
state: State::new_thread(&self.state),
report_err: self.report_err.clone(),
}
}

View File

@@ -12,7 +12,6 @@ use luaffi::{
marker::{function, many},
metatype,
};
use luajit::LUA_MULTRET;
use std::{cell::RefCell, ffi::c_int, time::Duration};
use tokio::{task::JoinHandle, time::sleep};
@@ -59,12 +58,12 @@ impl lb_tasklib {
extern "Lua-C" fn __spawn(spawn_ref: c_int, handle_ref: c_int) -> lb_task {
let handle = spawn(async move |cx| {
// SAFETY: handle_ref is always unique, created in Self::spawn above.
let state = unsafe { cx.new_ref_unchecked(spawn_ref) };
let state = unsafe { luajit::Ref::from_raw(cx, spawn_ref) };
let mut s = cx.guard();
s.resize(0);
s.push(state); // this drops the state table ref, but the table is still on the stack
let narg = s.unpack(1, 1, None) - 1; // unpack the function and its args from the state table
match s.call_async(narg, LUA_MULTRET).await {
match s.call_async(narg, None).await {
Ok(nret) => {
s.pack(1, nret); // pack the return values back into the state table
}

View File

@@ -1,3 +1,6 @@
//! # luaify
//!
//! A Rust for generating Lua code from Rust syntax.
use crate::{
generate::{generate, generate_chunk},
transform::{transform, transform_chunk},

View File

@@ -16,4 +16,3 @@ bitflags = { version = "2.9.1", features = ["std"] }
bstr = "1.12.0"
luaffi = { path = "../luaffi" }
luajit-sys = { path = "../luajit-sys" }
thiserror = "2.0.12"

File diff suppressed because it is too large Load Diff