Skip to content

Commit

Permalink
add support for luau and luau-jit interpreters
Browse files Browse the repository at this point in the history
  • Loading branch information
emuell committed Jun 28, 2024
1 parent b18c044 commit c095f2f
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 32 deletions.
21 changes: 18 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,19 +40,34 @@ notify = { version = "^6.1" }
ctrlc = { version = "^3.4" }
criterion = { version = "^0.5" }

[profile.dev]
debug = 1

[profile.bench]
debug = 1

[profile.release]
debug = 1

[features]
# enables profiling in examples
dhat-profiler = ["dhat"]

# example player implementation
player = ["crossbeam-channel", "afplay"]

# lua scripting
scripting = ["mlua"]
lua51 = ["mlua/lua51"]
luajit = ["mlua/luajit"]
default = ["scripting", "luajit"]

# lua scripting interpreter backends (mutually exclusive)
# all featured interpreters should be compatible with lua51
lua = ["mlua/lua51"]
lua-jit = ["mlua/luajit"]
luau = ["mlua/luau"]
luau-jit = ["mlua/luau-jit"]

# default features enable scripting with a luaJIT interpreter
default = ["scripting", "lua-jit"]

[lib]
bench = false
Expand Down
43 changes: 22 additions & 21 deletions src/bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,13 +300,8 @@ fn register_math_bindings(lua: &mut Lua) -> LuaResult<()> {

// cache module bytecode to speed up initialization
lazy_static! {
static ref MATH_BYTECODE: LuaResult<Vec<u8>> = {
let strip = true;
Lua::new_with(LuaStdLib::NONE, LuaOptions::default())?
.load(include_str!("../types/nerdo/library/math.lua"))
.into_function()
.map(|x| x.dump(strip))
};
static ref MATH_BYTECODE: LuaResult<Vec<u8>> =
compile_chunk(include_str!("../types/nerdo/library/math.lua"));
}
// implemented in lua: load and evaluate cached chunk
match MATH_BYTECODE.as_ref() {
Expand Down Expand Up @@ -417,13 +412,8 @@ fn register_math_bindings(lua: &mut Lua) -> LuaResult<()> {
fn register_table_bindings(lua: &mut Lua) -> LuaResult<()> {
// cache module bytecode to speed up initialization
lazy_static! {
static ref TABLE_BYTECODE: LuaResult<Vec<u8>> = {
let strip = true;
Lua::new_with(LuaStdLib::NONE, LuaOptions::default())?
.load(include_str!("../types/nerdo/library/table.lua"))
.into_function()
.map(|x| x.dump(strip))
};
static ref TABLE_BYTECODE: LuaResult<Vec<u8>> =
compile_chunk(include_str!("../types/nerdo/library/table.lua"));
}
// implemented in lua: load and evaluate cached chunk
match TABLE_BYTECODE.as_ref() {
Expand All @@ -439,13 +429,8 @@ fn register_table_bindings(lua: &mut Lua) -> LuaResult<()> {
fn register_pattern_module(lua: &mut Lua) -> LuaResult<()> {
// cache module bytecode to speed up requires
lazy_static! {
static ref PATTERN_BYTECODE: LuaResult<Vec<u8>> = {
let strip = true;
Lua::new_with(LuaStdLib::NONE, LuaOptions::default())?
.load(include_str!("../types/nerdo/library/pattern.lua"))
.into_function()
.map(|x| x.dump(strip))
};
static ref PATTERN_BYTECODE: LuaResult<Vec<u8>> =
compile_chunk(include_str!("../types/nerdo/library/pattern.lua"));
}
// implemented in lua: load and evaluate cached chunk
match PATTERN_BYTECODE.as_ref() {
Expand All @@ -460,6 +445,22 @@ fn register_pattern_module(lua: &mut Lua) -> LuaResult<()> {

// --------------------------------------------------------------------------------------------------

#[cfg(any(feature = "lua", feature = "lua-jit"))]
fn compile_chunk(chunk: &'static str) -> LuaResult<Vec<u8>> {
let strip = false;
Lua::new_with(LuaStdLib::NONE, LuaOptions::default())?
.load(chunk)
.into_function()
.map(|x| x.dump(strip))
}

#[cfg(any(feature = "luau", feature = "luau-jit"))]
fn compile_chunk(chunk: &'static str) -> LuaResult<Vec<u8>> {
Ok(mlua::Compiler::new().compile(chunk))
}

// --------------------------------------------------------------------------------------------------

#[cfg(test)]
mod test {
use super::*;
Expand Down
40 changes: 34 additions & 6 deletions src/bindings/timeout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ impl LuaTimeoutHook {
pub(crate) fn new_with_timeout(lua: &Lua, timeout: Duration) -> Self {
let active = Rc::new(RefCell::new(1));
let start = Rc::new(RefCell::new(Instant::now()));
lua.set_hook(LuaHookTriggers::new().every_nth_instruction(timeout.as_millis() as u32), {
let timeout_hook = {
let active = Rc::clone(&active);
let start = Rc::clone(&start);
move |lua, _debug| {
move || {
if *active.borrow() > 0 {
if start.borrow().elapsed() > timeout {
*start.borrow_mut() = Instant::now();
Expand All @@ -47,14 +47,42 @@ impl LuaTimeoutHook {
+ "Also note that the script is running in real-time thread!",
))
} else {
Ok(())
Ok(false) // continue running
}
} else {
lua.remove_hook();
Ok(())
Ok(true) // remove hook
}
}
});
};
// Lua or LuaJij -> set_hook
#[cfg(not(any(feature = "luau", feature = "luau-jit")))]
{
lua.set_hook(
LuaHookTriggers::new().every_nth_instruction(timeout.as_millis() as u32 * 10),
move |lua, _debug| match timeout_hook() {
Ok(remove_hook) => {
if remove_hook {
lua.remove_hook();
}
Ok(())
}
Err(err) => Err(err),
},
);
}
// Luau -> set_interrupt
#[cfg(any(feature = "luau", feature = "luau-jit"))]
{
lua.set_interrupt(move |lua| match timeout_hook() {
Ok(remove_hook) => {
if remove_hook {
lua.remove_interrupt();
}
Ok(mlua::VmState::Continue)
}
Err(err) => Err(err),
});
}
Self { active, start }
}

Expand Down
14 changes: 12 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,18 @@

// -------------------------------------------------------------------------------------------------

#[cfg(all(feature = "scripting", not(any(feature = "lua51", feature = "luajit"))))]
compile_error!("when enabling the `scripting` feature, enable one of the lua backend features, such as `lua51`, as well");
#[cfg(all(
feature = "scripting",
not(any(
feature = "lua",
feature = "lua-jit",
feature = "luau",
feature = "luau-jit"
))
))]
compile_error!(
"When enabling the `scripting` feature, enable one of the lua interpreter features as well: `lua`, `lua-jit`, `luau` or `lua-jit`"
);

// -------------------------------------------------------------------------------------------------

Expand Down

0 comments on commit c095f2f

Please sign in to comment.