Tsuki
Tsuki is a port of Lua 5.4 to Rust. This is porting, not binding; which mean all code are Rust and can be using without C compiler[^1]. The initial works was done by C2Rust. Note that this port was done without compatibility with the previous version. You can see a list of the differences here.
[!IMPORTANT] All types in Tsuki does not implement
SendandSyncand no plan to support this at the moment.
Status
The VM to run Lua code is fully working almost exactly as vanilla Lua (see the list of differences below). Some functions on Lua standard library are still missing.
Safety
All public API of Tsuki should provide 100% safety as long as you don't use unsafe API incorrectly.
Tsuki is not designed to run untrusted Lua script. Although you can limit what Lua script can do by not expose a function to it but there is no way to limit amount of memory or execution time used by Lua script. The meaning of this is Lua script can cause a panic due to out of memory or never return the control back to Rust with infinite loop.
Performance
VM
On platform that Lua cannot use computed goto (e.g. Windows with MSVC) Tsuki VM is faster than Lua about 10% otherwise Lua is faster about 30%. The only possibility for Tsuki to be faster than Lua with computed goto is JIT since computed goto does not available on Rust. See issue 18 for more details.
Async
A call to async function without any suspend on Tsuki is faster than mlua about 3.5x. For 1 suspend Tsuki it faster about 3x. For 8 suspend Tsuki is faster about 2x.
Features
- 100% Rust code.
- libc is required at the moment.
- Support both synchronous and asynchronous.
- Safe, ergonomic and low overhead API.
- Any error propagated to the caller via Rust
Resultinstead of a long jump. core::any::Anyas Lua userdata and can be created without the need to define its metatable.- Metatable for a userdata is lookup with
core::any::TypeIdinstead of a string.
Differences from Lua
VM and Language
- Binary chunk is not supported.
- Panic when memory allocation is failed without retry (Rust behavior).
- Chunk name does not have a prefix (e.g.
@). - Second argument to
__closemetamethod alwaysnil. __gcmetamethod is not supported.__namemetavalue must be UTF-8 string.__tostringmetamethod must return a UTF-8 string.- C locale is ignored (once
libchas been completely removed).
Standard library
- No
_VERSION,collectgarbage,dofile,loadfile,warn,xpcall,string.dumpand debug library. - Second argument of
assertaccept only a UTF-8 string. - Arguments of
error:- First argument accept only a UTF-8 string.
- Second argument is not supported and it is always assume 1.
- Arguments of
load:- First argument accept only a string.
- Second argument accept only a UTF-8 string and will be empty when absent.
- Third argument must be
nilor"t".
string.formatrequires UTF-8 string for both format string and format value.- Native module is not supported.
- Environment variable
LUA_PATHandLUA_PATH_5_4is ignored. LUA_NOENVin registry is ignored.
Non-goals
- Become a superset of Lua (e.g. Luau).
- C API compatibility.
- Stand-alone mode.
- 16-bit systems.
Roadmap
- Complete Lua standard library.
- Remove libc.
- JIT using Cranelift.
Breaking changes in 0.2
Lua::with_seedhas parameters swapped.Lua::setup_basehas been replaced withBaseLib.Lua::setup_stringhas been replaced withStringLib.Lua::setup_tablehas been replaced withTableLib.Lua::setup_mathhas been replaced withMathLib.Lua::setup_coroutinehas been replaced withCoroLib.Lua::loadandContext::loadacceptInto<ChunkInfo>instead ofChunkInfo.Arg::get_strandArg::get_nilable_strno longer accept a number. UseArg::to_strorArg::to_nilable_strinstead of you want old behavior.Arg::to_numrenamed toArg::to_float.Arg::to_nilable_numrenamed toArg::to_nilable_float.Arg::lenis removed in favor ofContext::get_value_len.Arg::ltis removed in favor ofContext::is_value_lt.Value::Numis renamed toValue::Float.ChunkInfono longer implementDefault.Str::is_utf8andStr::as_strnow lazy evaluate the content to see if data is UTF-8.
License
Same as Lua, which is MIT.
[^1]: On Windows, a proxy to sprintf written in C++ is required at the moment. This proxy will be removed when we replace sprintf calls with Rust equivalent.